From d40873ddcd392c70b8720a88d1b9adc94f553f1b Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Fri, 15 Jul 2016 02:24:38 +0300 Subject: [PATCH] test: ensure stream preprocessing order Sometimes it is necessary to preprocess some initial bit of a stream data before giving the entire stream to the main processing function. Sometimes this bit should be extracted from the stream before the main processing; sometimes it should be returned to the stream. This test checks an order of stream modes, methods and events for a possible preprocessing algorithm. Stream BOM stripping is selected as a use case. See https://github.com/nodejs/help/issues/221 as the prehistory. PR-URL: https://github.com/nodejs/node/pull/7741 Reviewed-By: Anna Henningsen --- test/fixtures/file-to-read-with-bom.txt | 3 + test/fixtures/file-to-read-without-bom.txt | 3 + test/parallel/test-stream-preprocess.js | 67 ++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 test/fixtures/file-to-read-with-bom.txt create mode 100644 test/fixtures/file-to-read-without-bom.txt create mode 100644 test/parallel/test-stream-preprocess.js diff --git a/test/fixtures/file-to-read-with-bom.txt b/test/fixtures/file-to-read-with-bom.txt new file mode 100644 index 00000000000000..d46c8708d97946 --- /dev/null +++ b/test/fixtures/file-to-read-with-bom.txt @@ -0,0 +1,3 @@ +abc +def +ghi diff --git a/test/fixtures/file-to-read-without-bom.txt b/test/fixtures/file-to-read-without-bom.txt new file mode 100644 index 00000000000000..8edb37e36dfbc0 --- /dev/null +++ b/test/fixtures/file-to-read-without-bom.txt @@ -0,0 +1,3 @@ +abc +def +ghi diff --git a/test/parallel/test-stream-preprocess.js b/test/parallel/test-stream-preprocess.js new file mode 100644 index 00000000000000..9cb4c1d3cca8ae --- /dev/null +++ b/test/parallel/test-stream-preprocess.js @@ -0,0 +1,67 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const fs = require('fs'); +const path = require('path'); +const rl = require('readline'); + +const BOM = '\uFEFF'; + +// Get the data using a non-stream way to compare with the streamed data. +const modelData = fs.readFileSync( + path.join(common.fixturesDir, 'file-to-read-without-bom.txt'), 'utf8' +); +const modelDataFirstCharacter = modelData[0]; + +// Detect the number of forthcoming 'line' events for mustCall() 'expected' arg. +const lineCount = modelData.match(/\n/g).length; + +// Ensure both without-bom and with-bom test files are textwise equal. +assert.strictEqual( + fs.readFileSync( + path.join(common.fixturesDir, 'file-to-read-with-bom.txt'), 'utf8' + ), + `${BOM}${modelData}` +); + +// An unjustified BOM stripping with a non-BOM character unshifted to a stream. +const inputWithoutBOM = fs.createReadStream( + path.join(common.fixturesDir, 'file-to-read-without-bom.txt'), 'utf8' +); + +inputWithoutBOM.once('readable', common.mustCall(() => { + const maybeBOM = inputWithoutBOM.read(1); + assert.strictEqual(maybeBOM, modelDataFirstCharacter); + assert.notStrictEqual(maybeBOM, BOM); + + inputWithoutBOM.unshift(maybeBOM); + + let streamedData = ''; + rl.createInterface({ + input: inputWithoutBOM, + }).on('line', common.mustCall((line) => { + streamedData += `${line}\n`; + }, lineCount)).on('close', common.mustCall(() => { + assert.strictEqual(streamedData, modelData); + })); +})); + +// A justified BOM stripping. +const inputWithBOM = fs.createReadStream( + path.join(common.fixturesDir, 'file-to-read-with-bom.txt'), 'utf8' +); + +inputWithBOM.once('readable', common.mustCall(() => { + const maybeBOM = inputWithBOM.read(1); + assert.strictEqual(maybeBOM, BOM); + + let streamedData = ''; + rl.createInterface({ + input: inputWithBOM, + }).on('line', common.mustCall((line) => { + streamedData += `${line}\n`; + }, lineCount)).on('close', common.mustCall(() => { + assert.strictEqual(streamedData, modelData); + })); +}));