Skip to content
This repository has been archived by the owner on Dec 1, 2024. It is now read-only.

Add clear() #310

Merged
merged 4 commits into from
Aug 18, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add basic tests
  • Loading branch information
vweevers committed Aug 17, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 89df2b91939c105fbeeb0a7cb8e4296b23490d62
83 changes: 83 additions & 0 deletions test/clear-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
var concat = require('level-concat-iterator')
var db

exports.setUp = function (test, testCommon) {
test('setUp common', testCommon.setUp)
test('setUp db', function (t) {
db = testCommon.factory()
db.open(t.end.bind(t))
})
}

exports.args = function (test, testCommon) {
test('test argument-less clear() throws', function (t) {
t.throws(
db.clear.bind(db),
/Error: clear\(\) requires a callback argument/,
'no-arg clear() throws'
)
t.end()
})
}

exports.clear = function (test, testCommon) {
makeTest('string', ['a', 'b'])

if (testCommon.bufferKeys) {
makeTest('buffer', [Buffer.from('a'), Buffer.from('b')])
makeTest('mixed', [Buffer.from('a'), 'b'])

// These keys would be equal when compared as utf8 strings
makeTest('non-utf8 buffer', [Buffer.from('80', 'hex'), Buffer.from('c0', 'hex')])
}

function makeTest (type, keys) {
test('test simple clear() on ' + type + ' keys', function (t) {
t.plan(8)

var db = testCommon.factory()
var ops = keys.map(function (key) {
return { type: 'put', key: key, value: 'foo' }
})

db.open(function (err) {
t.ifError(err, 'no open error')

db.batch(ops, function (err) {
t.ifError(err, 'no batch error')

concat(db.iterator(), function (err, entries) {
t.ifError(err, 'no concat error')
t.is(entries.length, keys.length, 'has entries')

db.clear(function (err) {
t.ifError(err, 'no clear error')

concat(db.iterator(), function (err, entries) {
t.ifError(err, 'no concat error')
t.is(entries.length, 0, 'has no entries')

db.close(function (err) {
t.ifError(err, 'no close error')
})
})
})
})
})
})
})
}
}

exports.tearDown = function (test, testCommon) {
test('tearDown', function (t) {
db.close(testCommon.tearDown.bind(null, t))
})
}

exports.all = function (test, testCommon) {
exports.setUp(test, testCommon)
exports.args(test, testCommon)
exports.clear(test, testCommon)
exports.tearDown(test, testCommon)
}
4 changes: 3 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
@@ -40,7 +40,9 @@ function suite (options) {
}

if (testCommon.clear) {
// TODO
require('./clear-test').all(test, testCommon)

// TODO: add clear-range-test
}
}

108 changes: 96 additions & 12 deletions test/self.js
Original file line number Diff line number Diff line change
@@ -9,11 +9,15 @@ var AbstractChainedBatch = require('../').AbstractChainedBatch

var testCommon = require('./common')({
test: test,
clear: true,
factory: function () {
return new AbstractLevelDOWN()
}
})

var rangeOptions = ['gt', 'gte', 'lt', 'lte']
var legacyRangeOptions = ['start', 'end']

// Test the suite itself as well as the default implementation,
// excluding noop operations that can't pass the test suite.

@@ -67,6 +71,10 @@ require('./iterator-seek-test').setUp(test, testCommon)
require('./iterator-seek-test').sequence(test, testCommon)
require('./iterator-seek-test').tearDown(test, testCommon)

require('./clear-test').setUp(test, testCommon)
require('./clear-test').args(test, testCommon)
require('./clear-test').tearDown(test, testCommon)

