Buckets:
| const fs = require('fs') | |
| const path = require('path') | |
| const SonicBoom = require('../') | |
| const { file, runTests } = require('./helper') | |
| const proxyquire = require('proxyquire') | |
| runTests(buildTests) | |
| function buildTests (test, sync) { | |
| // Reset the unmask for testing | |
| process.umask(0o000) | |
| test('append', (t) => { | |
| t.plan(4) | |
| const dest = file() | |
| fs.writeFileSync(dest, 'hello world\n') | |
| const stream = new SonicBoom({ dest, append: false, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| t.ok(stream.write('something else\n')) | |
| stream.flush() | |
| stream.on('drain', () => { | |
| fs.readFile(dest, 'utf8', (err, data) => { | |
| t.error(err) | |
| t.equal(data, 'something else\n') | |
| stream.end() | |
| }) | |
| }) | |
| }) | |
| test('mkdir', (t) => { | |
| t.plan(4) | |
| const dest = path.join(file(), 'out.log') | |
| const stream = new SonicBoom({ dest, mkdir: true, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| t.ok(stream.write('hello world\n')) | |
| stream.flush() | |
| stream.on('drain', () => { | |
| fs.readFile(dest, 'utf8', (err, data) => { | |
| t.error(err) | |
| t.equal(data, 'hello world\n') | |
| stream.end() | |
| }) | |
| }) | |
| }) | |
| test('flush', (t) => { | |
| t.plan(5) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 4096, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| t.ok(stream.write('hello world\n')) | |
| t.ok(stream.write('something else\n')) | |
| stream.flush() | |
| stream.on('drain', () => { | |
| fs.readFile(dest, 'utf8', (err, data) => { | |
| t.error(err) | |
| t.equal(data, 'hello world\nsomething else\n') | |
| stream.end() | |
| }) | |
| }) | |
| }) | |
| test('flush with no data', (t) => { | |
| t.plan(2) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 4096, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| stream.flush() | |
| stream.on('drain', () => { | |
| t.pass('drain emitted') | |
| }) | |
| }) | |
| test('call flush cb after flushed', (t) => { | |
| t.plan(4) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 4096, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| t.ok(stream.write('hello world\n')) | |
| t.ok(stream.write('something else\n')) | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| }) | |
| }) | |
| test('only call fsyncSync and not fsync when fsync: true', (t) => { | |
| t.plan(6) | |
| const fakeFs = Object.create(fs) | |
| const SonicBoom = proxyquire('../', { | |
| fs: fakeFs | |
| }) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ | |
| fd, | |
| sync, | |
| fsync: true, | |
| minLength: 4096 | |
| }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| fakeFs.fsync = function (fd, cb) { | |
| t.fail('fake fs.fsync called while should not') | |
| cb() | |
| } | |
| fakeFs.fsyncSync = function (fd) { | |
| t.pass('fake fsyncSync called') | |
| } | |
| function successOnAsyncOrSyncFn (isSync, originalFn) { | |
| return function (...args) { | |
| t.pass(`fake fs.${originalFn.name} called`) | |
| fakeFs[originalFn.name] = originalFn | |
| return fakeFs[originalFn.name](...args) | |
| } | |
| } | |
| if (sync) { | |
| fakeFs.writeSync = successOnAsyncOrSyncFn(true, fs.writeSync) | |
| } else { | |
| fakeFs.write = successOnAsyncOrSyncFn(false, fs.write) | |
| } | |
| t.ok(stream.write('hello world\n')) | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| process.nextTick(() => { | |
| // to make sure fsync is not called as well | |
| t.pass('nextTick after flush called') | |
| }) | |
| }) | |
| }) | |
| test('call flush cb with error when fsync failed', (t) => { | |
| t.plan(5) | |
| const fakeFs = Object.create(fs) | |
| const SonicBoom = proxyquire('../', { | |
| fs: fakeFs | |
| }) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ | |
| fd, | |
| sync, | |
| minLength: 4096 | |
| }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| const err = new Error('other') | |
| err.code = 'other' | |
| function onFsyncOnFsyncSync (isSync, originalFn) { | |
| return function (...args) { | |
| Error.captureStackTrace(err) | |
| t.pass(`fake fs.${originalFn.name} called`) | |
| fakeFs[originalFn.name] = originalFn | |
| const cb = args[args.length - 1] | |
| cb(err) | |
| } | |
| } | |
| // only one is called depends on sync | |
| fakeFs.fsync = onFsyncOnFsyncSync(false, fs.fsync) | |
| function successOnAsyncOrSyncFn (isSync, originalFn) { | |
| return function (...args) { | |
| t.pass(`fake fs.${originalFn.name} called`) | |
| fakeFs[originalFn.name] = originalFn | |
| return fakeFs[originalFn.name](...args) | |
| } | |
| } | |
| if (sync) { | |
| fakeFs.writeSync = successOnAsyncOrSyncFn(true, fs.writeSync) | |
| } else { | |
| fakeFs.write = successOnAsyncOrSyncFn(false, fs.write) | |
| } | |
| t.ok(stream.write('hello world\n')) | |
| stream.flush((err) => { | |
| if (err) t.equal(err.code, 'other') | |
| else t.fail('flush cb called without an error') | |
| }) | |
| }) | |
| test('call flush cb even when have no data', (t) => { | |
| t.plan(2) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 4096, sync }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| }) | |
| }) | |
| }) | |
| test('call flush cb even when minLength is 0', (t) => { | |
| t.plan(1) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 0, sync }) | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| }) | |
| }) | |
| test('call flush cb with an error when trying to flush destroyed stream', (t) => { | |
| t.plan(1) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ fd, minLength: 4096, sync }) | |
| stream.destroy() | |
| stream.flush((err) => { | |
| if (err) t.pass(err) | |
| else t.fail('flush cb called without an error') | |
| }) | |
| }) | |
| test('call flush cb with an error when failed to flush', (t) => { | |
| t.plan(5) | |
| const fakeFs = Object.create(fs) | |
| const SonicBoom = proxyquire('../', { | |
| fs: fakeFs | |
| }) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ | |
| fd, | |
| sync, | |
| minLength: 4096 | |
| }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| const err = new Error('other') | |
| err.code = 'other' | |
| function onWriteOrWriteSync (isSync, originalFn) { | |
| return function (...args) { | |
| Error.captureStackTrace(err) | |
| t.pass(`fake fs.${originalFn.name} called`) | |
| fakeFs[originalFn.name] = originalFn | |
| if (isSync) throw err | |
| const cb = args[args.length - 1] | |
| cb(err) | |
| } | |
| } | |
| // only one is called depends on sync | |
| fakeFs.write = onWriteOrWriteSync(false, fs.write) | |
| fakeFs.writeSync = onWriteOrWriteSync(true, fs.writeSync) | |
| t.ok(stream.write('hello world\n')) | |
| stream.flush((err) => { | |
| if (err) t.equal(err.code, 'other') | |
| else t.fail('flush cb called without an error') | |
| }) | |
| stream.end() | |
| stream.on('close', () => { | |
| t.pass('close emitted') | |
| }) | |
| }) | |
| test('call flush cb when finish writing when currently in the middle', (t) => { | |
| t.plan(4) | |
| const fakeFs = Object.create(fs) | |
| const SonicBoom = proxyquire('../', { | |
| fs: fakeFs | |
| }) | |
| const dest = file() | |
| const fd = fs.openSync(dest, 'w') | |
| const stream = new SonicBoom({ | |
| fd, | |
| sync, | |
| // to trigger write without calling flush | |
| minLength: 1 | |
| }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| function onWriteOrWriteSync (originalFn) { | |
| return function (...args) { | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| }) | |
| t.pass(`fake fs.${originalFn.name} called`) | |
| fakeFs[originalFn.name] = originalFn | |
| return originalFn(...args) | |
| } | |
| } | |
| // only one is called depends on sync | |
| fakeFs.write = onWriteOrWriteSync(fs.write) | |
| fakeFs.writeSync = onWriteOrWriteSync(fs.writeSync) | |
| t.ok(stream.write('hello world\n')) | |
| }) | |
| test('call flush cb when writing and trying to flush before ready (on async)', (t) => { | |
| t.plan(4) | |
| const fakeFs = Object.create(fs) | |
| const SonicBoom = proxyquire('../', { | |
| fs: fakeFs | |
| }) | |
| fakeFs.open = fsOpen | |
| const dest = file() | |
| const stream = new SonicBoom({ | |
| fd: dest, | |
| // only async as sync is part of the constructor so the user will not be able to call write/flush | |
| // before ready | |
| sync: false, | |
| // to not trigger write without calling flush | |
| minLength: 4096 | |
| }) | |
| stream.on('ready', () => { | |
| t.pass('ready emitted') | |
| }) | |
| function fsOpen (...args) { | |
| process.nextTick(() => { | |
| // try writing and flushing before ready and in the middle of opening | |
| t.pass('fake fs.open called') | |
| t.ok(stream.write('hello world\n')) | |
| // calling flush | |
| stream.flush((err) => { | |
| if (err) t.fail(err) | |
| else t.pass('flush cb called') | |
| }) | |
| fakeFs.open = fs.open | |
| fs.open(...args) | |
| }) | |
| } | |
| }) | |
| } | |
Xet Storage Details
- Size:
- 9.68 kB
- Xet hash:
- d018e6cc9377fb2fe8fe031286403146c690d4825c9dd0b84c9949c67d192d14
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.