'use strict' const { test } = require('tap') const fs = require('fs') const proxyquire = require('proxyquire') const SonicBoom = require('../') const { file, runTests } = require('./helper') runTests(buildTests) function buildTests (test, sync) { // Reset the umask for testing process.umask(0o000) test('flushSync', (t) => { t.plan(4) const dest = file() const fd = fs.openSync(dest, 'w') const stream = new SonicBoom({ fd, minLength: 4096, sync }) t.ok(stream.write('hello world\n')) t.ok(stream.write('something else\n')) stream.flushSync() // let the file system settle down things setImmediate(function () { stream.end() const data = fs.readFileSync(dest, 'utf8') t.equal(data, 'hello world\nsomething else\n') stream.on('close', () => { t.pass('close emitted') }) }) }) } test('retry in flushSync on EAGAIN', (t) => { t.plan(7) 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: false, minLength: 0 }) stream.on('ready', () => { t.pass('ready emitted') }) t.ok(stream.write('hello world\n')) fakeFs.writeSync = function (fd, buf, enc) { t.pass('fake fs.write called') fakeFs.writeSync = fs.writeSync const err = new Error('EAGAIN') err.code = 'EAGAIN' throw err } t.ok(stream.write('something else\n')) stream.flushSync() stream.end() stream.on('finish', () => { fs.readFile(dest, 'utf8', (err, data) => { t.error(err) t.equal(data, 'hello world\nsomething else\n') }) }) stream.on('close', () => { t.pass('close emitted') }) }) test('throw error in flushSync on EAGAIN', (t) => { t.plan(12) 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: false, minLength: 1000, retryEAGAIN: (err, writeBufferLen, remainingBufferLen) => { t.equal(err.code, 'EAGAIN') t.equal(writeBufferLen, 12) t.equal(remainingBufferLen, 0) return false } }) stream.on('ready', () => { t.pass('ready emitted') }) const err = new Error('EAGAIN') err.code = 'EAGAIN' fakeFs.writeSync = function (fd, buf, enc) { Error.captureStackTrace(err) t.pass('fake fs.write called') fakeFs.writeSync = fs.writeSync throw err } fakeFs.fsyncSync = function (...args) { t.pass('fake fs.fsyncSync called') fakeFs.fsyncSync = fs.fsyncSync return fs.fsyncSync.apply(null, args) } t.ok(stream.write('hello world\n')) t.throws(stream.flushSync.bind(stream), err, 'EAGAIN') t.ok(stream.write('something else\n')) stream.flushSync() stream.end() stream.on('finish', () => { fs.readFile(dest, 'utf8', (err, data) => { t.error(err) t.equal(data, 'hello world\nsomething else\n') }) }) stream.on('close', () => { t.pass('close emitted') }) })