298 lines
7.6 KiB
JavaScript

'use strict'
const { assertAsync } = require('./util')
exports.open = function (test, testCommon) {
test('test database open, no options', function (t) {
const db = testCommon.factory()
t.is(db.status, 'opening')
// default createIfMissing=true, errorIfExists=false
db.open(function (err) {
t.error(err)
t.is(db.status, 'open')
db.close(function () {
t.is(db.status, 'closed')
t.end()
})
})
t.is(db.status, 'opening')
})
test('test database open, no options, with promise', function (t) {
const db = testCommon.factory()
t.is(db.status, 'opening')
// default createIfMissing=true, errorIfExists=false
db.open().then(function () {
t.is(db.status, 'open')
db.close(t.end.bind(t))
}).catch(t.fail.bind(t))
t.is(db.status, 'opening')
})
test('test database open, options and callback', function (t) {
const db = testCommon.factory()
// default createIfMissing=true, errorIfExists=false
db.open({}, function (err) {
t.error(err)
db.close(function () {
t.end()
})
})
})
test('test database open, options with promise', function (t) {
const db = testCommon.factory()
// default createIfMissing=true, errorIfExists=false
db.open({}).then(function () {
db.close(t.end.bind(t))
})
})
test('test database open, close and open', function (t) {
const db = testCommon.factory()
db.open(function (err) {
t.error(err)
db.close(function (err) {
t.error(err)
t.is(db.status, 'closed')
db.open(function (err) {
t.error(err)
t.is(db.status, 'open')
db.close(t.end.bind(t))
})
})
})
})
test('test database open, close and open with promise', function (t) {
const db = testCommon.factory()
db.open().then(function () {
db.close(function (err) {
t.error(err)
db.open().then(function () {
db.close(function () {
t.end()
})
}).catch(t.fail.bind(t))
})
}).catch(t.fail.bind(t))
})
test('test database open and close in same tick', assertAsync.ctx(function (t) {
t.plan(10)
const db = testCommon.factory()
const order = []
db.open(assertAsync(function (err) {
order.push('A')
t.is(err && err.code, 'LEVEL_DATABASE_NOT_OPEN', 'got open() error')
t.is(db.status, 'closed', 'is closed')
}))
t.is(db.status, 'opening', 'is opening')
// This wins from the open() call
db.close(assertAsync(function (err) {
order.push('B')
t.same(order, ['A', 'closed event', 'B'], 'order is correct')
t.ifError(err, 'no close() error')
t.is(db.status, 'closed', 'is closed')
}))
// But open() is still in control
t.is(db.status, 'opening', 'is still opening')
// Should not emit 'open', because close() wins
db.on('open', t.fail.bind(t))
db.on('closed', assertAsync(() => { order.push('closed event') }))
}))
test('test database open, close and open in same tick', assertAsync.ctx(function (t) {
t.plan(14)
const db = testCommon.factory()
const order = []
db.open(assertAsync(function (err) {
order.push('A')
t.ifError(err, 'no open() error (1)')
t.is(db.status, 'open', 'is open')
}))
t.is(db.status, 'opening', 'is opening')
// This wins from the open() call
db.close(assertAsync(function (err) {
order.push('B')
t.is(err && err.code, 'LEVEL_DATABASE_NOT_CLOSED')
t.is(db.status, 'open', 'is open')
}))
t.is(db.status, 'opening', 'is still opening')
// This wins from the close() call
db.open(assertAsync(function (err) {
order.push('C')
t.same(order, ['A', 'B', 'open event', 'C'], 'callback order is the same as call order')
t.ifError(err, 'no open() error (2)')
t.is(db.status, 'open', 'is open')
}))
// Should not emit 'closed', because open() wins
db.on('closed', t.fail.bind(t))
db.on('open', assertAsync(() => { order.push('open event') }))
t.is(db.status, 'opening', 'is still opening')
}))
test('test database open if already open (sequential)', function (t) {
t.plan(7)
const db = testCommon.factory()
db.open(assertAsync(function (err) {
t.ifError(err, 'no open() error (1)')
t.is(db.status, 'open', 'is open')
db.open(assertAsync(function (err) {
t.ifError(err, 'no open() error (2)')
t.is(db.status, 'open', 'is open')
}))
t.is(db.status, 'open', 'not reopening')
db.on('open', t.fail.bind(t))
assertAsync.end(t)
}))
assertAsync.end(t)
})
test('test database open if already opening (parallel)', assertAsync.ctx(function (t) {
t.plan(7)
const db = testCommon.factory()
db.open(assertAsync(function (err) {
t.ifError(err, 'no open() error (1)')
t.is(db.status, 'open')
}))
db.open(assertAsync(function (err) {
t.ifError(err, 'no open() error (2)')
t.is(db.status, 'open')
db.close(t.end.bind(t))
}))
t.is(db.status, 'opening')
}))
test('test database close if already closed', function (t) {
t.plan(8)
const db = testCommon.factory()
db.open(function (err) {
t.ifError(err, 'no open() error')
db.close(assertAsync(function (err) {
t.ifError(err, 'no close() error (1)')
t.is(db.status, 'closed', 'is closed')
db.close(assertAsync(function (err) {
t.ifError(err, 'no close() error (2)')
t.is(db.status, 'closed', 'is closed')
}))
t.is(db.status, 'closed', 'is closed', 'not reclosing')
db.on('closed', t.fail.bind(t))
assertAsync.end(t)
}))
assertAsync.end(t)
})
})
test('test database close if new', assertAsync.ctx(function (t) {
t.plan(5)
const db = testCommon.factory()
const expectedStatus = db.supports.deferredOpen ? 'opening' : 'closed'
t.is(db.status, expectedStatus, 'status ok')
db.close(assertAsync(function (err) {
t.ifError(err, 'no close() error')
t.is(db.status, 'closed', 'status ok')
}))
t.is(db.status, expectedStatus, 'status unchanged')
if (!db.supports.deferredOpen) {
db.on('closed', t.fail.bind(t, 'should not emit closed'))
}
}))
test('test database close on open event', function (t) {
t.plan(5)
const db = testCommon.factory()
const order = []
db.open(function (err) {
order.push('A')
t.is(err && err.code, 'LEVEL_DATABASE_NOT_OPEN', 'got open() error')
t.is(db.status, 'closed', 'is closed')
})
db.on('open', function () {
// This wins from the (still in progress) open() call
db.close(function (err) {
order.push('B')
t.same(order, ['A', 'closed event', 'B'], 'order is correct')
t.ifError(err, 'no close() error')
t.is(db.status, 'closed', 'is closed')
})
})
db.on('closed', () => { order.push('closed event') })
})
test('test passive open()', async function (t) {
t.plan(1)
const db = testCommon.factory()
await db.open({ passive: true }) // OK, already opening
await db.close()
await db.open({ passive: true }).catch(err => {
t.is(err.code, 'LEVEL_DATABASE_NOT_OPEN')
})
await db.open()
await db.open({ passive: true }) // OK, already open
return db.close()
})
test('test passive open(): ignored if set in constructor options', async function (t) {
const db = testCommon.factory({ passive: true })
await new Promise((resolve) => db.once('open', resolve))
return db.close()
})
}
exports.all = function (test, testCommon) {
exports.open(test, testCommon)
}