diff --git a/abstract-leveldown.js b/abstract-leveldown.js index cd744c24..7ec64b91 100644 --- a/abstract-leveldown.js +++ b/abstract-leveldown.js @@ -4,8 +4,52 @@ var AbstractChainedBatch = require('./abstract-chained-batch') var hasOwnProperty = Object.prototype.hasOwnProperty var rangeOptions = 'start end gt gte lt lte'.split(' ') -function AbstractLevelDOWN () { +function AbstractLevelDOWN (supports) { + // TODO (next major): make this mandatory + if (!supports || typeof supports !== 'object') supports = {} + this.status = 'new' + + // TODO (after review): move this to a module for reuse by levelup + this.supports = xtend(supports, { + // Features of abstract-leveldown + bufferKeys: !!supports.bufferKeys, + snapshots: !!supports.snapshots, + permanence: !!supports.permanence, + seek: !!supports.seek, + + // Features of abstract-leveldown that levelup doesn't have + status: !!supports.status, + + // Experimental features + clear: !!supports.clear, + type: !!supports.type, + + // Features of disk-based implementations + createIfMissing: !!supports.createIfMissing, + errorIfExists: !!supports.errorIfExists, + + // Features of level(up) that abstract-leveldown doesn't have yet + deferredOpen: !!supports.deferredOpen, + openCallback: !!supports.openCallback, + promises: !!supports.promises, + streams: !!supports.streams, + encodings: !!supports.encodings, + + // Methods that are not part of abstract-leveldown or levelup + additionalMethods: supports.additionalMethods || { + // Example + // approximateSize: { + // sync: false, + // callback: true, + // promise: false + // }, + // createWriteStream: { + // sync: true, + // writable: true + // } + } + }) } AbstractLevelDOWN.prototype.open = function (options, callback) { diff --git a/test/common.js b/test/common.js index 47c53454..cdc216ba 100644 --- a/test/common.js +++ b/test/common.js @@ -13,8 +13,12 @@ function testCommon (options) { return { test: test, factory: factory, + + // TODO (next major): remove setUp: options.setUp || noopTest(), tearDown: options.tearDown || noopTest(), + + // TODO (next major): use db.supports instead bufferKeys: options.bufferKeys !== false, createIfMissing: options.createIfMissing !== false, errorIfExists: options.errorIfExists !== false, diff --git a/test/index.js b/test/index.js index 9c2fa35a..1ef97afc 100644 --- a/test/index.js +++ b/test/index.js @@ -5,6 +5,7 @@ function suite (options) { var test = testCommon.test require('./factory-test')(test, testCommon) + require('./manifest-test')(test, testCommon) require('./leveldown-test')(test, testCommon) require('./open-test').all(test, testCommon) diff --git a/test/manifest-test.js b/test/manifest-test.js new file mode 100644 index 00000000..f1c360be --- /dev/null +++ b/test/manifest-test.js @@ -0,0 +1,47 @@ +var xtend = require('xtend') +var hasOwnProperty = Object.prototype.hasOwnProperty + +module.exports = function (test, testCommon) { + test('setUp common', testCommon.setUp) + + test('db has manifest', function (t) { + var db = testCommon.factory() + var supports = db.supports + + t.ok(isObject(supports)) + t.ok(isObject(supports.additionalMethods)) + + for (var k in supports) { + if (!hasOwnProperty.call(supports, k)) continue + if (k === 'additionalMethods') continue + + t.is(typeof supports[k], 'boolean', k) + } + + for (var m in supports.additionalMethods) { + if (!hasOwnProperty.call(supports.additionalMethods, m)) continue + t.ok(isObject(supports.additionalMethods[m]), m) + } + + var before = xtend(supports, { + additionalMethods: xtend(supports.additionalMethods) + }) + + db.open(function (err) { + t.ifError(err, 'no open error') + t.same(db.supports, before, 'manifest did not change after open') + + db.close(function (err) { + t.ifError(err, 'no close error') + t.same(db.supports, before, 'manifest did not change after close') + t.end() + }) + }) + }) + + test('tearDown', testCommon.tearDown) +} + +function isObject (o) { + return typeof o === 'object' && o !== null +} diff --git a/test/self.js b/test/self.js index 18e156c0..8dfc6255 100644 --- a/test/self.js +++ b/test/self.js @@ -22,7 +22,7 @@ var legacyRangeOptions = ['start', 'end'] // excluding noop operations that can't pass the test suite. require('./leveldown-test')(test, testCommon) - +require('./manifest-test')(test, testCommon) require('./open-test').all(test, testCommon) require('./open-create-if-missing-test').setUp(test, testCommon)