test('.truncate(lsn) fails when LSN out of range (ahead of entries)', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.truncate(1)) .catch(err => { t.equal('' + err, 'AssertionError: index out of range', 'AssertionError: index out of range'); t.end(); }); }); });
test('WriteAheadLog.openOrCreate({ path: \'random-temp\', index: \'specified\', writable: true }) creates a new log with the specified names', t => { tmp.tmpName((err, path) => { let index = path + '-my-specified-name'; if (err) t.fail('' + err); WriteAheadLog.openOrCreate({ path, index, writable: true }) .then(wal => { t.ok(wal.writable, 'new logs are writable'); t.equal(wal.name, path, '.name is the temp file'); t.equal(wal.index, index, '.index has the specified name'); t.equal(wal.size, 0, '.size is 0 (zero)'); t.equal(wal.next, 0, '.next is 0 (zero)'); t.equal(wal.commitHead, -1, '.commitHead is -1 (none)'); t.end(); }) .catch(err => { t.fail('' + err); }); }); });
test('WriteAheadLog.open({ path: \'random-temp\' }) succeeds opening a valid log', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.close()) .then(() => WriteAheadLog.open({ path }) .then(wal => { t.notOk(wal.writable, 'opened file without writable mode'); t.equal(wal.name, path, 'opened file is the created file'); t.end(); })) .catch(err => { t.fail('' + err); }); }); });
test('WriteAheadLog.create({ path: \'random-temp\' }) creates a new log with a default index file name', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => { t.equal(wal.name, path, '.name is the temp file'); t.equal(wal.index, path + WriteAheadLog.DEFAULT_INDEX_EXT, '.index is conventionally named'); t.equal(wal.size, 0, '.size is 0 (zero)'); t.equal(wal.next, 0, '.next is 0 (zero)'); t.equal(wal.commitHead, -1, '.commitHead is -1 (none)'); t.end(); }) .catch(err => { t.fail('' + err); }); }); });
test('WriteAheadLog.open({ path: \'random-temp\' }) fails when file doesn\'t exist', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.open({ path }) .then(wal => { t.fail(`Non-existent log should cause an error: ${wal.name}`); }) .catch(err => { t.equal(err.code, 'ENOENT', '' + err); t.end(); }); }); });
test('.recover() is benign when called on a new, empty log', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.recover(false)) .then(wal => { t.equal(wal.name, path, '.name is the temp file'); t.equal(wal.size, 0, '.size is 0 (zero)'); t.equal(wal.next, 0, '.next is 0 (zero)'); t.equal(wal.commitHead, -1, '.commitHead is -1 (none)'); t.end(); }) .catch(err => { t.fail('' + err); }); }); });
test('.read() fails when index unspecified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.read() .then(() => t.fail('Should fail due to missing LSN.'))) .catch(err => { t.equal('' + err, 'AssertionError: index (number) is required'); t.end(); }); }); });
test('.readRange() fails when arguments not specified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.readRange()) .catch(err => { t.equal('' + err, 'AssertionError: first (number) is required', 'AssertionError: first (number) is required'); t.end(); }); }); });
test('WriteAheadLog.openOrCreate({ path: \'random-temp\' }) when writable not specified and path doesn\'t exist', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.openOrCreate({ path }) .then(wal => { t.fail(`Non-existent log should cause an error: ${wal.name}`); }) .catch(err => { t.equal(err.code, 'ENOENT', '' + err); t.end(); }); }); });
test('.write(data) fails when data not specified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.write() .then(() => t.fail('Should fail due to missing data.'))) .catch(err => { t.equal('' + err, 'AssertionError: data (Buffer) is required', 'AssertionError: data (Buffer) is required'); t.end(); }); }); });
test('.recover() fails when handler unspecified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.recover()) .catch(err => { t.equal('' + err, 'AssertionError: handler (function) is required', 'AssertionError: handler (function) is required'); t.end(); }); }); });
test('.commit() fails when index unsepcified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.commit() .then(() => t.fail('Should fail due to missing LSN.'))) .catch(err => { t.equal('' + err, 'AssertionError: index (number) is required', 'AssertionError: index (number) is required' ); t.end(); }); }); });
test('.truncate() fails when LSN unspecified', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.truncate()) .catch(err => { t.equal('' + err, 'AssertionError: from (number) is required', 'AssertionError: from (number) is required'); t.end(); }); }); });
test('WriteAheadLog.openOrCreate({ path: \'random-temp\', index: \'specified\' }) when writable not specified and path doesn\'t exist', t => { tmp.tmpName((err, path) => { let index = path + '-my-specified-name'; if (err) t.fail('' + err); WriteAheadLog.openOrCreate({ path, index }) .then(wal => { t.fail(`Non-existent log should cause an error: ${wal.name}`); }) .catch(err => { t.equal(err.code, 'ENOENT', '' + err); t.end(); }); }); });
test('.write(data) fails when data is wrong type', t => { tmp.tmpName((err, path) => { if (err) t.fail('' + err); WriteAheadLog.create({ path }) .then(wal => wal.write('This is string data.') .then(() => t.fail('Should fail due to data of wrong type.'))) .catch(err => { t.equal('' + err, 'AssertionError: data (Buffer) is required', 'AssertionError: data (Buffer) is required'); t.end(); }); }); });