diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..404abb2 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +coverage/ diff --git a/index.js b/index.js index 6e12661..5f6aa98 100644 --- a/index.js +++ b/index.js @@ -1,43 +1,43 @@ -'use strict'; +'use strict' -var events = require('events'); -var once = require('once'); +var events = require('events') +var once = require('once') -module.exports = stream; +module.exports = stream function stream(processor) { - var chunks = []; - var emitter = new events.EventEmitter(); - var ended = false; + var chunks = [] + var emitter = new events.EventEmitter() + var ended = false - emitter.processor = processor; - emitter.readable = true; - emitter.writable = true; - emitter.write = write; - emitter.end = end; - emitter.pipe = pipe; + emitter.processor = processor + emitter.readable = true + emitter.writable = true + emitter.write = write + emitter.end = end + emitter.pipe = pipe - return emitter; + return emitter /* Write a chunk into memory. */ function write(chunk, encoding, callback) { if (typeof encoding === 'function') { - callback = encoding; - encoding = null; + callback = encoding + encoding = null } if (ended) { - throw new Error('Did not expect `write` after `end`'); + throw new Error('Did not expect `write` after `end`') } - chunks.push((chunk || '').toString(encoding || 'utf8')); + chunks.push((chunk || '').toString(encoding || 'utf8')) if (callback) { - callback(); + callback() } /* Signal succesful write. */ - return true; + return true } /* End the writing. Passes all arguments to a final @@ -47,37 +47,37 @@ function stream(processor) { * succesful. If messages are triggered during the * process, those are triggerd as `warning`s. */ function end() { - write.apply(null, arguments); + write.apply(null, arguments) - ended = true; + ended = true - processor.process(chunks.join(''), done); + processor.process(chunks.join(''), done) - return true; + return true function done(err, file) { - var messages = file ? file.messages : []; - var length = messages.length; - var index = -1; + var messages = file ? file.messages : [] + var length = messages.length + var index = -1 - chunks = null; + chunks = null /* Trigger messages as warnings, except for fatal error. */ while (++index < length) { /* istanbul ignore else - shouldn’t happen. */ if (messages[index] !== err) { - emitter.emit('warning', messages[index]); + emitter.emit('warning', messages[index]) } } if (err) { /* Don’t enter an infinite error throwing loop. */ - global.setTimeout(function () { - emitter.emit('error', err); - }, 4); + global.setTimeout(function() { + emitter.emit('error', err) + }, 4) } else { - emitter.emit('data', file.contents); - emitter.emit('end'); + emitter.emit('data', file.contents) + emitter.emit('end') } } } @@ -89,63 +89,63 @@ function stream(processor) { * * See https://github.com/nodejs/node/blob/master/lib/stream.js#L26. */ function pipe(dest, options) { - var settings = options || {}; - var onend = once(onended); + var settings = options || {} + var onend = once(onended) - emitter.on('data', ondata); - emitter.on('error', onerror); - emitter.on('end', cleanup); - emitter.on('close', cleanup); + emitter.on('data', ondata) + emitter.on('error', onerror) + emitter.on('end', cleanup) + emitter.on('close', cleanup) /* If the 'end' option is not supplied, dest.end() will be * called when the 'end' or 'close' events are received. * Only dest.end() once. */ if (!dest._isStdio && settings.end !== false) { - emitter.on('end', onend); + emitter.on('end', onend) } - dest.on('error', onerror); - dest.on('close', cleanup); + dest.on('error', onerror) + dest.on('close', cleanup) - dest.emit('pipe', emitter); + dest.emit('pipe', emitter) - return dest; + return dest /* End destination. */ function onended() { if (dest.end) { - dest.end(); + dest.end() } } /* Handle data. */ function ondata(chunk) { if (dest.writable) { - dest.write(chunk); + dest.write(chunk) } } /* Clean listeners. */ function cleanup() { - emitter.removeListener('data', ondata); - emitter.removeListener('end', onend); - emitter.removeListener('error', onerror); - emitter.removeListener('end', cleanup); - emitter.removeListener('close', cleanup); - - dest.removeListener('error', onerror); - dest.removeListener('close', cleanup); + emitter.removeListener('data', ondata) + emitter.removeListener('end', onend) + emitter.removeListener('error', onerror) + emitter.removeListener('end', cleanup) + emitter.removeListener('close', cleanup) + + dest.removeListener('error', onerror) + dest.removeListener('close', cleanup) } /* Close dangling pipes and handle unheard errors. */ function onerror(err) { - var handlers = emitter._events.error; + var handlers = emitter._events.error - cleanup(); + cleanup() /* Cannot use `listenerCount` in node <= 0.12. */ if (!handlers || handlers.length === 0 || handlers === onerror) { - throw err; /* Unhandled stream error in pipe. */ + throw err /* Unhandled stream error in pipe. */ } } } diff --git a/package.json b/package.json index 2691e62..5ddb0ea 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "devDependencies": { "is-function": "^1.0.1", "nyc": "^11.0.0", + "prettier": "^1.12.1", "remark-cli": "^5.0.0", "remark-preset-wooorm": "^4.0.0", "tape": "^4.6.3", @@ -29,12 +30,10 @@ "xo": "^0.20.0" }, "scripts": { - "build-md": "remark . -qfo", - "build": "npm run build-md", - "lint": "xo", + "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run build && npm run lint && npm run test-coverage" + "test": "npm run format && npm run test-coverage" }, "nyc": { "check-coverage": true, @@ -42,13 +41,22 @@ "functions": 100, "branches": 100 }, + "prettier": { + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "bracketSpacing": false, + "semi": false, + "trailingComma": "none" + }, "xo": { - "space": true, + "prettier": true, "esnext": false, "rules": { "guard-for-in": "off", "no-var": "off", - "prefer-arrow-callback": "off" + "prefer-arrow-callback": "off", + "unicorn/number-literal-case": "off" } }, "remarkConfig": { diff --git a/readme.md b/readme.md index 1ab4ec5..6659e4c 100644 --- a/readme.md +++ b/readme.md @@ -17,13 +17,11 @@ npm install unified-stream The below example pipes stdin, into an HTML formatter, to stdout. ```js -var stream = require('unified-stream'); -var rehype = require('rehype'); -var format = require('rehype-format'); +var stream = require('unified-stream') +var rehype = require('rehype') +var format = require('rehype-format') -process.stdin - .pipe(stream(rehype().use(format))) - .pipe(process.stdout); +process.stdin.pipe(stream(rehype().use(format))).pipe(process.stdout) ``` ## API diff --git a/test.js b/test.js index 5df9619..dd4a873 100644 --- a/test.js +++ b/test.js @@ -1,199 +1,197 @@ -'use strict'; +'use strict' -var stream = require('stream'); -var test = require('tape'); -var unified = require('unified'); -var func = require('is-function'); -var createStream = require('.'); +var stream = require('stream') +var test = require('tape') +var unified = require('unified') +var func = require('is-function') +var createStream = require('.') -test('createStream', function (t) { - var proc = unified().use(parse).use(stringify); +test('createStream', function(t) { + var proc = unified() + .use(parse) + .use(stringify) - t.test('interface', function (st) { - var tr = createStream(proc); - st.equal(tr.readable, true, 'should be readable'); - st.equal(tr.writable, true, 'should be writable'); - st.ok(func(tr.write), 'should have a `write` method'); - st.ok(func(tr.end), 'should have an `end` method'); - st.ok(func(tr.pipe), 'should have a `pipe` method'); - st.end(); - }); + t.test('interface', function(st) { + var tr = createStream(proc) + st.equal(tr.readable, true, 'should be readable') + st.equal(tr.writable, true, 'should be writable') + st.ok(func(tr.write), 'should have a `write` method') + st.ok(func(tr.end), 'should have an `end` method') + st.ok(func(tr.pipe), 'should have a `pipe` method') + st.end() + }) - t.test('#end and #write', function (st) { - var phase; - var exception; + t.test('#end and #write', function(st) { + var phase + var exception - st.plan(10); + st.plan(10) - st.equal(createStream(proc).end(), true, 'should return true'); + st.equal(createStream(proc).end(), true, 'should return true') st.throws( - function () { - var tr = createStream(proc); - tr.end(); - tr.end(); + function() { + var tr = createStream(proc) + tr.end() + tr.end() }, /^Error: Did not expect `write` after `end`$/, 'should throw on end after end' - ); + ) createStream(proc) - .on('data', function (value) { - st.equal(value, '', 'should emit processed `data`'); + .on('data', function(value) { + st.equal(value, '', 'should emit processed `data`') }) - .end(); + .end() createStream(proc) - .on('data', function (value) { - st.equal(value, 'alpha', 'should emit given `data`'); + .on('data', function(value) { + st.equal(value, 'alpha', 'should emit given `data`') }) - .end('alpha'); + .end('alpha') createStream(proc) - .on('data', function (value) { - st.equal(value, 'brC!vo', 'should honour encoding'); + .on('data', function(value) { + st.equal(value, 'brC!vo', 'should honour encoding') }) - .end(Buffer.from([0x62, 0x72, 0xC3, 0xA1, 0x76, 0x6F]), 'ascii'); + .end(Buffer.from([0x62, 0x72, 0xc3, 0xa1, 0x76, 0x6f]), 'ascii') - phase = 0; + phase = 0 createStream(proc) - .on('data', function () { - st.equal(phase, 1, 'should trigger data after callback'); - phase++; + .on('data', function() { + st.equal(phase, 1, 'should trigger data after callback') + phase++ }) - .end('charlie', function () { - st.equal(phase, 0, 'should trigger callback before data'); - phase++; - }); - - exception = new Error('alpha'); - - createStream(proc().use(function () { - return transformer; - function transformer() { - return exception; - } - })) - .on('error', function (err) { - st.equal( - err, - exception, - 'should trigger `error` if an error occurs' - ); + .end('charlie', function() { + st.equal(phase, 0, 'should trigger callback before data') + phase++ + }) + + exception = new Error('alpha') + + createStream( + proc().use(function() { + return transformer + function transformer() { + return exception + } }) - .on('data', /* istanbul ignore next */ function () { - st.fail('should not trigger `data` if an error occurs'); + ) + .on('error', function(err) { + st.equal(err, exception, 'should trigger `error` if an error occurs') }) - .end(); - - createStream(proc().use(function () { - return transformer; - function transformer(tree, file) { - file.message(exception); - } - })) - .on('warning', function (err) { + .on( + 'data', + /* istanbul ignore next */ function() { + st.fail('should not trigger `data` if an error occurs') + } + ) + .end() + + createStream( + proc().use(function() { + return transformer + function transformer(tree, file) { + file.message(exception) + } + }) + ) + .on('warning', function(err) { st.equal( err.reason, 'alpha', 'should trigger `warning` if an messages are emitted' - ); + ) }) - .on('data', function (data) { - st.equal(data, '', 'should not fail if warnings are emitted'); + .on('data', function(data) { + st.equal(data, '', 'should not fail if warnings are emitted') }) - .end(); - }); + .end() + }) - t.test('#pipe', function (st) { - var tr; - var s; + t.test('#pipe', function(st) { + var tr + var s - st.plan(5); + st.plan(5) - st.doesNotThrow( - function () { - /* Not writable. */ - var tr = createStream(proc); - tr.pipe(new stream.Readable()); - tr.end('foo'); - }, - 'should not throw when piping to a non-writable stream' - ); + st.doesNotThrow(function() { + /* Not writable. */ + var tr = createStream(proc) + tr.pipe(new stream.Readable()) + tr.end('foo') + }, 'should not throw when piping to a non-writable stream') - tr = createStream(proc); - s = new stream.PassThrough(); - s._isStdio = true; + tr = createStream(proc) + s = new stream.PassThrough() + s._isStdio = true - tr.pipe(s); + tr.pipe(s) - tr.write('alpha'); - tr.write('bravo'); - tr.end('charlie'); + tr.write('alpha') + tr.write('bravo') + tr.end('charlie') - st.doesNotThrow( - function () { - s.write('delta'); - }, - 'should not `end` stdio streams' - ); + st.doesNotThrow(function() { + s.write('delta') + }, 'should not `end` stdio streams') - tr = createStream(proc).on('error', function (err) { - st.equal( - err.message, - 'Whoops!', - 'should pass errors' - ); - }); + tr = createStream(proc).on('error', function(err) { + st.equal(err.message, 'Whoops!', 'should pass errors') + }) - tr.pipe(new stream.PassThrough()); - tr.emit('error', new Error('Whoops!')); + tr.pipe(new stream.PassThrough()) + tr.emit('error', new Error('Whoops!')) - tr = createStream(proc); - tr.pipe(new stream.PassThrough()); + tr = createStream(proc) + tr.pipe(new stream.PassThrough()) st.throws( - function () { - tr.emit('error', new Error('Whoops!')); + function() { + tr.emit('error', new Error('Whoops!')) }, /Whoops!/, 'should throw if errors are not listened to' - ); + ) - tr = createStream(proc); + tr = createStream(proc) tr .pipe(new stream.PassThrough()) - .on('data', function (buf) { + .on('data', function(buf) { st.equal( String(buf), 'alphabravocharlie', 'should trigger `data` with the processed result' - ); + ) }) - .on('error', /* istanbul ignore next */ function () { - st.fail('should not trigger `error`'); - }); - - tr.write('alpha'); - tr.write('bravo'); - tr.end('charlie'); - }); -}); + .on( + 'error', + /* istanbul ignore next */ function() { + st.fail('should not trigger `error`') + } + ) + + tr.write('alpha') + tr.write('bravo') + tr.end('charlie') + }) +}) function parse() { - this.Parser = parser; + this.Parser = parser function parser(doc) { - return {type: 'root', value: doc}; + return {type: 'root', value: doc} } } function stringify() { - this.Compiler = compiler; + this.Compiler = compiler function compiler(tree) { - return tree.value; + return tree.value } }