diff --git a/package.json b/package.json index 9901d76..d8d3c96 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "pullout": "^4.0.0", "pump": "^3.0.0", "putout": "^9.1.0", + "serve-once": "^2.0.0", "supertape": "^2.0.1", "tar-fs": "^2.0.0", "tar-stream": "^2.1.0", diff --git a/test/pipe.js b/test/pipe.js index 0e736cc..d9ae708 100644 --- a/test/pipe.js +++ b/test/pipe.js @@ -1,5 +1,7 @@ 'use strict'; +const {once} = require('events'); + const fs = require('fs'); const path = require('path'); const http = require('http'); @@ -7,7 +9,6 @@ const os = require('os'); const zlib = require('zlib'); const {Readable} = require('stream'); -const through2 = require('through2'); const { callbackify, promisify, @@ -18,9 +19,10 @@ const gunzip = require('gunzip-maybe'); const pullout = require('pullout'); const tryToCatch = require('try-to-catch'); const tarStream = require('tar-stream'); +const through2 = require('through2'); +const serveOnce = require('serve-once') -const _pipe = require('..'); -const pipe = callbackify(_pipe); +const pipe = require('..'); const test = require('supertape'); const random = Math.random(); @@ -32,7 +34,7 @@ test('empty buffer | write file: error directory', async (t) => { inStream.push(null); - const [e] = await tryToCatch(_pipe, [inStream, fs.createWriteStream('/')]); + const [e] = await tryToCatch(pipe, [inStream, fs.createWriteStream('/')]); t.equal(e.code, 'EISDIR', 'should equal'); t.end(); @@ -41,7 +43,7 @@ test('empty buffer | write file: error directory', async (t) => { test('file1 | gunzip maybe: error', async (t) => { const file = fs.createReadStream('/hello'); - const [e] = await tryToCatch(_pipe, [file, gunzip()]); + const [e] = await tryToCatch(pipe, [file, gunzip()]); t.equal(e.code, 'ENOENT', 'should return error'); t.end(); @@ -50,7 +52,7 @@ test('file1 | gunzip maybe: error', async (t) => { test('file1 | gunzip maybe: error', async (t) => { const file = fs.createReadStream('/hello'); - const [e] = await tryToCatch(_pipe, [file, gunzip()]); + const [e] = await tryToCatch(pipe, [file, gunzip()]); t.equal(e.code, 'ENOENT', 'should return error'); t.end(); @@ -62,7 +64,7 @@ test('file | unzip | untar', async (t) => { const streamUnzip = gunzip(); const streamParse = tarStream.extract(); - const [e] = await tryToCatch(_pipe, [ + const [e] = await tryToCatch(pipe, [ streamFile, streamUnzip, streamParse, @@ -76,9 +78,8 @@ test('file1 | file2: no error', async (t) => { const tmp = os.tmpdir(); const name = path.basename(__filename); const nameTmp = path.join(tmp, name + random); - const _tryPipe = promisify(tryPipe); - await _tryPipe(__filename, nameTmp); + await tryPipe(__filename, nameTmp); const file1 = fs.readFileSync(__filename, 'utf8'); const file2 = fs.readFileSync(nameTmp, 'utf8'); @@ -96,37 +97,36 @@ test('file1 | file2: no open event', async (t) => { const from = fs.createReadStream(__filename); const to = fs.createWriteStream(nameTmp); - to.on('open', async () => { - await _pipe([from, to]); - - const file1 = fs.readFileSync(__filename, 'utf8'); - const file2 = fs.readFileSync(nameTmp, 'utf8'); - - fs.unlinkSync(nameTmp); - - t.equal(file1, file2, 'files equal'); - t.end(); - }); + await once(to, 'open'); + await pipe([from, to]); + + const file1 = fs.readFileSync(__filename, 'utf8'); + const file2 = fs.readFileSync(nameTmp, 'utf8'); + + fs.unlinkSync(nameTmp); + + t.equal(file1, file2, 'files equal'); + t.end(); }); -test('file1 | file2: write open EACESS', (t) => { +test('file1 | file2: write open EACESS', async (t) => { const name = path.basename(__filename); const nameTmp = '/' + name + random; - tryPipe(__filename, nameTmp, (error) => { - t.ok(error, error && error.message); - t.end(); - }); + const [error] = await tryPipe(__filename, nameTmp); + + t.ok(error, error && error.message); + t.end(); }); -test('file1 | file2: write open EACESS: big file', (t) => { +test('file1 | file2: write open EACESS: big file', async (t) => { const name = path.basename(__filename); const nameTmp = '/' + name + random; - tryPipe('/bin/bash', nameTmp, (error) => { - t.ok(error, error && error.message); - t.end(); - }); + const [error] = await tryPipe('/bin/bash', nameTmp); + + t.ok(error, error && error.message); + t.end(); }); test('file1 | file2: read open ENOENT', async (t) => { @@ -137,36 +137,36 @@ test('file1 | file2: read open ENOENT', async (t) => { const read = fs.createReadStream(__filename + random); const write = fs.createWriteStream(nameTmp); - const [error] = await tryToCatch(_pipe, [read, write]); + const [error] = await tryToCatch(pipe, [read, write]); t.ok(error, error && error.message); t.end(); }); -test('file1 | file2: error read EISDIR', (t) => { +test('file1 | file2: error read EISDIR', async(t) => { const tmp = os.tmpdir(); const name = path.basename(__filename); const nameTmp = path.join(tmp, name + random); - tryPipe('/', nameTmp, (error) => { - fs.unlinkSync(nameTmp); - t.equal(error.code, 'EISDIR', 'EISDIR: read error'); - t.end(); - }); + const [error] = await tryPipe('/', nameTmp); + fs.unlinkSync(nameTmp); + + t.equal(error.code, 'EISDIR', 'EISDIR: read error'); + t.end(); }); -test('file | dir: error write EISDIR', (t) => { - tryPipe(__filename, '/', (error) => { - t.equal(error.code, 'EISDIR', 'EISDIR: write error'); - t.end(); - }); +test('file | dir: error write EISDIR', async (t) => { + const [error] = await tryPipe(__filename, '/'); + + t.equal(error.code, 'EISDIR', 'EISDIR: write error'); + t.end(); }); -test('dir1 | dir2: error read/write EISDIR', (t) => { - tryPipe(__dirname, '/', (error) => { - t.equal(error.code, 'EISDIR', 'read/write EISDIR'); - t.end(); - }); +test('dir1 | dir2: error read/write EISDIR', async (t) => { + const [error] = await tryPipe(__dirname, '/'); + + t.equal(error.code, 'EISDIR', 'read/write EISDIR'); + t.end(); }); test('file1 | gzip | file2: no errors', async (t) => { @@ -178,7 +178,7 @@ test('file1 | gzip | file2: no errors', async (t) => { const write = fs.createWriteStream(nameTmp); const zipStream = zlib.createGzip(); - await _pipe([read, zipStream, write]); + await pipe([read, zipStream, write]); const file1 = fs.readFileSync(__filename, 'utf8'); const file2 = fs.readFileSync(nameTmp); @@ -190,44 +190,44 @@ test('file1 | gzip | file2: no errors', async (t) => { t.end(); }); -test('file1 | gzip', (t) => { +test('file1 | gzip', async (t) => { const read = fs.createReadStream(__filename); const zip = zlib.createGzip(); - pipe([read, zip], (error) => { - t.notOk(error, 'no errors'); - t.end(); - }); + const [error] = await tryToCatch(pipe, [read, zip]); + + t.notOk(error, 'no errors'); + t.end(); }); -test('file1 | gzip: error ENOENT', (t) => { +test('file1 | gzip: error ENOENT', async (t) => { const read = fs.createReadStream(__filename + random); const zip = zlib.createGzip(); - pipe([read, zip], (error) => { - t.ok(error, error.message); - t.end(); - }); + const [error] = await tryToCatch(pipe, [read, zip]); + + t.ok(error, error.message); + t.end(); }); -test('file1 | gzip: error EISDIR', (t) => { +test('file1 | gzip: error EISDIR', async (t) => { const read = fs.createReadStream('/'); const zip = zlib.createGzip(); - pipe([read, zip], (error) => { - t.ok(error, error.message); - t.end(); - }); + const [error] = await tryToCatch(pipe, [read, zip]); + + t.ok(error, error.message); + t.end(); }); -test('file1 | gunzip: error header check', (t) => { +test('file1 | gunzip: error header check', async (t) => { const read = fs.createReadStream(__filename); const gunzip = zlib.createGunzip(); - pipe([read, gunzip], (error) => { - t.ok(error, error.message); - t.end(); - }); + const [error] = await tryToCatch(pipe, [read, gunzip]); + + t.ok(error, error.message); + t.end(); }); test('file1 | gunzip | untar: error header check', async (t) => { @@ -235,7 +235,7 @@ test('file1 | gunzip | untar: error header check', async (t) => { const gunzip = zlib.createGunzip(); const tarStream = tar.extract(__dirname); - const [error] = await tryToCatch(_pipe, [read, gunzip, tarStream]); + const [error] = await tryToCatch(pipe, [read, gunzip, tarStream]); t.ok(error, error.message); t.end(); @@ -246,13 +246,13 @@ test('file1 | gunzip | untar: error header check: gz', async (t) => { const gunzip = zlib.createGunzip(); const tarStream = tar.extract(__dirname); - const [error] = await tryToCatch(_pipe, [read, gunzip, tarStream]); + const [error] = await tryToCatch(pipe, [read, gunzip, tarStream]); t.ok(error, error.message); t.end(); }); -test('tar | gzip | file', (t) => { +test('tar | gzip | file', async (t) => { const fixture = path.join(__dirname, 'fixture'); const to = path.join(os.tmpdir(), `${Math.random()}.tar.gz`); const tarStream = tar.pack(fixture, { @@ -264,16 +264,16 @@ test('tar | gzip | file', (t) => { const gzip = zlib.createGzip(); const write = fs.createWriteStream(to); - pipe([tarStream, gzip, write], () => { - const toFile = fs.readFileSync(to); - - fs.unlinkSync(to); - t.ok(toFile.length, 'should pack file'); - t.end(); - }); + await pipe([tarStream, gzip, write]); + const toFile = fs.readFileSync(to); + + fs.unlinkSync(to); + + t.ok(toFile.length, 'should pack file'); + t.end(); }); -test('tar | gzip | file: error: EACESS', (t) => { +test('tar | gzip | file: error: EACESS', async (t) => { const fixture = path.join(__dirname, 'fixture'); const to = path.join(`/${Math.random()}.tar.gz`); const tarStream = tar.pack(fixture, { @@ -285,92 +285,62 @@ test('tar | gzip | file: error: EACESS', (t) => { const gzip = zlib.createGzip(); const write = fs.createWriteStream(to); - pipe([tarStream, gzip, write], (error) => { - t.ok(error); - t.end(); - }); + const [error] = await tryToCatch(pipe, [tarStream, gzip, write]); + + t.ok(error); + t.end(); }); -test('put file', (t) => { - const server = http.createServer((req, res) => { +test('put file', async (t) => { + const middleware = () => async (req, res) => { const write = fs.createWriteStream('/xxxxxxx'); - - pipe([req, write], () => { - server.close(); - - t.pass('should not crash'); - t.end(); - }); + await pipe([req, write]); res.end(); - }); + }; - server.listen(() => { - const {port} = server.address(); - - const options = { - method: 'PUT', - hostname: 'localhost', - port, - path: '/', - }; - - const req = http.request(options, () => { - server.close(); - }); - - req.end(); - }); + const {request} = serveOnce(middleware); + + await request.put('/'); + + t.pass('should not crash'); + t.end(); }); test('read file| through| write directory: error', async (t) => { const transform = through2((chunk, enc, cb) => cb(null, chunk)); - const [e] = await tryToCatch(_pipe, [fs.createReadStream('/sdlfj'), transform, fs.createWriteStream('/dsfsdf')]); - //const [e] = await tryToCatch(_pipe, [fs.createReadStream('/sdlfj'), fs.createWriteStream('/dsfsdf')]); + const [e] = await tryToCatch(pipe, [fs.createReadStream('/sdlfj'), transform, fs.createWriteStream('/dsfsdf')]); t.equal(e.code, 'EACCES', 'should equal'); t.end(); }); -test('put file | unzip', (t) => { - const server = http.createServer((req, res) => { +test('put file | unzip', async (t) => { + const middleware = () => async (req, res) => { const gunzip = zlib.createGunzip(); const transform = through2((chunk, enc, cb) => cb(null, chunk)); - pipe([req, gunzip, transform], () => { - server.close(); - - t.pass('should not crash'); - t.end(); - }); + await pipe([req, gunzip, transform]); res.end(); - }); + }; - server.listen(() => { - const {port} = server.address(); - - const options = { - method: 'PUT', - hostname: 'localhost', - port, - path: '/', - }; - - const req = http.request(options, () => { - server.close(); - }); - - req.end(); - }); + const {request} = serveOnce(middleware); + + await request.put('/'); + + t.pass('should not crash'); + t.end(); }); -test('file1, file2 | response: end false', (t) => { +test('file1, file2 | response: end false', async (t) => { const server = http.createServer((req, res) => { const read1 = fs.createReadStream(__filename); const read2 = fs.createReadStream(__filename); - pipe([read1, res], {end: false}, () => { + pipe([read1, res], { + end: false, + }, () => { pipe([read2, res], (error) => { t.notOk(error, 'file1, file2 -> response'); }); @@ -379,13 +349,13 @@ test('file1, file2 | response: end false', (t) => { server.listen(() => { const {port} = server.address(); + const url = `http://127.0.0.1:${port}`; http.get(url, (res) => { pullout(res).then((data) => { const file = fs.readFileSync(__filename, 'utf8'); server.close(); - t.equal(data.length, file.length * 2, 'reponse == file1 + file2'); t.end(); }); @@ -395,13 +365,12 @@ test('file1, file2 | response: end false', (t) => { }); }); - server.on('error', (error) => { - t.ok(error, error.message); - t.end(); - }); + const [error] = await once(server, 'error'); + t.ok(error, error.message); + t.end(); }); -test('file1, file2 | options: empty object', (t) => { +test('file1, file2 | options: empty object', async (t) => { const server = http.createServer((req, res) => { const read1 = fs.createReadStream(__filename); const read2 = fs.createReadStream(__filename); @@ -416,7 +385,6 @@ test('file1, file2 | options: empty object', (t) => { pullout(res).then((data) => { const file = fs.readFileSync(__filename, 'utf8'); server.close(); - t.equal(data.length, file.length, 'reponse == file'); t.end(); }); @@ -426,18 +394,15 @@ test('file1, file2 | options: empty object', (t) => { }); }); - server.on('error', (error) => { - t.ok(error, error.message); - t.end(); - }); + const [error] = await once(server, 'error'); + t.ok(error, error.message); + t.end(); }); -function tryPipe(from, to, fn) { +async function tryPipe(from, to) { const read = fs.createReadStream(from); const write = fs.createWriteStream(to); - pipe([read, write], (error) => { - fn(error); - }); + return await tryToCatch(pipe, [read, write]); }