function implement (ctor, methods) {
function Test () {
ctor.apply(this, arguments)
@@ -374,7 +382,7 @@ test('test AbstractChainedBatch expects a db', function (t) {
}
})

test('test write() extensibility', function (t) {
test('test AbstractChainedBatch#write() extensibility', function (t) {
var spy = sinon.spy()
var spycb = sinon.spy()
var Test = implement(AbstractChainedBatch, { _write: spy })
@@ -394,7 +402,7 @@ test('test write() extensibility', function (t) {
t.end()
})

test('test write() extensibility with null options', function (t) {
test('test AbstractChainedBatch#write() extensibility with null options', function (t) {
var spy = sinon.spy()
var Test = implement(AbstractChainedBatch, { _write: spy })
var test = new Test({ test: true })
@@ -406,7 +414,7 @@ test('test write() extensibility with null options', function (t) {
t.end()
})

test('test write() extensibility with options', function (t) {
test('test AbstractChainedBatch#write() extensibility with options', function (t) {
var spy = sinon.spy()
var Test = implement(AbstractChainedBatch, { _write: spy })
var test = new Test({ test: true })
@@ -418,7 +426,7 @@ test('test write() extensibility with options', function (t) {
t.end()
})

test('test put() extensibility', function (t) {
test('test AbstractChainedBatch#put() extensibility', function (t) {
var spy = sinon.spy()
var expectedKey = 'key'
var expectedValue = 'value'
@@ -435,7 +443,7 @@ test('test put() extensibility', function (t) {
t.end()
})

test('test del() extensibility', function (t) {
test('test AbstractChainedBatch#del() extensibility', function (t) {
var spy = sinon.spy()
var expectedKey = 'key'
var Test = implement(AbstractChainedBatch, { _del: spy })
@@ -450,7 +458,7 @@ test('test del() extensibility', function (t) {
t.end()
})

test('test clear() extensibility', function (t) {
test('test AbstractChainedBatch#clear() extensibility', function (t) {
var spy = sinon.spy()
var Test = implement(AbstractChainedBatch, { _clear: spy })
var test = new Test(testCommon.factory())
@@ -479,8 +487,8 @@ test('test iterator() extensibility', function (t) {

test.iterator({ options: 1 })

t.equal(spy.callCount, 1, 'got _close() call')
t.equal(spy.getCall(0).thisValue, test, '`this` on _close() was correct')
t.equal(spy.callCount, 1, 'got _iterator() call')
t.equal(spy.getCall(0).thisValue, test, '`this` on _iterator() was correct')
t.equal(spy.getCall(0).args.length, 1, 'got one arguments')
t.deepEqual(spy.getCall(0).args[0], expectedOptions, 'got expected options argument')
t.end()
@@ -494,7 +502,7 @@ test('test AbstractIterator extensibility', function (t) {
t.end()
})

test('test next() extensibility', function (t) {
test('test AbstractIterator#next() extensibility', function (t) {
var spy = sinon.spy()
var spycb = sinon.spy()
var Test = implement(AbstractIterator, { _next: spy })
@@ -513,7 +521,7 @@ test('test next() extensibility', function (t) {
t.end()
})

test('test end() extensibility', function (t) {
test('test AbstractIterator#end() extensibility', function (t) {
var spy = sinon.spy()
var expectedCb = function () {}
var Test = implement(AbstractIterator, { _end: spy })
@@ -528,6 +536,35 @@ test('test end() extensibility', function (t) {
t.end()
})

test('test clear() extensibility', function (t) {
var spy = sinon.spy()
var Test = implement(AbstractLevelDOWN, { _clear: spy })
var db = new Test()
var callback = function () {}

call([callback], { reverse: false, limit: -1 })
call([null, callback], { reverse: false, limit: -1 })
call([undefined, callback], { reverse: false, limit: -1 })
call([{ custom: 1 }, callback], { custom: 1, reverse: false, limit: -1 })
call([{ reverse: true, limit: 0 }, callback], { reverse: true, limit: 0 })
call([{ reverse: 1 }, callback], { reverse: true, limit: -1 })
call([{ reverse: null }, callback], { reverse: false, limit: -1 })

function call (args, expectedOptions) {
db.clear.apply(db, args)

t.is(spy.callCount, 1, 'got _clear() call')
t.is(spy.getCall(0).thisValue, db, '`this` on _clear() was correct')
t.is(spy.getCall(0).args.length, 2, 'got two arguments')
t.same(spy.getCall(0).args[0], expectedOptions, 'got expected options argument')
t.is(spy.getCall(0).args[1], callback, 'got expected callback argument')

spy.resetHistory()
}

t.end()
})

test('test serialization extensibility (put)', function (t) {
t.plan(5)

@@ -752,6 +789,53 @@ test('test serialization extensibility (iterator seek)', function (t) {
t.equal(spy.getCall(0).args[0], 'serialized', 'got expected target argument')
})

test('test serialization extensibility (clear range options)', function (t) {
t.plan(rangeOptions.length * 2)

rangeOptions.forEach(function (key) {
var Test = implement(AbstractLevelDOWN, {
_serializeKey: function (key) {
t.is(key, 'input')
return 'output'
},
_clear: function (options, callback) {
t.is(options[key], 'output')
}
})

var db = new Test()
var options = {}

options[key] = 'input'
db.clear(options, function () {})
})
})

test('clear() does not delete empty or nullish range options', function (t) {
var rangeValues = [Buffer.alloc(0), '', null, undefined]

t.plan(rangeOptions.length * rangeValues.length)

rangeValues.forEach(function (value) {
var Test = implement(AbstractLevelDOWN, {
_clear: function (options, callback) {
rangeOptions.forEach(function (key) {
t.ok(key in options, key + ' option should not be deleted')
})
}
})

var db = new Test()
var options = {}

rangeOptions.forEach(function (key) {
options[key] = value
})

db.clear(options, function () {})
})
})

test('.status', function (t) {
t.plan(5)

@@ -843,7 +927,7 @@ test('.status', function (t) {
})

test('_setupIteratorOptions', function (t) {
var keys = 'start end gt gte lt lte'.split(' ')
var keys = legacyRangeOptions.concat(rangeOptions)
var db = new AbstractLevelDOWN()

function setupOptions (constrFn) {
@@ -856,7 +940,7 @@ test('_setupIteratorOptions', function (t) {

function verifyOptions (t, options) {
keys.forEach(function (key) {
t.ok(key in options, 'property should not be deleted')
t.ok(key in options, key + ' option should not be deleted')
})
t.end()
}