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

update abstract-leveldown to v4 #28

Merged
merged 9 commits into from
Jan 28, 2018
16 changes: 15 additions & 1 deletion leveldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,21 @@ LevelDOWN.prototype._batch = function (operations, options, callback) {
}


LevelDOWN.prototype._approximateSize = function (start, end, callback) {
LevelDOWN.prototype.approximateSize = function (start, end, callback) {
if (start == null ||
end == null ||
typeof start === 'function' ||
typeof end === 'function') {
throw new Error('approximateSize() requires valid `start`, `end` and `callback` arguments')
}

if (typeof callback !== 'function') {
throw new Error('approximateSize() requires a callback argument')
}

start = this._serializeKey(start)
end = this._serializeKey(end)

this.binding.approximateSize(start, end, callback)
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"main": "leveldown.js",
"typings": "leveldown.d.ts",
"dependencies": {
"abstract-leveldown": "~3.0.0",
"abstract-leveldown": "~4.0.0",
"bindings": "~1.3.0",
"fast-future": "~1.0.2",
"nan": "~2.8.0",
Expand Down
127 changes: 122 additions & 5 deletions test/approximate-size-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,123 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/approximate-size-test')
const test = require('tape')
const leveldown = require('..')
const testCommon = require('abstract-leveldown/testCommon')

abstract.all(leveldown, test, testCommon)
var db

test('setUp common for approximate size', testCommon.setUp)

test('setUp db', function (t) {
db = leveldown(testCommon.location())
console.log('db', db)
db.open(t.end.bind(t))
})

test('test argument-less approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db)
, { name: 'Error', message: 'approximateSize() requires valid `start`, `end` and `callback` arguments' }
, 'no-arg approximateSize() throws'
)
t.end()
})

test('test callback-less, 1-arg, approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db, 'foo')
, { name: 'Error', message: 'approximateSize() requires valid `start`, `end` and `callback` arguments' }
, 'callback-less, 1-arg approximateSize() throws'
)
t.end()
})

test('test callback-less, 2-arg, approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db, 'foo', 'bar')
, { name: 'Error', message: 'approximateSize() requires a callback argument' }
, 'callback-less, 2-arg approximateSize() throws'
)
t.end()
})

test('test callback-less, 3-arg, approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db, function () {})
, { name: 'Error', message: 'approximateSize() requires valid `start`, `end` and `callback` arguments' }
, 'callback-only approximateSize() throws'
)
t.end()
})

test('test callback-only approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db, function () {})
, { name: 'Error', message: 'approximateSize() requires valid `start`, `end` and `callback` arguments' }
, 'callback-only approximateSize() throws'
)
t.end()
})

test('test 1-arg + callback approximateSize() throws', function (t) {
t.throws(
db.approximateSize.bind(db, 'foo', function () {})
, { name: 'Error', message: 'approximateSize() requires valid `start`, `end` and `callback` arguments' }
, '1-arg + callback approximateSize() throws'
)
t.end()
})

test('test custom _serialize*', function (t) {
t.plan(4)
var db = leveldown(testCommon.location())
db._serializeKey = function (data) { return data }
db.approximateSize = function (start, end, callback) {
t.deepEqual(start, { foo: 'bar' })
t.deepEqual(end, { beep: 'boop' })
process.nextTick(callback)
}
db.open(function () {
db.approximateSize({ foo: 'bar' }, { beep: 'boop' }, function (err) {
t.error(err)
db.close(t.error.bind(t))
})
})
})

test('test approximateSize()', function (t) {
var data = Array.apply(null, Array(10000)).map(function () {
return 'aaaaaaaaaa'
}).join('')

db.batch(Array.apply(null, Array(10)).map(function (x, i) {
return { type: 'put', key: 'foo' + i, value: data }
}), function (err) {
t.error(err)

// cycle open/close to ensure a pack to .sst

db.close(function (err) {
t.error(err)

db.open(function (err) {
t.error(err)

db.approximateSize('!', '~', function (err, size) {
t.error(err)

t.equal(typeof size, 'number')
// account for snappy compression, original would be ~100000
t.ok(size > 40000, 'size reports a reasonable amount (' + size + ')')

db.close(function (err) {
t.error(err)
t.end()
})
})
})
})
})
})

test('tearDown', function (t) {
db.close(testCommon.tearDown.bind(null, t))
})
3 changes: 1 addition & 2 deletions test/batch-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/batch-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
3 changes: 1 addition & 2 deletions test/chained-batch-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/chained-batch-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
1 change: 0 additions & 1 deletion test/cleanup-hanging-iterators-test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, makeTest = require('./make')

Expand Down
2 changes: 1 addition & 1 deletion test/close-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ module.exports.tearDown = function () {

module.exports.all = function (leveldown) {
module.exports.setUp()
module.exports.close(leveldown, test, testCommon)
module.exports.close(leveldown, test)
module.exports.tearDown()
}

Expand Down
32 changes: 18 additions & 14 deletions test/compact-range-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ test('setUp db', function (t) {
})

test('test compactRange() frees disk space after key deletion', function (t) {
var key1 = '000000';
var key2 = '000001';
var val1 = Buffer(64).fill(1);
var val2 = Buffer(64).fill(1);
var key1 = '000000'
var key2 = '000001'
var val1 = Buffer(64).fill(1)
var val2 = Buffer(64).fill(1)
db.put(key1, val1, function() {
db.put(key2, val2, function() {
db.compactRange(key1, key2, function() {
Expand All @@ -25,13 +25,17 @@ test('test compactRange() frees disk space after key deletion', function (t) {
db.compactRange(key1, key2, function() {
db.approximateSize('0', 'z', function(err, sizeAfterCompact) {
t.ok(sizeAfterCompact < sizeAfterPuts);
t.end();
});
});
});
});
});
});
});
});
});
t.end()
})
})
})
})
})
})
})
})
})

test('tearDown', function (t) {
db.close(testCommon.tearDown.bind(null, t))
})
Binary file removed test/data/testdata.bin
Binary file not shown.
3 changes: 1 addition & 2 deletions test/del-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/del-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
3 changes: 1 addition & 2 deletions test/destroy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const test = require('tape')
, path = require('path')
, mkfiletree = require('mkfiletree')
, readfiletree = require('readfiletree')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, makeTest = require('./make')

Expand Down Expand Up @@ -58,7 +57,7 @@ makeTest('test destroy() cleans and removes leveldb-only dir', function (db, t,
db.close(function (err) {
t.notOk(err, 'no error')
leveldown.destroy(location, function () {
t.notOk(fs.existsSync(), 'directory completely removed')
t.notOk(fs.existsSync(location), 'directory completely removed')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it's a timing issue to use fs.existsSync() on windows or if it's actually a bug. Clearly, not using location is incorrect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though I almost never use fs.exist(Sync), I'm not aware of any timing issues.

It could be the same issue as in leveldown, that some test isn't closing its db, but in leveldown, we saw EBUSY rather than EPERM errors.

No promises as to when, but I'll try to take a look at this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, should have read the code, it actually does close the db. Hmm that's great

Copy link
Member

@vweevers vweevers Jan 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Able to reproduce. There are no leftover files, but it seems the directory itself (location) isn't removed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So maybe the test should actually check for an empty folder, rather than the folder itself being removed?

Copy link
Member

@vweevers vweevers Jan 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worse.. leveldown.destroy actually creates the directory.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Repro:

test('destroy does not create a directory', function (t) {
  t.plan(3)

  const location = path.resolve('destroy-test')

  rimraf.sync(location)
  t.is(fs.existsSync(location), false, 'exists before')

  leveldown.destroy(location, function (err) {
    t.ifError(err, 'no error')
    t.is(fs.existsSync(location), false, 'exists after') // Fails
  })
})

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test could check for

  • removal of the location folder
  • if the folder is not removed, then make sure it's empty

For now, we could do:

fs.readdir(location, (err, files) => {
  if (err && err.code === 'ENOENT') // Passed
  if (files.length === 0) // Passed
})

And open an issue to fix the destroy bug later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #30 for the bug.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worse.. leveldown.destroy actually creates the directory.

O.o

done(false)
})
})
Expand Down
3 changes: 1 addition & 2 deletions test/get-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/get-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
5 changes: 5 additions & 0 deletions test/iterator-range-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const test = require('tape')
, leveldown = require('..')
, abstract = require('abstract-leveldown/abstract/iterator-range-test')

abstract.all(leveldown, test)
5 changes: 2 additions & 3 deletions test/iterator-test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/iterator-test')
, make = require('./make')
, iota = require('iota-array')
, lexi = require('lexicographic-integer')
, util = require('util')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)

make('iterator throws if key is not a string or buffer', function (db, t, done) {
var keys = [null, undefined, 1, true, false]
Expand Down Expand Up @@ -288,4 +287,4 @@ function not (n) {

function even (n) {
return n % 2 === 0
}
}
47 changes: 26 additions & 21 deletions test/make.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,33 @@ function makeTest (name, testFn) {
test(name, function (t) {
cleanup(function () {
var loc = location()
, db = leveldown(loc)
, done = function (close) {
if (close === false)
return cleanup(t.end.bind(t))
db.close(function (err) {
t.notOk(err, 'no error from close()')
cleanup(t.end.bind(t))
})
}
var db = leveldown(loc)
var done = function (close) {
if (close === false) {
cleanup(function (err) {
t.error(err, 'no error after cleanup')
t.end()
})
return
}
db.close(function (err) {
t.notOk(err, 'no error from close()')
cleanup(function (err) {
t.error(err, 'no error after cleanup')
t.end()
})
})
}
db.open(function (err) {
t.notOk(err, 'no error from open()')
db.batch(
[
{ type: 'put', key: 'one', value: '1' }
, { type: 'put', key: 'two', value: '2' }
, { type: 'put', key: 'three', value: '3' }
]
, function (err) {
t.notOk(err, 'no error from batch()')
testFn(db, t, done, loc)
}
)
t.notOk(err, 'no error from open()')
db.batch([
{ type: 'put', key: 'one', value: '1' },
{ type: 'put', key: 'two', value: '2' },
{ type: 'put', key: 'three', value: '3' }
], function (err) {
t.notOk(err, 'no error from batch()')
testFn(db, t, done, loc)
})
})
})
})
Expand Down
3 changes: 1 addition & 2 deletions test/open-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/open-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
6 changes: 1 addition & 5 deletions test/put-get-del-test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, fs = require('fs')
, path = require('path')
, testBuffer = fs.readFileSync(path.join(__dirname, 'data/testdata.bin'))
, abstract = require('abstract-leveldown/abstract/put-get-del-test')

abstract.all(leveldown, test, testCommon, testBuffer)
abstract.all(leveldown, test)
3 changes: 1 addition & 2 deletions test/put-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const test = require('tape')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, abstract = require('abstract-leveldown/abstract/put-test')

abstract.all(leveldown, test, testCommon)
abstract.all(leveldown, test)
6 changes: 0 additions & 6 deletions test/ranges-test.js

This file was deleted.

1 change: 0 additions & 1 deletion test/repair-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const test = require('tape')
, path = require('path')
, mkfiletree = require('mkfiletree')
, readfiletree = require('readfiletree')
, testCommon = require('abstract-leveldown/testCommon')
, leveldown = require('../')
, makeTest = require('./make')

Expand Down