From ebb7b48b76a5f07d653270ebc4a5401bc865765a Mon Sep 17 00:00:00 2001 From: Sebastian Van Sande Date: Tue, 7 Feb 2017 17:58:23 +0100 Subject: [PATCH 01/19] increase test coverage of mocha.js --- test/unit/mocha.spec.js | 130 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index af0c44a730..52437de528 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -32,4 +32,134 @@ describe('Mocha', function () { }); }); }); + + describe('.addFile()', function () { + it('should add the given file to the files array', function () { + var mocha = new Mocha(blankOpts); + mocha.addFile('myFile.js'); + mocha.files.length.should.equal(1); + mocha.files[0].should.equal('myFile.js'); + }); + }); + + describe('.invert()', function () { + it('should set the invert option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.invert(); + mocha.options.invert.should.equal(true); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.invert().should.equal(mocha); + }); + }); + + describe('.ignoreLeaks()', function () { + it('should set the ignoreLeaks option to true when param equals true', function () { + var mocha = new Mocha(blankOpts); + mocha.ignoreLeaks(true); + mocha.options.ignoreLeaks.should.equal(true); + }); + + it('should set the ignoreLeaks option to true when param equals false', function () { + var mocha = new Mocha(blankOpts); + mocha.ignoreLeaks(false); + mocha.options.ignoreLeaks.should.equal(false); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.ignoreLeaks(false).should.equal(mocha); + }); + }); + + describe('.checkLeaks()', function () { + it('should set the ignoreLeaks option to false', function () { + var mocha = new Mocha(blankOpts); + mocha.checkLeaks(); + mocha.options.ignoreLeaks.should.equal(false); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.checkLeaks().should.equal(mocha); + }); + }); + + describe('.fullTrace()', function () { + it('should set the fullStackTrace option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.fullTrace(); + mocha.options.fullStackTrace.should.equal(true); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.fullTrace().should.equal(mocha); + }); + }); + + describe('.growl()', function () { + it('should set the growl option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.growl(); + mocha.options.growl.should.equal(true); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.growl().should.equal(mocha); + }); + }); + + describe('.useInlineDiffs()', function () { + it('should set the useInlineDiffs option to true when param equals true', function () { + var mocha = new Mocha(blankOpts); + mocha.useInlineDiffs(true); + mocha.options.useInlineDiffs.should.equal(true); + }); + + it('should set the useInlineDiffs option to true when param equals false', function () { + var mocha = new Mocha(blankOpts); + mocha.useInlineDiffs(false); + mocha.options.useInlineDiffs.should.equal(false); + }); + + it('should set the useInlineDiffs option to false when the param is undefined', function () { + var mocha = new Mocha(blankOpts); + mocha.useInlineDiffs(); + mocha.options.useInlineDiffs.should.equal(false); + }); + + it('should be chainable', function () { + var mocha = new Mocha(blankOpts); + mocha.useInlineDiffs().should.equal(mocha); + }); + }); + + describe('.noHighlighting()', function () { + it('should set the noHighlighting option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.noHighlighting(); + mocha.options.noHighlighting.should.equal(true); + }); + }); + + describe('.allowUncaught()', function () { + it('should set the allowUncaught option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.allowUncaught(); + mocha.options.allowUncaught.should.equal(true); + }); + }); + + describe('.delay()', function () { + it('should set the delay option to true', function () { + var mocha = new Mocha(blankOpts); + mocha.delay(); + mocha.options.delay.should.equal(true); + }); + }); + }); From a763592308faa147f00579a94fb788627bcc0936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20M=C3=BCller?= Date: Tue, 7 Feb 2017 21:28:00 +0100 Subject: [PATCH 02/19] Linting --- test/unit/mocha.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index 52437de528..2de2fc4768 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -161,5 +161,4 @@ describe('Mocha', function () { mocha.options.delay.should.equal(true); }); }); - }); From 1b1377c4048e0b6de93a0b9b7aa9d568c7ef6fba Mon Sep 17 00:00:00 2001 From: Sebastian Van Sande Date: Thu, 15 Jun 2017 15:12:21 +0200 Subject: [PATCH 03/19] Add test for ignoreLeaks and fix descriptions --- test/unit/mocha.spec.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index 2de2fc4768..befb9302d4 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -62,12 +62,18 @@ describe('Mocha', function () { mocha.options.ignoreLeaks.should.equal(true); }); - it('should set the ignoreLeaks option to true when param equals false', function () { + it('should set the ignoreLeaks option to false when param equals false', function () { var mocha = new Mocha(blankOpts); mocha.ignoreLeaks(false); mocha.options.ignoreLeaks.should.equal(false); }); + it('should set the ignoreLeaks option to false when the param is undefined', function () { + var mocha = new Mocha(blankOpts); + mocha.ignoreLeaks(); + mocha.options.ignoreLeaks.should.equal(false); + }); + it('should be chainable', function () { var mocha = new Mocha(blankOpts); mocha.ignoreLeaks(false).should.equal(mocha); @@ -120,7 +126,7 @@ describe('Mocha', function () { mocha.options.useInlineDiffs.should.equal(true); }); - it('should set the useInlineDiffs option to true when param equals false', function () { + it('should set the useInlineDiffs option to false when param equals false', function () { var mocha = new Mocha(blankOpts); mocha.useInlineDiffs(false); mocha.options.useInlineDiffs.should.equal(false); From 27c749655e6874e6d83aed8c90766367c8cba42a Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Fri, 16 Jun 2017 18:13:39 -0700 Subject: [PATCH 04/19] upgrade to debug@2.6.8; closes #2859 (#2860) * upgrade to debug@2.6.8; closes #2859 - ensure we can run the test suite with `DEBUG=mocha*` by removing it when spawning `mocha` - remove some cruft in the test helpers * downgrade should to ^v9.0.2 * increase timeout on file-utils tests * use cross-spawn to spawn mocha in integration tests * integration tests will now fail with less useless information * lint --- package.json | 5 +- test/integration/helpers.js | 48 ++--------------- test/integration/hooks.spec.js | 5 +- test/integration/only.spec.js | 15 ++++-- test/integration/options.spec.js | 80 +++++++++++++++++++++++------ test/integration/pending.spec.js | 35 ++++++++++--- test/integration/regression.spec.js | 37 ++++++++++--- test/integration/reporters.spec.js | 10 +++- test/integration/retries.spec.js | 20 ++++++-- test/integration/suite.spec.js | 15 ++++-- test/integration/timeout.spec.js | 5 +- test/integration/uncaught.spec.js | 10 +++- test/node-unit/file-utils.spec.js | 4 ++ 13 files changed, 195 insertions(+), 94 deletions(-) diff --git a/package.json b/package.json index e772d90290..8102546afe 100644 --- a/package.json +++ b/package.json @@ -309,7 +309,7 @@ "dependencies": { "browser-stdout": "1.3.0", "commander": "2.9.0", - "debug": "2.6.0", + "debug": "2.6.8", "diff": "3.2.0", "escape-string-regexp": "1.0.5", "glob": "7.1.1", @@ -325,6 +325,7 @@ "browserify": "^13.0.0", "coffee-script": "^1.10.0", "coveralls": "^2.11.15", + "cross-spawn": "^5.1.0", "eslint": "^3.11.1", "eslint-config-semistandard": "^7.0.0", "eslint-config-standard": "^6.2.1", @@ -343,7 +344,7 @@ "os-name": "^2.0.1", "phantomjs": "1.9.8", "rimraf": "^2.5.2", - "should": "^11.1.1", + "should": "^9.0.2", "through2": "^2.0.1", "watchify": "^3.7.0" }, diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 025770dd6b..58749b2c80 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -1,8 +1,7 @@ 'use strict'; -var spawn = require('child_process').spawn; +var spawn = require('cross-spawn').spawn; var path = require('path'); -var fs = require('fs'); var baseReporter = require('../../lib/reporters/base'); module.exports = { @@ -41,47 +40,6 @@ module.exports = { }); }, - /** - * Invokes the mocha binary on the code of the body of the function. - * Accepts an array of additional command line args to pass. The callback is - * invoked with a summary of the run, in addition to its output. The summary - * includes the number of passing, pending, and failing tests, as well as the - * exit code. Useful for testing different reporters. - * - * Example response: - * { - * pending: 0, - * passing: 0, - * failing: 1, - * code: 1, - * output: '...' - * } - * - * @param {function} fixture - * @param {array} args - * @param {function} fn - */ - runMochaFunction: function (fixture, args, fn) { - var path = resolveFixturePath(fixture.name + '.js' || 'tempfile.js'); - args = args || []; - - var fixtureContent = 'var fn = ' + fixture.toString() + '; fn()'; - fs.writeFileSync(path, fixtureContent, 'utf8'); - - function cleanup () { - fs.unlink(path); - fn.apply(this, arguments); - } - - invokeMocha(args.concat(['-C', path]), function (err, res) { - if (err) { - return cleanup(err); - } - - cleanup(null, getSummary(res)); - }); - }, - /** * Invokes the mocha binary for the given fixture using the JSON reporter, * returning the parsed output, as well as exit code. @@ -157,10 +115,10 @@ module.exports = { function invokeMocha (args, fn) { var output, mocha, listener; - + // ensure DEBUG doesn't kill tests output = ''; args = [path.join('bin', 'mocha')].concat(args); - mocha = spawn(process.execPath, args); + mocha = spawn(process.execPath, args, {env: {}}); listener = function (data) { output += data; diff --git a/test/integration/hooks.spec.js b/test/integration/hooks.spec.js index ed3c25b2b1..e68aa66b64 100644 --- a/test/integration/hooks.spec.js +++ b/test/integration/hooks.spec.js @@ -10,7 +10,10 @@ describe('hooks', function () { runMocha('cascade.fixture.js', args, function (err, res) { var lines, expected; - assert(!err); + if (err) { + done(err); + return; + } lines = res.output.split(splitRegExp).map(function (line) { return line.trim(); diff --git a/test/integration/only.spec.js b/test/integration/only.spec.js index b37a4b263e..098af6786c 100644 --- a/test/integration/only.spec.js +++ b/test/integration/only.spec.js @@ -7,7 +7,10 @@ describe('.only()', function () { describe('bdd', function () { it('should run only tests that marked as `only`', function (done) { run('options/only/bdd.fixture.js', ['--ui', 'bdd'], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 11); assert.equal(res.stats.failures, 0); @@ -20,7 +23,10 @@ describe('.only()', function () { describe('tdd', function () { it('should run only tests that marked as `only`', function (done) { run('options/only/tdd.fixture.js', ['--ui', 'tdd'], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 8); assert.equal(res.stats.failures, 0); @@ -33,7 +39,10 @@ describe('.only()', function () { describe('qunit', function () { it('should run only tests that marked as `only`', function (done) { run('options/only/qunit.fixture.js', ['--ui', 'qunit'], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 5); assert.equal(res.stats.failures, 0); diff --git a/test/integration/options.spec.js b/test/integration/options.spec.js index 325fbada8f..be4abf53c5 100644 --- a/test/integration/options.spec.js +++ b/test/integration/options.spec.js @@ -12,7 +12,10 @@ describe('options', function () { it('should fail synchronous specs', function (done) { run('options/async-only-sync.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 1); @@ -25,7 +28,10 @@ describe('options', function () { it('should allow asynchronous specs', function (done) { run('options/async-only-async.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); @@ -44,7 +50,10 @@ describe('options', function () { it('should stop after the first error', function (done) { run('options/bail.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 1); @@ -64,7 +73,10 @@ describe('options', function () { it('should sort tests in alphabetical order', function (done) { run('options/sort*', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 2); assert.equal(res.stats.failures, 0); @@ -84,7 +96,10 @@ describe('options', function () { it('should run the generated test suite', function (done) { run('options/delay.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); @@ -98,7 +113,10 @@ describe('options', function () { it('should throw an error if the test suite failed to run', function (done) { run('options/delay-fail.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 1); @@ -115,7 +133,10 @@ describe('options', function () { it('runs specs matching a string', function (done) { args = ['--grep', 'match']; run('options/grep.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 2); assert.equal(res.stats.failures, 0); @@ -128,7 +149,10 @@ describe('options', function () { it('with RegExp like strings(pattern follow by flag)', function (done) { args = ['--grep', '/match/i']; run('options/grep.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 4); assert.equal(res.stats.failures, 0); @@ -140,7 +164,10 @@ describe('options', function () { it('string as pattern', function (done) { args = ['--grep', '.*']; run('options/grep.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 4); assert.equal(res.stats.failures, 1); @@ -154,7 +181,10 @@ describe('options', function () { it('runs specs that do not match the pattern', function (done) { args = ['--grep', 'fail', '--invert']; run('options/grep.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 4); assert.equal(res.stats.failures, 0); @@ -169,7 +199,10 @@ describe('options', function () { it('retries after a certain threshold', function (done) { args = ['--retries', '3']; run('options/retries.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.tests, 1); @@ -188,7 +221,10 @@ describe('options', function () { it('succeeds if there are only passed tests', function (done) { run('options/forbid-only/passed.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 0); done(); }); @@ -196,7 +232,10 @@ describe('options', function () { it('fails if there are tests marked only', function (done) { run('options/forbid-only/only.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 1); done(); }); @@ -210,7 +249,10 @@ describe('options', function () { it('succeeds if there are only passed tests', function (done) { run('options/forbid-pending/passed.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 0); done(); }); @@ -218,7 +260,10 @@ describe('options', function () { it('fails if there are tests marked skip', function (done) { run('options/forbid-pending/skip.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 1); done(); }); @@ -226,7 +271,10 @@ describe('options', function () { it('fails if there are pending tests', function (done) { run('options/forbid-pending/pending.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 1); done(); }); diff --git a/test/integration/pending.spec.js b/test/integration/pending.spec.js index 19ae30ad3a..f5a400f089 100644 --- a/test/integration/pending.spec.js +++ b/test/integration/pending.spec.js @@ -8,7 +8,10 @@ describe('pending', function () { describe('pending specs', function () { it('should be created by omitting a function', function (done) { run('pending/spec.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 1); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 0); @@ -22,7 +25,10 @@ describe('pending', function () { describe('in spec', function () { it('should immediately skip the spec and run all others', function (done) { run('pending/skip-sync-spec.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 1); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); @@ -35,7 +41,10 @@ describe('pending', function () { describe('in before', function () { it('should skip all suite specs', function (done) { run('pending/skip-sync-before.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 2); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 0); @@ -48,7 +57,10 @@ describe('pending', function () { describe('in beforeEach', function () { it('should skip all suite specs', function (done) { run('pending/skip-sync-beforeEach.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 2); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 0); @@ -63,7 +75,10 @@ describe('pending', function () { describe('in spec', function () { it('should immediately skip the spec and run all others', function (done) { run('pending/skip-async-spec.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 1); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); @@ -76,7 +91,10 @@ describe('pending', function () { describe('in before', function () { it('should skip all suite specs', function (done) { run('pending/skip-async-before.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 2); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 0); @@ -89,7 +107,10 @@ describe('pending', function () { describe('in beforeEach', function () { it('should skip all suite specs', function (done) { run('pending/skip-sync-beforeEach.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 2); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 0); diff --git a/test/integration/regression.spec.js b/test/integration/regression.spec.js index 74f32f8081..01fe472fcc 100644 --- a/test/integration/regression.spec.js +++ b/test/integration/regression.spec.js @@ -15,7 +15,10 @@ describe('regressions', function () { return (res.output.match(pattern) || []).length; }; - assert(!err); + if (err) { + done(err); + return; + } assert.equal(occurences('testbody1'), 1); assert.equal(occurences('testbody2'), 1); assert.equal(occurences('testbody3'), 1); @@ -36,7 +39,10 @@ describe('regressions', function () { var simpleUiPath = path.join(__dirname, 'fixtures', 'regression', '1794', 'simple-ui.js'); var args = ['--require', simpleUiPath, '--ui', 'simple-ui']; run('regression/1794/issue-1794.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.code, 0, 'Custom UI should be loaded'); done(); }); @@ -47,7 +53,10 @@ describe('regressions', function () { // Could easily take longer on even weaker machines (Travis-CI containers for example). this.timeout(120000); run('regression/issue-1991.fixture.js', [], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(/process out of memory/.test(res.output), false, 'fixture\'s process out of memory!'); assert.equal(res.code, 0, 'Runnable fn (it/before[Each]/after[Each]) references should be deleted to avoid memory leaks'); done(); @@ -68,7 +77,10 @@ describe('regressions', function () { it('issue-2315: cannot read property currentRetry of undefined', function (done) { runJSON('regression/issue-2315.fixture.js', [], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 1); @@ -80,7 +92,10 @@ describe('regressions', function () { it('issue-2406: should run nested describe.only suites', function (done) { this.timeout(2000); runJSON('regression/issue-2406.fixture.js', [], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 2); assert.equal(res.stats.failures, 0); @@ -89,9 +104,12 @@ describe('regressions', function () { }); }); - it('issue-2417: should not recurse infinitely with .only suites nested within each other', function () { + it('issue-2417: should not recurse infinitely with .only suites nested within each other', function (done) { runJSON('regression/issue-2417.fixture.js', [], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); @@ -101,7 +119,10 @@ describe('regressions', function () { it('issue-1417 uncaught exceptions from async specs', function (done) { runJSON('regression/issue-1417.fixture.js', [], function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 2); diff --git a/test/integration/reporters.spec.js b/test/integration/reporters.spec.js index 19b4d8e30c..9bf8df289c 100644 --- a/test/integration/reporters.spec.js +++ b/test/integration/reporters.spec.js @@ -68,7 +68,10 @@ describe('reporters', function () { var args = ['--reporter=' + reporterAtARelativePath]; run('passing.fixture.js', args, function (err, result) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(result.code, 0); done(); }); @@ -81,7 +84,10 @@ describe('reporters', function () { var args = ['--reporter=' + reporterAtAnAbsolutePath]; run('passing.fixture.js', args, function (err, result) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(result.code, 0); done(); }); diff --git a/test/integration/retries.spec.js b/test/integration/retries.spec.js index 9d9301ad78..6197c43ca8 100644 --- a/test/integration/retries.spec.js +++ b/test/integration/retries.spec.js @@ -10,7 +10,10 @@ describe('retries', function () { helpers.runMocha('retries/hooks.fixture.js', args, function (err, res) { var lines, expected; - assert(!err); + if (err) { + done(err); + return; + } lines = res.output.split(helpers.splitRegExp).map(function (line) { return line.trim(); @@ -49,7 +52,10 @@ describe('retries', function () { it('should exit early if test passes', function (done) { helpers.runMochaJSON('retries/early-pass.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); assert.equal(res.tests[0].currentRetry, 1); @@ -61,7 +67,10 @@ describe('retries', function () { it('should let test override', function (done) { helpers.runMochaJSON('retries/nested.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 1); assert.equal(res.stats.tests, 1); @@ -75,7 +84,10 @@ describe('retries', function () { helpers.runMocha('retries/async.fixture.js', args, function (err, res) { var lines, expected; - assert(!err); + if (err) { + done(err); + return; + } lines = res.output.split(helpers.splitRegExp).map(function (line) { return line.trim(); diff --git a/test/integration/suite.spec.js b/test/integration/suite.spec.js index f497e72652..4af47697f7 100644 --- a/test/integration/suite.spec.js +++ b/test/integration/suite.spec.js @@ -8,7 +8,10 @@ describe('suite w/no callback', function () { this.timeout(2000); it('should throw a helpful error message when a callback for suite is not supplied', function (done) { run('suite/suite-no-callback.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } var result = res.output.match(/no callback was supplied/) || []; assert.equal(result.length, 1); done(); @@ -20,7 +23,10 @@ describe('skipped suite w/no callback', function () { this.timeout(2000); it('should not throw an error when a callback for skipped suite is not supplied', function (done) { run('suite/suite-skipped-no-callback.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } var pattern = new RegExp('Error', 'g'); var result = res.output.match(pattern) || []; assert.equal(result.length, 0); @@ -33,7 +39,10 @@ describe('skipped suite w/ callback', function () { this.timeout(2000); it('should not throw an error when a callback for skipped suite is supplied', function (done) { run('suite/suite-skipped-callback.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } var pattern = new RegExp('Error', 'g'); var result = res.output.match(pattern) || []; assert.equal(result.length, 0); diff --git a/test/integration/timeout.spec.js b/test/integration/timeout.spec.js index 4e0f989e86..c51ba774de 100644 --- a/test/integration/timeout.spec.js +++ b/test/integration/timeout.spec.js @@ -7,7 +7,10 @@ var args = []; describe('this.timeout()', function () { it('is respected by sync and async suites', function (done) { run('timeout.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 2); diff --git a/test/integration/uncaught.spec.js b/test/integration/uncaught.spec.js index 92e39c195e..9a3dadbbbd 100644 --- a/test/integration/uncaught.spec.js +++ b/test/integration/uncaught.spec.js @@ -7,7 +7,10 @@ var args = []; describe('uncaught exceptions', function () { it('handles uncaught exceptions from hooks', function (done) { run('uncaught-hook.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 1); @@ -21,7 +24,10 @@ describe('uncaught exceptions', function () { it('handles uncaught exceptions from async specs', function (done) { run('uncaught.fixture.js', args, function (err, res) { - assert(!err); + if (err) { + done(err); + return; + } assert.equal(res.stats.pending, 0); assert.equal(res.stats.passes, 0); assert.equal(res.stats.failures, 2); diff --git a/test/node-unit/file-utils.spec.js b/test/node-unit/file-utils.spec.js index 540589821d..3ff1bd4d7e 100644 --- a/test/node-unit/file-utils.spec.js +++ b/test/node-unit/file-utils.spec.js @@ -13,6 +13,10 @@ describe('file utils', function () { var tmpFile = path.join.bind(path, tmpDir); var symlinkSupported = false; + beforeEach(function () { + this.timeout(2000); + }); + (function testSymlinkSupport () { makeTempDir(); From 1f270cd4503ab3f83af4d98fb3b38d55572e468f Mon Sep 17 00:00:00 2001 From: Scott Santucci Date: Fri, 16 Jun 2017 22:25:08 -0400 Subject: [PATCH 05/19] Stop timing out (#2889) Corrects a bug in #2860 --- test/integration/regression.spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/regression.spec.js b/test/integration/regression.spec.js index 01fe472fcc..14a1a164f3 100644 --- a/test/integration/regression.spec.js +++ b/test/integration/regression.spec.js @@ -114,6 +114,7 @@ describe('regressions', function () { assert.equal(res.stats.passes, 1); assert.equal(res.stats.failures, 0); assert.equal(res.code, 0); + done(); }); }); From 958fbb4509eb4e28eee6623b297e60fa48ebeffe Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Wed, 5 Jul 2017 22:04:00 -0400 Subject: [PATCH 06/19] Update new tests to work in browser per test hierarchy reorganization --- test/unit/mocha.spec.js | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index bef492e47f..37b75ffd85 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -37,8 +37,8 @@ describe('Mocha', function () { it('should add the given file to the files array', function () { var mocha = new Mocha(blankOpts); mocha.addFile('myFile.js'); - mocha.files.length.should.equal(1); - mocha.files[0].should.equal('myFile.js'); + expect(mocha.files.length).to.equal(1); + expect(mocha.files[0]).to.equal('myFile.js'); }); }); @@ -46,12 +46,12 @@ describe('Mocha', function () { it('should set the invert option to true', function () { var mocha = new Mocha(blankOpts); mocha.invert(); - mocha.options.invert.should.equal(true); + expect(mocha.options.invert).to.equal(true); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.invert().should.equal(mocha); + expect(mocha.invert()).to.equal(mocha); }); }); @@ -59,24 +59,24 @@ describe('Mocha', function () { it('should set the ignoreLeaks option to true when param equals true', function () { var mocha = new Mocha(blankOpts); mocha.ignoreLeaks(true); - mocha.options.ignoreLeaks.should.equal(true); + expect(mocha.options.ignoreLeaks).to.equal(true); }); it('should set the ignoreLeaks option to false when param equals false', function () { var mocha = new Mocha(blankOpts); mocha.ignoreLeaks(false); - mocha.options.ignoreLeaks.should.equal(false); + expect(mocha.options.ignoreLeaks).to.equal(false); }); it('should set the ignoreLeaks option to false when the param is undefined', function () { var mocha = new Mocha(blankOpts); mocha.ignoreLeaks(); - mocha.options.ignoreLeaks.should.equal(false); + expect(mocha.options.ignoreLeaks).to.equal(false); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.ignoreLeaks(false).should.equal(mocha); + expect(mocha.ignoreLeaks(false)).to.equal(mocha); }); }); @@ -84,12 +84,12 @@ describe('Mocha', function () { it('should set the ignoreLeaks option to false', function () { var mocha = new Mocha(blankOpts); mocha.checkLeaks(); - mocha.options.ignoreLeaks.should.equal(false); + expect(mocha.options.ignoreLeaks).to.equal(false); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.checkLeaks().should.equal(mocha); + expect(mocha.checkLeaks()).to.equal(mocha); }); }); @@ -97,12 +97,12 @@ describe('Mocha', function () { it('should set the fullStackTrace option to true', function () { var mocha = new Mocha(blankOpts); mocha.fullTrace(); - mocha.options.fullStackTrace.should.equal(true); + expect(mocha.options.fullStackTrace).to.equal(true); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.fullTrace().should.equal(mocha); + expect(mocha.fullTrace()).to.equal(mocha); }); }); @@ -110,12 +110,12 @@ describe('Mocha', function () { it('should set the growl option to true', function () { var mocha = new Mocha(blankOpts); mocha.growl(); - mocha.options.growl.should.equal(true); + expect(mocha.options.growl).to.equal(true); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.growl().should.equal(mocha); + expect(mocha.growl()).to.equal(mocha); }); }); @@ -123,24 +123,24 @@ describe('Mocha', function () { it('should set the useInlineDiffs option to true when param equals true', function () { var mocha = new Mocha(blankOpts); mocha.useInlineDiffs(true); - mocha.options.useInlineDiffs.should.equal(true); + expect(mocha.options.useInlineDiffs).to.equal(true); }); it('should set the useInlineDiffs option to false when param equals false', function () { var mocha = new Mocha(blankOpts); mocha.useInlineDiffs(false); - mocha.options.useInlineDiffs.should.equal(false); + expect(mocha.options.useInlineDiffs).to.equal(false); }); it('should set the useInlineDiffs option to false when the param is undefined', function () { var mocha = new Mocha(blankOpts); mocha.useInlineDiffs(); - mocha.options.useInlineDiffs.should.equal(false); + expect(mocha.options.useInlineDiffs).to.equal(false); }); it('should be chainable', function () { var mocha = new Mocha(blankOpts); - mocha.useInlineDiffs().should.equal(mocha); + expect(mocha.useInlineDiffs()).to.equal(mocha); }); }); @@ -148,7 +148,7 @@ describe('Mocha', function () { it('should set the noHighlighting option to true', function () { var mocha = new Mocha(blankOpts); mocha.noHighlighting(); - mocha.options.noHighlighting.should.equal(true); + expect(mocha.options.noHighlighting).to.equal(true); }); }); @@ -156,7 +156,7 @@ describe('Mocha', function () { it('should set the allowUncaught option to true', function () { var mocha = new Mocha(blankOpts); mocha.allowUncaught(); - mocha.options.allowUncaught.should.equal(true); + expect(mocha.options.allowUncaught).to.equal(true); }); }); @@ -164,7 +164,7 @@ describe('Mocha', function () { it('should set the delay option to true', function () { var mocha = new Mocha(blankOpts); mocha.delay(); - mocha.options.delay.should.equal(true); + expect(mocha.options.delay).to.equal(true); }); }); }); From 68a1466a5ec56f7477a2f14cd327bdcabc3727e3 Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Tue, 20 Jun 2017 23:26:29 -0400 Subject: [PATCH 07/19] Try not clearing the env for debug in the integration test and see if that fixes Node 0.10 on AppVeyor; if need be, some other fix/workaround can be applied to handle whatever was up with debug without causing this issue --- test/integration/helpers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 58749b2c80..f2d9c81192 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -115,10 +115,10 @@ module.exports = { function invokeMocha (args, fn) { var output, mocha, listener; - // ensure DEBUG doesn't kill tests + output = ''; args = [path.join('bin', 'mocha')].concat(args); - mocha = spawn(process.execPath, args, {env: {}}); + mocha = spawn(process.execPath, args); listener = function (data) { output += data; From 2408d9067483451fdd40eed98399db958f7bf672 Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Wed, 21 Jun 2017 01:45:22 -0400 Subject: [PATCH 08/19] Make dependencies use older version of readable-stream to work around incompatibilities introduced by 2.3.0 on June 19th --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 8102546afe..e225bfa448 100644 --- a/package.json +++ b/package.json @@ -343,6 +343,7 @@ "nyc": "^10.0.0", "os-name": "^2.0.1", "phantomjs": "1.9.8", + "readable-stream": "2.2.11", "rimraf": "^2.5.2", "should": "^9.0.2", "through2": "^2.0.1", From 6886ccca61a589ff43d322fdaee621122807cdba Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Sun, 30 Jul 2017 12:51:53 -0700 Subject: [PATCH 09/19] increase timeout for slow-grepping test --- test/node-unit/color.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/node-unit/color.spec.js b/test/node-unit/color.spec.js index bffd30e6eb..ab27d2019e 100644 --- a/test/node-unit/color.spec.js +++ b/test/node-unit/color.spec.js @@ -5,7 +5,7 @@ var childProcess = require('child_process'); var path = require('path'); describe('Mocha', function () { - this.timeout(2000); + this.timeout(4000); it('should not output colors to pipe', function (cb) { var command = [path.join('bin', 'mocha'), '--grep', 'missing-test']; From 4e870467aa41221e66bfc9cde4631da6b8f43aab Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Wed, 26 Jul 2017 13:35:29 -0700 Subject: [PATCH 10/19] update karma-sauce-launcher URL for npm@5 - maintain compat with npm@2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e225bfa448..69543c66dc 100644 --- a/package.json +++ b/package.json @@ -320,7 +320,7 @@ "supports-color": "3.1.2" }, "devDependencies": { - "@coderbyheart/karma-sauce-launcher": "coderbyheart/karma-sauce-launcher#5259942cd6d40090eaa13ceeef5b0b8738c7710f", + "@coderbyheart/karma-sauce-launcher": "git://github.com/coderbyheart/karma-sauce-launcher#5259942cd6d40090eaa13ceeef5b0b8738c7710f", "assert": "^1.4.1", "browserify": "^13.0.0", "coffee-script": "^1.10.0", From 065e14ef41a3c54de2c66c0fd930c1d6667b5402 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Sun, 30 Jul 2017 12:53:07 -0700 Subject: [PATCH 11/19] remove custom install script from travis (no longer needed) --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a76015bdd..d5c75c269a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -68,10 +68,6 @@ matrix: before_install: scripts/travis-before-install.sh -install: - - npm install - - cd node_modules && ln -nsf @coderbyheart/karma-sauce-launcher karma-sauce-launcher && cd ../ - before_script: scripts/travis-before-script.sh script: make $TARGET From 1ba2cfc10a59b554be5b2f8cb7b70717940a50c9 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Fri, 16 Jun 2017 14:46:36 -0700 Subject: [PATCH 12/19] update CHANGELOG.md for v3.5.0 [ci skip] --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 295971edde..a3959cfcd8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,40 @@ +# 3.5.0 / 2017-06-16 + +## :newspaper: News + +- Mocha now has a [code of conduct](https://github.com/mochajs/mocha/blob/master/.github/CODE_OF_CONDUCT.md) (thanks [@kungapal]!). +- Old issues and PRs are now being marked "stale" by [Probot's "Stale" plugin](https://github.com/probot/stale). If an issue is marked as such, and you would like to see it remain open, simply add a new comment to the ticket or PR. +- **WARNING**: Support for non-ES5-compliant environments will be dropped starting with version 4.0.0 of Mocha! + +## :lock: Security Fixes + +- [#2860]: Address [CVE-2015-8315](https://nodesecurity.io/advisories/46) via upgrade of [debug](https://npm.im/debug) ([@boneskull]) + +## :tada: Enhancements + +- [#2696]: Add `--forbid-only` and `--forbid-pending` flags. Use these in CI or hooks to ensure tests aren't accidentally being skipped! ([@charlierudolph]) +- [#2813]: Support Node.js 8's `--napi-modules` flag ([@jupp0r]) + +## :nut_and_bolt: Other + +- Various CI-and-test-related fixes and improvements ([@boneskull], [@dasilvacontin], [@PopradiArpad], [@Munter], [@ScottFreeCode]) +- "Officially" support Node.js 8 ([@elergy]) + +[#2860]: https://github.com/mochajs/mocha/pulls/2860 +[#2696]: https://github.com/mochajs/mocha/pulls/2696 +[#2813]: https://github.com/mochajs/mocha/pulls/2813 +[@charlierudolph]: https://github.com/charlierudolph +[@PopradiArpad]: https://github.com/PopradiArpad +[@kungapal]: https://github.com/kungapal +[@elergy]: https://github.com/elergy +[@jupp0r]: https://github.com/jupp0r + # 3.4.2 / 2017-05-24 ## :bug: Fixes -- [#2802]: Remove call to deprecated os.tmpDir ([@makepanic]) -- [#2820]: Eagerly set process.exitCode ([@chrisleck]) +- [#2802]: Remove call to deprecated `os.tmpDir` ([@makepanic]) +- [#2820]: Eagerly set `process.exitCode` ([@chrisleck]) ## :nut_and_bolt: Other From ec73c9a7d3f2bb2fa55ccb7a52b729ef03cc35a9 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Mon, 31 Jul 2017 12:11:17 -0700 Subject: [PATCH 13/19] update date for release of v3.5.0 in CHANGELOG [ci skip] --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3959cfcd8..66e5aac8a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# 3.5.0 / 2017-06-16 +# 3.5.0 / 2017-07-31 ## :newspaper: News From bf687ceaa854591cc8c1b0f8ba029db1312740f5 Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Mon, 31 Jul 2017 12:14:56 -0700 Subject: [PATCH 14/19] update mocha.js for v3.5.0 --- mocha.js | 1633 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 838 insertions(+), 795 deletions(-) diff --git a/mocha.js b/mocha.js index 4e59d156cf..2ad1356722 100644 --- a/mocha.js +++ b/mocha.js @@ -189,7 +189,7 @@ global.mocha = mocha; module.exports = global; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./lib/mocha":14,"_process":82,"browser-stdout":41}],2:[function(require,module,exports){ +},{"./lib/mocha":14,"_process":81,"browser-stdout":41}],2:[function(require,module,exports){ 'use strict'; function noop () {} @@ -647,7 +647,7 @@ Context.prototype.inspect = function () { }, 2); }; -},{"json3":69}],7:[function(require,module,exports){ +},{"json3":68}],7:[function(require,module,exports){ 'use strict'; /** @@ -1743,6 +1743,24 @@ Mocha.prototype.delay = function delay () { return this; }; +/** + * Tests marked only fail the suite + * @returns {Mocha} + */ +Mocha.prototype.forbidOnly = function () { + this.options.forbidOnly = true; + return this; +}; + +/** + * Pending tests and tests marked skip fail the suite + * @returns {Mocha} + */ +Mocha.prototype.forbidPending = function () { + this.options.forbidPending = true; + return this; +}; + /** * Run tests and invoke `fn()` when complete. * @@ -1764,6 +1782,8 @@ Mocha.prototype.run = function (fn) { runner.hasOnly = options.hasOnly; runner.asyncOnly = options.asyncOnly; runner.allowUncaught = options.allowUncaught; + runner.forbidOnly = options.forbidOnly; + runner.forbidPending = options.forbidPending; if (options.grep) { runner.grep(options.grep, options.invert); } @@ -1790,7 +1810,7 @@ Mocha.prototype.run = function (fn) { }; }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},"/lib") -},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":21,"./runnable":33,"./runner":34,"./suite":35,"./test":36,"./utils":38,"_process":82,"escape-string-regexp":62,"growl":64,"path":42}],15:[function(require,module,exports){ +},{"./context":6,"./hook":7,"./interfaces":11,"./reporters":21,"./runnable":33,"./runner":34,"./suite":35,"./test":36,"./utils":38,"_process":81,"escape-string-regexp":61,"growl":63,"path":42}],15:[function(require,module,exports){ 'use strict'; /** @@ -2435,7 +2455,7 @@ function sameType (a, b) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../ms":15,"../utils":38,"_process":82,"diff":56,"supports-color":42,"tty":5}],18:[function(require,module,exports){ +},{"../ms":15,"../utils":38,"_process":81,"diff":55,"supports-color":42,"tty":5}],18:[function(require,module,exports){ 'use strict'; /** @@ -2573,7 +2593,7 @@ function Dot (runner) { inherits(Dot, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],20:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],20:[function(require,module,exports){ (function (global){ 'use strict'; @@ -2925,7 +2945,7 @@ function on (el, event, fn) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../browser/progress":4,"../utils":38,"./base":17,"escape-string-regexp":62}],21:[function(require,module,exports){ +},{"../browser/progress":4,"../utils":38,"./base":17,"escape-string-regexp":61}],21:[function(require,module,exports){ 'use strict'; // Alias exports to a their normalized format Mocha#reporter to prevent a need @@ -3013,7 +3033,7 @@ function clean (test) { } }).call(this,require('_process')) -},{"./base":17,"_process":82,"json3":69}],23:[function(require,module,exports){ +},{"./base":17,"_process":81,"json3":68}],23:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3109,7 +3129,7 @@ function errorJSON (err) { } }).call(this,require('_process')) -},{"./base":17,"_process":82}],24:[function(require,module,exports){ +},{"./base":17,"_process":81}],24:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3207,7 +3227,7 @@ function Landing (runner) { inherits(Landing, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],25:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],25:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3274,7 +3294,7 @@ function List (runner) { inherits(List, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],26:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],26:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3377,7 +3397,7 @@ function Markdown (runner) { } }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],27:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],27:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3419,7 +3439,7 @@ function Min (runner) { inherits(Min, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],28:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],28:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3686,7 +3706,7 @@ function write (string) { } }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],29:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],29:[function(require,module,exports){ (function (process){ 'use strict'; @@ -3781,7 +3801,7 @@ function Progress (runner, options) { inherits(Progress, Base); }).call(this,require('_process')) -},{"../utils":38,"./base":17,"_process":82}],30:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81}],30:[function(require,module,exports){ 'use strict'; /** @@ -4108,7 +4128,7 @@ function tag (name, attrs, close, content) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"../utils":38,"./base":17,"_process":82,"fs":42,"mkdirp":79,"path":42}],33:[function(require,module,exports){ +},{"../utils":38,"./base":17,"_process":81,"fs":42,"mkdirp":78,"path":42}],33:[function(require,module,exports){ (function (global){ 'use strict'; @@ -4501,7 +4521,7 @@ Runnable.prototype.run = function (fn) { }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./ms":15,"./pending":16,"./utils":38,"debug":2,"events":3,"json3":69,"lodash.create":75}],34:[function(require,module,exports){ +},{"./ms":15,"./pending":16,"./utils":38,"debug":2,"events":3,"json3":68,"lodash.create":69}],34:[function(require,module,exports){ (function (process,global){ 'use strict'; @@ -5325,6 +5345,12 @@ Runner.prototype.run = function (fn) { // callback this.on('end', function () { + if (self.forbidOnly && self.hasOnly) { + self.failures += self.stats.tests; + } + if (self.forbidPending) { + self.failures += self.stats.pending; + } debug('end'); process.removeListener('uncaughtException', uncaught); fn(self.failures); @@ -5467,7 +5493,7 @@ function extraGlobals () { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./pending":16,"./runnable":33,"./utils":38,"_process":82,"debug":2,"events":3}],35:[function(require,module,exports){ +},{"./pending":16,"./runnable":33,"./utils":38,"_process":81,"debug":2,"events":3}],35:[function(require,module,exports){ 'use strict'; /** @@ -5925,7 +5951,7 @@ Test.prototype.clone = function () { return test; }; -},{"./runnable":33,"./utils":38,"lodash.create":75}],37:[function(require,module,exports){ +},{"./runnable":33,"./utils":38,"lodash.create":69}],37:[function(require,module,exports){ 'use strict'; /** @@ -6775,7 +6801,7 @@ exports.isPromise = function isPromise (value) { exports.noop = function () {}; }).call(this,require('_process'),require("buffer").Buffer) -},{"./to-iso-string":37,"_process":82,"buffer":44,"debug":2,"fs":42,"glob":42,"json3":69,"path":42,"util":99}],39:[function(require,module,exports){ +},{"./to-iso-string":37,"_process":81,"buffer":43,"debug":2,"fs":42,"glob":42,"json3":68,"path":42,"util":101}],39:[function(require,module,exports){ 'use strict' exports.byteLength = byteLength @@ -6811,22 +6837,22 @@ function placeHoldersCount (b64) { function byteLength (b64) { // base64 is 4/3 + up to two characters of the original data - return b64.length * 3 / 4 - placeHoldersCount(b64) + return (b64.length * 3 / 4) - placeHoldersCount(b64) } function toByteArray (b64) { - var i, j, l, tmp, placeHolders, arr + var i, l, tmp, placeHolders, arr var len = b64.length placeHolders = placeHoldersCount(b64) - arr = new Arr(len * 3 / 4 - placeHolders) + arr = new Arr((len * 3 / 4) - placeHolders) // if there are placeholders, only get up to the last complete 4 chars l = placeHolders > 0 ? len - 4 : len var L = 0 - for (i = 0, j = 0; i < l; i += 4, j += 3) { + for (i = 0; i < l; i += 4) { tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)] arr[L++] = (tmp >> 16) & 0xFF arr[L++] = (tmp >> 8) & 0xFF @@ -6922,122 +6948,10 @@ BrowserStdout.prototype._write = function(chunks, encoding, cb) { } }).call(this,require('_process')) -},{"_process":82,"stream":94,"util":99}],42:[function(require,module,exports){ +},{"_process":81,"stream":95,"util":101}],42:[function(require,module,exports){ arguments[4][40][0].apply(exports,arguments) },{"dup":40}],43:[function(require,module,exports){ (function (global){ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"buffer":44}],44:[function(require,module,exports){ -(function (global){ /*! * The buffer module from node.js, for the browser. * @@ -8829,7 +8743,7 @@ function isnan (val) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"base64-js":39,"ieee754":65,"isarray":68}],45:[function(require,module,exports){ +},{"base64-js":39,"ieee754":64,"isarray":67}],44:[function(require,module,exports){ (function (Buffer){ // Copyright Joyent, Inc. and other Node contributors. // @@ -8940,7 +8854,7 @@ function objectToString(o) { } }).call(this,{"isBuffer":require("../../is-buffer/index.js")}) -},{"../../is-buffer/index.js":67}],46:[function(require,module,exports){ +},{"../../is-buffer/index.js":66}],45:[function(require,module,exports){ /*istanbul ignore start*/"use strict"; exports.__esModule = true; @@ -8966,7 +8880,7 @@ function convertChangesToDMP(changes) { } -},{}],47:[function(require,module,exports){ +},{}],46:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9003,7 +8917,7 @@ function escapeHTML(s) { } -},{}],48:[function(require,module,exports){ +},{}],47:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9027,7 +8941,7 @@ function diffArrays(oldArr, newArr, callback) { } -},{"./base":49}],49:[function(require,module,exports){ +},{"./base":48}],48:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9259,7 +9173,7 @@ function clonePath(path) { } -},{}],50:[function(require,module,exports){ +},{}],49:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9279,7 +9193,7 @@ function diffChars(oldStr, newStr, callback) { } -},{"./base":49}],51:[function(require,module,exports){ +},{"./base":48}],50:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9303,7 +9217,7 @@ function diffCss(oldStr, newStr, callback) { } -},{"./base":49}],52:[function(require,module,exports){ +},{"./base":48}],51:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9414,7 +9328,7 @@ function canonicalize(obj, stack, replacementStack) { } -},{"./base":49,"./line":53}],53:[function(require,module,exports){ +},{"./base":48,"./line":52}],52:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9469,7 +9383,7 @@ function diffTrimmedLines(oldStr, newStr, callback) { } -},{"../util/params":61,"./base":49}],54:[function(require,module,exports){ +},{"../util/params":60,"./base":48}],53:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9493,7 +9407,7 @@ function diffSentences(oldStr, newStr, callback) { } -},{"./base":49}],55:[function(require,module,exports){ +},{"./base":48}],54:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9565,7 +9479,7 @@ function diffWordsWithSpace(oldStr, newStr, callback) { } -},{"../util/params":61,"./base":49}],56:[function(require,module,exports){ +},{"../util/params":60,"./base":48}],55:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9640,7 +9554,7 @@ exports. /*istanbul ignore end*/Diff = _base2['default']; */ -},{"./convert/dmp":46,"./convert/xml":47,"./diff/array":48,"./diff/base":49,"./diff/character":50,"./diff/css":51,"./diff/json":52,"./diff/line":53,"./diff/sentence":54,"./diff/word":55,"./patch/apply":57,"./patch/create":58,"./patch/parse":59}],57:[function(require,module,exports){ +},{"./convert/dmp":45,"./convert/xml":46,"./diff/array":47,"./diff/base":48,"./diff/character":49,"./diff/css":50,"./diff/json":51,"./diff/line":52,"./diff/sentence":53,"./diff/word":54,"./patch/apply":56,"./patch/create":57,"./patch/parse":58}],56:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9819,7 +9733,7 @@ function applyPatches(uniDiff, options) { } -},{"../util/distance-iterator":60,"./parse":59}],58:[function(require,module,exports){ +},{"../util/distance-iterator":59,"./parse":58}],57:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -9977,7 +9891,7 @@ function createPatch(fileName, oldStr, newStr, oldHeader, newHeader, options) { } -},{"../diff/line":53}],59:[function(require,module,exports){ +},{"../diff/line":52}],58:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -10122,7 +10036,7 @@ function parsePatch(uniDiff) { } -},{}],60:[function(require,module,exports){ +},{}],59:[function(require,module,exports){ /*istanbul ignore start*/"use strict"; exports.__esModule = true; @@ -10171,7 +10085,7 @@ exports["default"] = /*istanbul ignore end*/function (start, minLine, maxLine) { }; -},{}],61:[function(require,module,exports){ +},{}],60:[function(require,module,exports){ /*istanbul ignore start*/'use strict'; exports.__esModule = true; @@ -10191,7 +10105,7 @@ function generateOptions(options, defaults) { } -},{}],62:[function(require,module,exports){ +},{}],61:[function(require,module,exports){ 'use strict'; var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; @@ -10204,7 +10118,7 @@ module.exports = function (str) { return str.replace(matchOperatorsRe, '\\$&'); }; -},{}],63:[function(require,module,exports){ +},{}],62:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -10508,7 +10422,7 @@ function isUndefined(arg) { return arg === void 0; } -},{}],64:[function(require,module,exports){ +},{}],63:[function(require,module,exports){ (function (process){ // Growl - Copyright TJ Holowaychuk (MIT Licensed) @@ -10802,7 +10716,7 @@ function growl(msg, options, fn) { }; }).call(this,require('_process')) -},{"_process":82,"child_process":42,"fs":42,"os":80,"path":42}],65:[function(require,module,exports){ +},{"_process":81,"child_process":42,"fs":42,"os":79,"path":42}],64:[function(require,module,exports){ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = nBytes * 8 - mLen - 1 @@ -10888,7 +10802,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { buffer[offset + i - d] |= s * 128 } -},{}],66:[function(require,module,exports){ +},{}],65:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { @@ -10913,7 +10827,7 @@ if (typeof Object.create === 'function') { } } -},{}],67:[function(require,module,exports){ +},{}],66:[function(require,module,exports){ /*! * Determine if an object is a Buffer * @@ -10936,14 +10850,14 @@ function isSlowBuffer (obj) { return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) } -},{}],68:[function(require,module,exports){ +},{}],67:[function(require,module,exports){ var toString = {}.toString; module.exports = Array.isArray || function (arr) { return toString.call(arr) == '[object Array]'; }; -},{}],69:[function(require,module,exports){ +},{}],68:[function(require,module,exports){ (function (global){ /*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */ ;(function () { @@ -11849,7 +11763,64 @@ module.exports = Array.isArray || function (arr) { }).call(this); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],70:[function(require,module,exports){ +},{}],69:[function(require,module,exports){ +/** + * lodash 3.1.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseAssign = require('lodash._baseassign'), + baseCreate = require('lodash._basecreate'), + isIterateeCall = require('lodash._isiterateecall'); + +/** + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. + * @example + * + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle + * }); + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true + */ +function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = undefined; + } + return properties ? baseAssign(result, properties) : result; +} + +module.exports = create; + +},{"lodash._baseassign":70,"lodash._basecreate":76,"lodash._isiterateecall":77}],70:[function(require,module,exports){ /** * lodash 3.2.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -11878,7 +11849,7 @@ function baseAssign(object, source) { module.exports = baseAssign; -},{"lodash._basecopy":71,"lodash.keys":78}],71:[function(require,module,exports){ +},{"lodash._basecopy":71,"lodash.keys":72}],71:[function(require,module,exports){ /** * lodash 3.0.1 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -11914,33 +11885,125 @@ module.exports = baseCopy; },{}],72:[function(require,module,exports){ /** - * lodash 3.0.3 (Custom Build) + * lodash 3.1.2 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ +var getNative = require('lodash._getnative'), + isArguments = require('lodash.isarguments'), + isArray = require('lodash.isarray'); + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = getNative(Object, 'keys'); + +/** + * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * of an array-like value. + */ +var MAX_SAFE_INTEGER = 9007199254740991; /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. + * The base implementation of `_.property` without support for deep paths. * * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new function. */ -var baseCreate = (function() { - function object() {} - return function(prototype) { - if (isObject(prototype)) { - object.prototype = prototype; - var result = new object; - object.prototype = undefined; - } - return result || {}; +function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; }; -}()); +} + +/** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ +var getLength = baseProperty('length'); + +/** + * Checks if `value` is array-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + */ +function isArrayLike(value) { + return value != null && isLength(getLength(value)); +} + +/** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ +function isIndex(value, length) { + value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; +} + +/** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = !!length && isLength(length) && + (isArray(object) || isArguments(object)); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} /** * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. @@ -11969,11 +12032,98 @@ function isObject(value) { return !!value && (type == 'object' || type == 'function'); } -module.exports = baseCreate; - -},{}],73:[function(require,module,exports){ /** - * lodash 3.9.1 (Custom Build) + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object == null ? undefined : object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; + +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || isArguments(object)) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; +} + +module.exports = keys; + +},{"lodash._getnative":73,"lodash.isarguments":74,"lodash.isarray":75}],73:[function(require,module,exports){ +/** + * lodash 3.9.1 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 @@ -12111,197 +12261,6 @@ function isNative(value) { module.exports = getNative; },{}],74:[function(require,module,exports){ -/** - * lodash 3.0.9 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - -/** Used to detect unsigned integer values. */ -var reIsUint = /^\d+$/; - -/** - * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * of an array-like value. - */ -var MAX_SAFE_INTEGER = 9007199254740991; - -/** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. - */ -function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; -} - -/** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * that affects Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ -var getLength = baseProperty('length'); - -/** - * Checks if `value` is array-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - */ -function isArrayLike(value) { - return value != null && isLength(getLength(value)); -} - -/** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ -function isIndex(value, length) { - value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; -} - -/** - * Checks if the provided arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. - */ -function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object)) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); - } - return false; -} - -/** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; -} - -/** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(1); - * // => false - */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); -} - -module.exports = isIterateeCall; - -},{}],75:[function(require,module,exports){ -/** - * lodash 3.1.1 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ -var baseAssign = require('lodash._baseassign'), - baseCreate = require('lodash._basecreate'), - isIterateeCall = require('lodash._isiterateecall'); - -/** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ -function create(prototype, properties, guard) { - var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = undefined; - } - return properties ? baseAssign(result, properties) : result; -} - -module.exports = create; - -},{"lodash._baseassign":70,"lodash._basecreate":72,"lodash._isiterateecall":74}],76:[function(require,module,exports){ /** * lodash (Custom Build) * Build: `lodash modularize exports="npm" -o ./` @@ -12532,7 +12491,7 @@ function isObjectLike(value) { module.exports = isArguments; -},{}],77:[function(require,module,exports){ +},{}],75:[function(require,module,exports){ /** * lodash 3.0.4 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -12714,33 +12673,80 @@ function isNative(value) { module.exports = isArray; -},{}],78:[function(require,module,exports){ +},{}],76:[function(require,module,exports){ /** - * lodash 3.1.2 (Custom Build) + * lodash 3.0.3 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.8.3 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ -var getNative = require('lodash._getnative'), - isArguments = require('lodash.isarguments'), - isArray = require('lodash.isarray'); -/** Used to detect unsigned integer values. */ -var reIsUint = /^\d+$/; +/** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ +var baseCreate = (function() { + function object() {} + return function(prototype) { + if (isObject(prototype)) { + object.prototype = prototype; + var result = new object; + object.prototype = undefined; + } + return result || {}; + }; +}()); -/** Used for native method references. */ -var objectProto = Object.prototype; +/** + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; +module.exports = baseCreate; -/* Native method references for those with the same name as other `lodash` methods. */ -var nativeKeys = getNative(Object, 'keys'); +},{}],77:[function(require,module,exports){ +/** + * lodash 3.0.9 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** Used to detect unsigned integer values. */ +var reIsUint = /^\d+$/; /** - * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer) + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * of an array-like value. */ var MAX_SAFE_INTEGER = 9007199254740991; @@ -12796,44 +12802,39 @@ function isIndex(value, length) { } /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * Checks if the provided arguments are from an iteratee call. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; } /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). * * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ -function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; - - var allowIndexes = !!length && isLength(length) && - (isArray(object) || isArguments(object)); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** @@ -12863,96 +12864,9 @@ function isObject(value) { return !!value && (type == 'object' || type == 'function'); } -/** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) - * for more details. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ -var keys = !nativeKeys ? shimKeys : function(object) { - var Ctor = object == null ? undefined : object.constructor; - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isArrayLike(object))) { - return shimKeys(object); - } - return isObject(object) ? nativeKeys(object) : []; -}; - -/** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ -function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || isArguments(object)) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; - - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; -} - -module.exports = keys; +module.exports = isIterateeCall; -},{"lodash._getnative":73,"lodash.isarguments":76,"lodash.isarray":77}],79:[function(require,module,exports){ +},{}],78:[function(require,module,exports){ (function (process){ var path = require('path'); var fs = require('fs'); @@ -13054,7 +12968,7 @@ mkdirP.sync = function sync (p, opts, made) { }; }).call(this,require('_process')) -},{"_process":82,"fs":42,"path":42}],80:[function(require,module,exports){ +},{"_process":81,"fs":42,"path":42}],79:[function(require,module,exports){ exports.endianness = function () { return 'LE' }; exports.hostname = function () { @@ -13101,7 +13015,7 @@ exports.tmpdir = exports.tmpDir = function () { exports.EOL = '\n'; -},{}],81:[function(require,module,exports){ +},{}],80:[function(require,module,exports){ (function (process){ 'use strict'; @@ -13148,7 +13062,7 @@ function nextTick(fn, arg1, arg2, arg3) { } }).call(this,require('_process')) -},{"_process":82}],82:[function(require,module,exports){ +},{"_process":81}],81:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -13319,6 +13233,10 @@ process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; +process.prependListener = noop; +process.prependOnceListener = noop; + +process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); @@ -13330,10 +13248,10 @@ process.chdir = function (dir) { }; process.umask = function() { return 0; }; -},{}],83:[function(require,module,exports){ -module.exports = require("./lib/_stream_duplex.js") +},{}],82:[function(require,module,exports){ +module.exports = require('./lib/_stream_duplex.js'); -},{"./lib/_stream_duplex.js":84}],84:[function(require,module,exports){ +},{"./lib/_stream_duplex.js":83}],83:[function(require,module,exports){ // a duplex stream is just a stream that is both readable and writable. // Since JS doesn't have multiple prototypal inheritance, this class // prototypally inherits from Readable, and then parasitically from @@ -13409,7 +13327,7 @@ function forEach(xs, f) { f(xs[i], i); } } -},{"./_stream_readable":86,"./_stream_writable":88,"core-util-is":45,"inherits":66,"process-nextick-args":81}],85:[function(require,module,exports){ +},{"./_stream_readable":85,"./_stream_writable":87,"core-util-is":44,"inherits":65,"process-nextick-args":80}],84:[function(require,module,exports){ // a passthrough stream. // basically just the most minimal sort of Transform stream. // Every written chunk gets output as-is. @@ -13436,7 +13354,7 @@ function PassThrough(options) { PassThrough.prototype._transform = function (chunk, encoding, cb) { cb(null, chunk); }; -},{"./_stream_transform":87,"core-util-is":45,"inherits":66}],86:[function(require,module,exports){ +},{"./_stream_transform":86,"core-util-is":44,"inherits":65}],85:[function(require,module,exports){ (function (process){ 'use strict'; @@ -13450,6 +13368,10 @@ var processNextTick = require('process-nextick-args'); var isArray = require('isarray'); /**/ +/**/ +var Duplex; +/**/ + Readable.ReadableState = ReadableState; /**/ @@ -13461,19 +13383,11 @@ var EElistenerCount = function (emitter, type) { /**/ /**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); +var Stream = require('./internal/streams/stream'); /**/ -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); +var Buffer = require('safe-buffer').Buffer; /**/ /**/ @@ -13496,7 +13410,11 @@ var StringDecoder; util.inherits(Readable, Stream); +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. if (typeof emitter.prependListener === 'function') { return emitter.prependListener(event, fn); } else { @@ -13508,7 +13426,6 @@ function prependListener(emitter, event, fn) { } } -var Duplex; function ReadableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); @@ -13527,7 +13444,7 @@ function ReadableState(options, stream) { this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; + this.highWaterMark = ~~this.highWaterMark; // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than @@ -13578,7 +13495,6 @@ function ReadableState(options, stream) { } } -var Duplex; function Readable(options) { Duplex = Duplex || require('./_stream_duplex'); @@ -13604,7 +13520,7 @@ Readable.prototype.push = function (chunk, encoding) { if (!state.objectMode && typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { - chunk = bufferShim.from(chunk, encoding); + chunk = Buffer.from(chunk, encoding); encoding = ''; } } @@ -13901,7 +13817,7 @@ function maybeReadMore_(stream, state) { // for virtual (non-string, non-buffer) streams, "length" is somewhat // arbitrary, and perhaps not very meaningful. Readable.prototype._read = function (n) { - this.emit('error', new Error('not implemented')); + this.emit('error', new Error('_read() is not implemented')); }; Readable.prototype.pipe = function (dest, pipeOpts) { @@ -13924,7 +13840,7 @@ Readable.prototype.pipe = function (dest, pipeOpts) { var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - var endFn = doEnd ? onend : cleanup; + var endFn = doEnd ? onend : unpipe; if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); @@ -13957,7 +13873,7 @@ Readable.prototype.pipe = function (dest, pipeOpts) { dest.removeListener('error', onerror); dest.removeListener('unpipe', onunpipe); src.removeListener('end', onend); - src.removeListener('end', cleanup); + src.removeListener('end', unpipe); src.removeListener('data', ondata); cleanedUp = true; @@ -14079,16 +13995,16 @@ Readable.prototype.unpipe = function (dest) { state.pipesCount = 0; state.flowing = false; - for (var _i = 0; _i < len; _i++) { - dests[_i].emit('unpipe', this); + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this); }return this; } // try to find the right one. - var i = indexOf(state.pipes, dest); - if (i === -1) return this; + var index = indexOf(state.pipes, dest); + if (index === -1) return this; - state.pipes.splice(i, 1); + state.pipes.splice(index, 1); state.pipesCount -= 1; if (state.pipesCount === 1) state.pipes = state.pipes[0]; @@ -14220,10 +14136,9 @@ Readable.prototype.wrap = function (stream) { } // proxy certain important events. - var events = ['error', 'close', 'destroy', 'pause', 'resume']; - forEach(events, function (ev) { - stream.on(ev, self.emit.bind(self, ev)); - }); + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); + } // when we try to consume some more bytes, simply unpause the // underlying stream. @@ -14315,7 +14230,7 @@ function copyFromBufferString(n, list) { // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); + var ret = Buffer.allocUnsafe(n); var p = list.head; var c = 1; p.data.copy(ret); @@ -14376,7 +14291,7 @@ function indexOf(xs, x) { return -1; } }).call(this,require('_process')) -},{"./_stream_duplex":84,"./internal/streams/BufferList":89,"_process":82,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":63,"inherits":66,"isarray":68,"process-nextick-args":81,"string_decoder/":95,"util":40}],87:[function(require,module,exports){ +},{"./_stream_duplex":83,"./internal/streams/BufferList":88,"./internal/streams/stream":89,"_process":81,"core-util-is":44,"events":62,"inherits":65,"isarray":67,"process-nextick-args":80,"safe-buffer":94,"string_decoder/":96,"util":40}],86:[function(require,module,exports){ // a transform stream is a readable/writable stream where you do // something with the data. Sometimes it's called a "filter", // but that's not a great name for it, since that implies a thing where @@ -14473,7 +14388,6 @@ function Transform(options) { this._transformState = new TransformState(this); - // when the writable side finishes, then flush out anything remaining. var stream = this; // start out asking for a readable event once data is transformed. @@ -14490,9 +14404,10 @@ function Transform(options) { if (typeof options.flush === 'function') this._flush = options.flush; } + // When the writable side finishes, then flush out anything remaining. this.once('prefinish', function () { - if (typeof this._flush === 'function') this._flush(function (er) { - done(stream, er); + if (typeof this._flush === 'function') this._flush(function (er, data) { + done(stream, er, data); });else done(stream); }); } @@ -14513,7 +14428,7 @@ Transform.prototype.push = function (chunk, encoding) { // an error, then that'll put the hurt on the whole operation. If you // never call cb(), then you'll never get another chunk. Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('Not implemented'); + throw new Error('_transform() is not implemented'); }; Transform.prototype._write = function (chunk, encoding, cb) { @@ -14543,9 +14458,11 @@ Transform.prototype._read = function (n) { } }; -function done(stream, er) { +function done(stream, er, data) { if (er) return stream.emit('error', er); + if (data !== null && data !== undefined) stream.push(data); + // if there's nothing in the write buffer, then that means // that nothing more will ever be provided var ws = stream._writableState; @@ -14557,7 +14474,7 @@ function done(stream, er) { return stream.push(null); } -},{"./_stream_duplex":84,"core-util-is":45,"inherits":66}],88:[function(require,module,exports){ +},{"./_stream_duplex":83,"core-util-is":44,"inherits":65}],87:[function(require,module,exports){ (function (process){ // A bit simpler than readable streams. // Implement an async ._write(chunk, encoding, cb), and it'll handle all @@ -14575,6 +14492,10 @@ var processNextTick = require('process-nextick-args'); var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : processNextTick; /**/ +/**/ +var Duplex; +/**/ + Writable.WritableState = WritableState; /**/ @@ -14589,19 +14510,11 @@ var internalUtil = { /**/ /**/ -var Stream; -(function () { - try { - Stream = require('st' + 'ream'); - } catch (_) {} finally { - if (!Stream) Stream = require('events').EventEmitter; - } -})(); +var Stream = require('./internal/streams/stream'); /**/ -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); +var Buffer = require('safe-buffer').Buffer; /**/ util.inherits(Writable, Stream); @@ -14615,7 +14528,6 @@ function WriteReq(chunk, encoding, cb) { this.next = null; } -var Duplex; function WritableState(options, stream) { Duplex = Duplex || require('./_stream_duplex'); @@ -14635,8 +14547,9 @@ function WritableState(options, stream) { this.highWaterMark = hwm || hwm === 0 ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~ ~this.highWaterMark; + this.highWaterMark = ~~this.highWaterMark; + // drain event flag. this.needDrain = false; // at the start of calling end() this.ending = false; @@ -14711,7 +14624,7 @@ function WritableState(options, stream) { this.corkedRequestsFree = new CorkedRequest(this); } -WritableState.prototype.getBuffer = function writableStateGetBuffer() { +WritableState.prototype.getBuffer = function getBuffer() { var current = this.bufferedRequest; var out = []; while (current) { @@ -14731,13 +14644,37 @@ WritableState.prototype.getBuffer = function writableStateGetBuffer() { } catch (_) {} })(); -var Duplex; +// Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. +var realHasInstance; +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function (object) { + if (realHasInstance.call(this, object)) return true; + + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function (object) { + return object instanceof this; + }; +} + function Writable(options) { Duplex = Duplex || require('./_stream_duplex'); - // Writable ctor is applied to Duplexes, though they're not - // instanceof Writable, they're instanceof Readable. - if (!(this instanceof Writable) && !(this instanceof Duplex)) return new Writable(options); + // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { + return new Writable(options); + } this._writableState = new WritableState(options, this); @@ -14765,20 +14702,16 @@ function writeAfterEnd(stream, cb) { processNextTick(cb, er); } -// If we get something that is not a buffer, string, null, or undefined, -// and we're not in objectMode, then that's an error. -// Otherwise stream chunks are all considered to be of length=1, and the -// watermarks determine how many objects to keep in the buffer, rather than -// how many bytes or characters. +// Checks that a user-supplied chunk is valid, especially for the particular +// mode the stream is in. Currently this means that `null` is never accepted +// and undefined/non-string values are only allowed in object mode. function validChunk(stream, state, chunk, cb) { var valid = true; var er = false; - // Always throw error if a null is written - // if we are not in object mode then throw - // if it is not a buffer, string, or undefined. + if (chunk === null) { er = new TypeError('May not write null values to stream'); - } else if (!Buffer.isBuffer(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { er = new TypeError('Invalid non-string/buffer chunk'); } if (er) { @@ -14792,19 +14725,20 @@ function validChunk(stream, state, chunk, cb) { Writable.prototype.write = function (chunk, encoding, cb) { var state = this._writableState; var ret = false; + var isBuf = Buffer.isBuffer(chunk); if (typeof encoding === 'function') { cb = encoding; encoding = null; } - if (Buffer.isBuffer(chunk)) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; - if (state.ended) writeAfterEnd(this, cb);else if (validChunk(this, state, chunk, cb)) { + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; - ret = writeOrBuffer(this, state, chunk, encoding, cb); + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } return ret; @@ -14836,7 +14770,7 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = bufferShim.from(chunk, encoding); + chunk = Buffer.from(chunk, encoding); } return chunk; } @@ -14844,10 +14778,11 @@ function decodeChunk(state, chunk, encoding) { // if we're already writing something, then just put this // in the queue, and wait our turn. Otherwise, call _write // If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, chunk, encoding, cb) { - chunk = decodeChunk(state, chunk, encoding); - - if (Buffer.isBuffer(chunk)) encoding = 'buffer'; +function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + chunk = decodeChunk(state, chunk, encoding); + if (Buffer.isBuffer(chunk)) encoding = 'buffer'; + } var len = state.objectMode ? 1 : chunk.length; state.length += len; @@ -14916,8 +14851,8 @@ function onwrite(stream, er) { asyncWrite(afterWrite, stream, state, finished, cb); /**/ } else { - afterWrite(stream, state, finished, cb); - } + afterWrite(stream, state, finished, cb); + } } } @@ -14997,7 +14932,7 @@ function clearBuffer(stream, state) { } Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('not implemented')); + cb(new Error('_write() is not implemented')); }; Writable.prototype._writev = null; @@ -15068,7 +15003,6 @@ function CorkedRequest(state) { this.next = null; this.entry = null; - this.finish = function (err) { var entry = _this.entry; _this.entry = null; @@ -15086,12 +15020,12 @@ function CorkedRequest(state) { }; } }).call(this,require('_process')) -},{"./_stream_duplex":84,"_process":82,"buffer":44,"buffer-shims":43,"core-util-is":45,"events":63,"inherits":66,"process-nextick-args":81,"util-deprecate":96}],89:[function(require,module,exports){ +},{"./_stream_duplex":83,"./internal/streams/stream":89,"_process":81,"core-util-is":44,"inherits":65,"process-nextick-args":80,"safe-buffer":94,"util-deprecate":98}],88:[function(require,module,exports){ 'use strict'; -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); + +var Buffer = require('safe-buffer').Buffer; /**/ module.exports = BufferList; @@ -15139,9 +15073,9 @@ BufferList.prototype.join = function (s) { }; BufferList.prototype.concat = function (n) { - if (this.length === 0) return bufferShim.alloc(0); + if (this.length === 0) return Buffer.alloc(0); if (this.length === 1) return this.head.data; - var ret = bufferShim.allocUnsafe(n >>> 0); + var ret = Buffer.allocUnsafe(n >>> 0); var p = this.head; var i = 0; while (p) { @@ -15151,36 +15085,31 @@ BufferList.prototype.concat = function (n) { } return ret; }; -},{"buffer":44,"buffer-shims":43}],90:[function(require,module,exports){ -module.exports = require("./lib/_stream_passthrough.js") +},{"safe-buffer":94}],89:[function(require,module,exports){ +module.exports = require('events').EventEmitter; -},{"./lib/_stream_passthrough.js":85}],91:[function(require,module,exports){ -(function (process){ -var Stream = (function (){ - try { - return require('st' + 'ream'); // hack to fix a circular dependency issue when used with browserify - } catch(_){} -}()); +},{"events":62}],90:[function(require,module,exports){ +module.exports = require('./readable').PassThrough + +},{"./readable":91}],91:[function(require,module,exports){ exports = module.exports = require('./lib/_stream_readable.js'); -exports.Stream = Stream || exports; +exports.Stream = exports; exports.Readable = exports; exports.Writable = require('./lib/_stream_writable.js'); exports.Duplex = require('./lib/_stream_duplex.js'); exports.Transform = require('./lib/_stream_transform.js'); exports.PassThrough = require('./lib/_stream_passthrough.js'); -if (!process.browser && process.env.READABLE_STREAM === 'disable' && Stream) { - module.exports = Stream; -} +},{"./lib/_stream_duplex.js":83,"./lib/_stream_passthrough.js":84,"./lib/_stream_readable.js":85,"./lib/_stream_transform.js":86,"./lib/_stream_writable.js":87}],92:[function(require,module,exports){ +module.exports = require('./readable').Transform -}).call(this,require('_process')) -},{"./lib/_stream_duplex.js":84,"./lib/_stream_passthrough.js":85,"./lib/_stream_readable.js":86,"./lib/_stream_transform.js":87,"./lib/_stream_writable.js":88,"_process":82}],92:[function(require,module,exports){ -module.exports = require("./lib/_stream_transform.js") +},{"./readable":91}],93:[function(require,module,exports){ +module.exports = require('./lib/_stream_writable.js'); -},{"./lib/_stream_transform.js":87}],93:[function(require,module,exports){ -module.exports = require("./lib/_stream_writable.js") +},{"./lib/_stream_writable.js":87}],94:[function(require,module,exports){ +module.exports = require('buffer') -},{"./lib/_stream_writable.js":88}],94:[function(require,module,exports){ +},{"buffer":43}],95:[function(require,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -15309,230 +15238,344 @@ Stream.prototype.pipe = function(dest, options) { return dest; }; -},{"events":63,"inherits":66,"readable-stream/duplex.js":83,"readable-stream/passthrough.js":90,"readable-stream/readable.js":91,"readable-stream/transform.js":92,"readable-stream/writable.js":93}],95:[function(require,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var Buffer = require('buffer').Buffer; +},{"events":62,"inherits":65,"readable-stream/duplex.js":82,"readable-stream/passthrough.js":90,"readable-stream/readable.js":91,"readable-stream/transform.js":92,"readable-stream/writable.js":93}],96:[function(require,module,exports){ +'use strict'; -var isBufferEncoding = Buffer.isEncoding - || function(encoding) { - switch (encoding && encoding.toLowerCase()) { - case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; - default: return false; - } - } +var Buffer = require('safe-buffer').Buffer; +var isEncoding = Buffer.isEncoding || function (encoding) { + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': + return true; + default: + return false; + } +}; -function assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); +function _normalizeEncoding(enc) { + if (!enc) return 'utf8'; + var retried; + while (true) { + switch (enc) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return enc; + default: + if (retried) return; // undefined + enc = ('' + enc).toLowerCase(); + retried = true; + } } +}; + +// Do not cache `Buffer.isEncoding` when checking encoding names as some +// modules monkey-patch it to support additional encodings +function normalizeEncoding(enc) { + var nenc = _normalizeEncoding(enc); + if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); + return nenc || enc; } // StringDecoder provides an interface for efficiently splitting a series of // buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); +// characters. +exports.StringDecoder = StringDecoder; +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + var nb; switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; + this.text = utf16Text; + this.end = utf16End; + nb = 4; + break; + case 'utf8': + this.fillLast = utf8FillLast; + nb = 4; break; case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; + this.text = base64Text; + this.end = base64End; + nb = 3; break; default: - this.write = passThroughWrite; + this.write = simpleWrite; + this.end = simpleEnd; return; } + this.lastNeed = 0; + this.lastTotal = 0; + this.lastChar = Buffer.allocUnsafe(nb); +} - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; +StringDecoder.prototype.write = function (buf) { + if (buf.length === 0) return ''; + var r; + var i; + if (this.lastNeed) { + r = this.fillLast(buf); + if (r === undefined) return ''; + i = this.lastNeed; + this.lastNeed = 0; + } else { + i = 0; + } + if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); + return r || ''; }; +StringDecoder.prototype.end = utf8End; -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; - - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; - - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } - - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); - - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; +// Returns only complete characters in a Buffer +StringDecoder.prototype.text = utf8Text; - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; - } - break; +// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer +StringDecoder.prototype.fillLast = function (buf) { + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); } + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); + this.lastNeed -= buf.length; +}; - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); +// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a +// continuation byte. +function utf8CheckByte(byte) { + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; + return -1; +} - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; +// Checks at most 3 bytes at the end of a Buffer in order to detect an +// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) +// needed to complete the UTF-8 character (if applicable) are returned. +function utf8CheckIncomplete(self, buf, i) { + var j = buf.length - 1; + if (j < i) return 0; + var nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 1; + return nb; } + if (--j < i) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 2; + return nb; + } + if (--j < i) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) { + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; + } + return nb; + } + return 0; +} - charStr += buffer.toString(this.encoding, 0, end); - - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); +// Validates as many continuation bytes for a multi-byte UTF-8 character as +// needed or are available. If we see a non-continuation byte where we expect +// one, we "replace" the validated continuation bytes we've seen so far with +// UTF-8 replacement characters ('\ufffd'), to match v8's UTF-8 decoding +// behavior. The continuation byte check is included three times in the case +// where all of the continuation bytes for a character exist in the same buffer. +// It is also done this way as a slight performance increase instead of using a +// loop. +function utf8CheckExtraBytes(self, buf, p) { + if ((buf[0] & 0xC0) !== 0x80) { + self.lastNeed = 0; + return '\ufffd'.repeat(p); + } + if (self.lastNeed > 1 && buf.length > 1) { + if ((buf[1] & 0xC0) !== 0x80) { + self.lastNeed = 1; + return '\ufffd'.repeat(p + 1); + } + if (self.lastNeed > 2 && buf.length > 2) { + if ((buf[2] & 0xC0) !== 0x80) { + self.lastNeed = 2; + return '\ufffd'.repeat(p + 2); + } + } } +} - // or just emit the charStr - return charStr; -}; +// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. +function utf8FillLast(buf) { + var p = this.lastTotal - this.lastNeed; + var r = utf8CheckExtraBytes(this, buf, p); + if (r !== undefined) return r; + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, p, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, p, 0, buf.length); + this.lastNeed -= buf.length; +} + +// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a +// partial character, the character's bytes are buffered until the required +// number of bytes are available. +function utf8Text(buf, i) { + var total = utf8CheckIncomplete(this, buf, i); + if (!this.lastNeed) return buf.toString('utf8', i); + this.lastTotal = total; + var end = buf.length - (total - this.lastNeed); + buf.copy(this.lastChar, 0, end); + return buf.toString('utf8', i, end); +} + +// For UTF-8, a replacement character for each buffered byte of a (partial) +// character needs to be added to the output. +function utf8End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + '\ufffd'.repeat(this.lastTotal - this.lastNeed); + return r; +} + +// UTF-16LE typically needs two bytes per character, but even if we have an even +// number of bytes available, we need to check if we end on a leading/high +// surrogate. In that case, we need to wait for the next two bytes in order to +// decode the last character properly. +function utf16Text(buf, i) { + if ((buf.length - i) % 2 === 0) { + var r = buf.toString('utf16le', i); + if (r) { + var c = r.charCodeAt(r.length - 1); + if (c >= 0xD800 && c <= 0xDBFF) { + this.lastNeed = 2; + this.lastTotal = 4; + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + return r.slice(0, -1); + } + } + return r; + } + this.lastNeed = 1; + this.lastTotal = 2; + this.lastChar[0] = buf[buf.length - 1]; + return buf.toString('utf16le', i, buf.length - 1); +} -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; +// For UTF-16LE we do not explicitly append special replacement characters if we +// end on a partial character, we simply let v8 handle that. +function utf16End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) { + var end = this.lastTotal - this.lastNeed; + return r + this.lastChar.toString('utf16le', 0, end); + } + return r; +} - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; +function base64Text(buf, i) { + var n = (buf.length - i) % 3; + if (n === 0) return buf.toString('base64', i); + this.lastNeed = 3 - n; + this.lastTotal = 3; + if (n === 1) { + this.lastChar[0] = buf[buf.length - 1]; + } else { + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + } + return buf.toString('base64', i, buf.length - n); +} - // See http://en.wikipedia.org/wiki/UTF-8#Description +function base64End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); + return r; +} - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } +// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) +function simpleWrite(buf) { + return buf.toString(this.encoding); +} - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } +function simpleEnd(buf) { + return buf && buf.length ? this.write(buf) : ''; +} +},{"safe-buffer":97}],97:[function(require,module,exports){ +/* eslint-disable node/no-deprecated-api */ +var buffer = require('buffer') +var Buffer = buffer.Buffer - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] } - this.charReceived = i; -}; +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) - return res; -}; +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf } -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) } -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) } -},{"buffer":44}],96:[function(require,module,exports){ +},{"buffer":43}],98:[function(require,module,exports){ (function (global){ /** @@ -15603,16 +15646,16 @@ function config (name) { } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],97:[function(require,module,exports){ -arguments[4][66][0].apply(exports,arguments) -},{"dup":66}],98:[function(require,module,exports){ +},{}],99:[function(require,module,exports){ +arguments[4][65][0].apply(exports,arguments) +},{"dup":65}],100:[function(require,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } -},{}],99:[function(require,module,exports){ +},{}],101:[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // @@ -16202,4 +16245,4 @@ function hasOwnProperty(obj, prop) { } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./support/isBuffer":98,"_process":82,"inherits":97}]},{},[1]); +},{"./support/isBuffer":100,"_process":81,"inherits":99}]},{},[1]); From 82d879f5f9fcd28953a585683809221ac4f86fab Mon Sep 17 00:00:00 2001 From: Christopher Hiller Date: Mon, 31 Jul 2017 12:25:54 -0700 Subject: [PATCH 15/19] Release v3.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69543c66dc..e199cee1b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mocha", - "version": "3.4.2", + "version": "3.5.0", "description": "simple, flexible, fun test framework", "keywords": [ "mocha", From c0e6b68847e5bc414e5c158116caec2b089707c6 Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Sat, 8 Jul 2017 22:01:14 -0400 Subject: [PATCH 16/19] Eliminate glob.sh --- Makefile | 6 +- test/glob/glob.sh | 66 ----------------- .../fixtures}/glob/glob.spec.js | 2 +- test/integration/glob.spec.js | 71 +++++++++++++++++++ 4 files changed, 73 insertions(+), 72 deletions(-) delete mode 100755 test/glob/glob.sh rename test/{ => integration/fixtures}/glob/glob.spec.js (67%) create mode 100644 test/integration/glob.spec.js diff --git a/Makefile b/Makefile index 2fa367e8ff..13c50b8643 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ lint: @printf "==> [Test :: Lint]\n" npm run lint -test-node: test-bdd test-tdd test-qunit test-exports test-unit test-integration test-jsapi test-compilers test-glob test-requires test-reporters test-only test-global-only +test-node: test-bdd test-tdd test-qunit test-exports test-unit test-integration test-jsapi test-compilers test-requires test-reporters test-only test-global-only test-browser: clean BUILDTMP/mocha.js test-browser-unit test-browser-bdd test-browser-qunit test-browser-tdd test-browser-exports @@ -107,10 +107,6 @@ test-exports: $(call test_node,exports) --ui exports \ test/interfaces/exports.spec -test-glob: - @printf "==> [Test :: Glob]\n" - bash ./test/glob/glob.sh - test-reporters: @printf "==> [Test :: Reporters]\n" $(call test_node,reporters) test/reporters/*.spec.js diff --git a/test/glob/glob.sh b/test/glob/glob.sh deleted file mode 100755 index c0cb21d3f8..0000000000 --- a/test/glob/glob.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -REL_SCRIPT_DIR="`dirname \"$0\"`" -SCRIPT_DIR="`( cd \"$REL_SCRIPT_DIR\" && pwd )`" - -cd $SCRIPT_DIR || { - echo Could not cd to $SCRIPT_DIR from `pwd` - exit 1 -} - -../../bin/mocha -R json-stream ./*.js > /tmp/mocha-glob.txt || { - echo Globbing ./*.js in `pwd` failed. - exit 1 -} - -cat /tmp/mocha-glob.txt | grep -q -F '["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,' || { - echo Globbing ./*.js in `pwd` should match glob.js with one test inside. - exit 1 -} - -../../bin/mocha -R json-stream ./*-none.js 2> /tmp/mocha-glob.txt && { - echo Globbing './*-none.js' in `pwd` failed. - exit 1 -} - -cat /tmp/mocha-glob.txt | grep -q -F 'Could not find any test files matching pattern' || { - echo Globbing './*-none.js' in `pwd` should match no files and run no tests. - exit 1 -} - -../../bin/mocha -R json-stream ./*.js ./*-none.js >& /tmp/mocha-glob.txt || { - echo Globbing ./*.js ./*-none.js in `pwd` failed. - exit 1 -} - -cat /tmp/mocha-glob.txt | grep -q -F '["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,' && -cat /tmp/mocha-glob.txt | grep -q -F 'Could not find any test files matching pattern' || { - echo Globbing ./*.js ./*-none.js in `pwd` should match glob.js with one test inside and display one warning for the non-existing file. - exit 1 -} - -# Globbing in windows command-shell differs completely from unix-style globbing. -# In bash, the shell expands globs and passes the result to executables. -# In windows, the shell passes globs unexpanded, executables do expansion if they support it. -# Adding single-quotes around the glob below makes bash pass glob unexpanded, -# allowing us to test windows-style globbing in bash. -../../bin/mocha -R json-stream './*.js' > /tmp/mocha-glob.txt || { - echo Globbing './*.js' in `pwd` failed. - exit 1 -} - -cat /tmp/mocha-glob.txt | grep -q -F '["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,' || { - echo Globbing './*.js' in `pwd` should match glob.js with one test inside. - exit 1 -} - -../../bin/mocha -R json-stream './*-none.js' 2> /tmp/mocha-glob.txt && { - echo Globbing './*-none.js' in `pwd` failed. - exit 1 -} - -cat /tmp/mocha-glob.txt | grep -q -F 'Could not find any test files matching pattern' || { - echo Globbing './*-none.js' in `pwd` should match no files and run no tests. - exit 1 -} - -echo Glob-test passed. diff --git a/test/glob/glob.spec.js b/test/integration/fixtures/glob/glob.spec.js similarity index 67% rename from test/glob/glob.spec.js rename to test/integration/fixtures/glob/glob.spec.js index eca3733898..235c2f8417 100644 --- a/test/glob/glob.spec.js +++ b/test/integration/fixtures/glob/glob.spec.js @@ -2,6 +2,6 @@ describe('globbing test', function () { it('should find this test', function () { - // see glob.sh for details + // see test/integration/glob.spec.js for details }); }); diff --git a/test/integration/glob.spec.js b/test/integration/glob.spec.js new file mode 100644 index 0000000000..fb2bbf4353 --- /dev/null +++ b/test/integration/glob.spec.js @@ -0,0 +1,71 @@ +'use strict'; + +var expect = require('expect.js'); +var exec = require('child_process').exec; +var path = require('path'); + +var node = '"' + process.execPath + '"'; + +describe('globbing', function () { + describe('by the shell', function () { + it('should find the first level test', function (done) { + testGlob.shouldSucceed('./*.js', function (results) { + expect(results.stdout).to.contain('["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,'); + }, done); + }); + + it('should not find a non-matching pattern', function (done) { + testGlob.shouldFail('./*-none.js', function (results) { + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + + it('should handle both matching and non-matching patterns in the same command', function (done) { + testGlob.shouldSucceed('./*.js ./*-none.js', function (results) { + expect(results.stdout).to.contain('["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,'); + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + }); + + describe('by Mocha', function () { + it('should find the first level test', function (done) { + testGlob.shouldSucceed('"./*.js"', function (results) { + expect(results.stdout).to.contain('["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,'); + }, done); + }); + + it('should not find a non-matching pattern', function (done) { + testGlob.shouldFail('"./*-none.js"', function (results) { + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + + it('should handle both matching and non-matching patterns in the same command', function (done) { + testGlob.shouldSucceed('"./*.js" "./*-none.js"', function (results) { + expect(results.stdout).to.contain('["end",{"suites":1,"tests":1,"passes":1,"pending":0,"failures":0,'); + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + }); +}); + +var testGlob = { + shouldSucceed: execMochaWith(function shouldNotError (error) { if (error) { throw error; } }), + + shouldFail: execMochaWith(function shouldFailWithStderr (error, stderr) { expect(error && error.message).to.contain(stderr); }) +}; + +function execMochaWith (validate) { + return function execMocha (glob, assertOn, done) { + exec(node + ' "' + path.join('..', '..', '..', '..', 'bin', 'mocha') + '" -R json-stream ' + glob, { cwd: path.join(__dirname, 'fixtures', 'glob') }, function (error, stdout, stderr) { + try { + validate(error, stderr); + assertOn({ stdout: stdout, stderr: stderr }); + done(); + } catch (assertion) { + done(assertion); + } + }); + }; +} From 26d337aa1b7589f66dbbfe49ff9ff9821ca96897 Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Sat, 8 Jul 2017 22:33:26 -0400 Subject: [PATCH 17/19] Add tests for double-star behavior --- .../fixtures/glob/nested/glob.spec.js | 7 +++++++ test/integration/glob.spec.js | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/integration/fixtures/glob/nested/glob.spec.js diff --git a/test/integration/fixtures/glob/nested/glob.spec.js b/test/integration/fixtures/glob/nested/glob.spec.js new file mode 100644 index 0000000000..235c2f8417 --- /dev/null +++ b/test/integration/fixtures/glob/nested/glob.spec.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('globbing test', function () { + it('should find this test', function () { + // see test/integration/glob.spec.js for details + }); +}); diff --git a/test/integration/glob.spec.js b/test/integration/glob.spec.js index fb2bbf4353..df16d28283 100644 --- a/test/integration/glob.spec.js +++ b/test/integration/glob.spec.js @@ -47,6 +47,27 @@ describe('globbing', function () { expect(results.stderr).to.contain('Could not find any test files matching pattern'); }, done); }); + + describe('double-starred', function () { + it('should find the tests on multiple levels', function (done) { + testGlob.shouldSucceed('"./**/*.js"', function (results) { + expect(results.stdout).to.contain('["end",{"suites":2,"tests":2,"passes":2,"pending":0,"failures":0,'); + }, done); + }); + + it('should not find a non-matching pattern', function (done) { + testGlob.shouldFail('"./**/*-none.js"', function (results) { + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + + it('should handle both matching and non-matching patterns in the same command', function (done) { + testGlob.shouldSucceed('"./**/*.js" "./**/*-none.js"', function (results) { + expect(results.stdout).to.contain('["end",{"suites":2,"tests":2,"passes":2,"pending":0,"failures":0,'); + expect(results.stderr).to.contain('Could not find any test files matching pattern'); + }, done); + }); + }); }); }); From 13b83402cb735de0b39313904ea87fd9b3c2154f Mon Sep 17 00:00:00 2001 From: Scott Santucci Date: Tue, 1 Aug 2017 20:30:11 -0400 Subject: [PATCH 18/19] Ensure that compiler lookup works and not just that transpilation works (#2922) Test compilers lookup --- Makefile | 12 +++++++++--- test/{compiler => compiler-fixtures}/foo.js | 0 2 files changed, 9 insertions(+), 3 deletions(-) rename test/{compiler => compiler-fixtures}/foo.js (100%) diff --git a/Makefile b/Makefile index 2fa367e8ff..3e694ba6c0 100644 --- a/Makefile +++ b/Makefile @@ -74,9 +74,15 @@ test-integration: test-compilers: @printf "==> [Test :: Compilers]\n" - $(call test_node,compilers) --compilers coffee:coffee-script/register,foo:./test/compiler/foo \ - test/compiler/test.coffee \ - test/compiler/test.foo + $(call test_node,compilers-coffee) --compilers coffee:coffee-script/register \ + test/compiler + + $(call test_node,compilers-custom) --compilers foo:./test/compiler-fixtures/foo \ + test/compiler + + $(call test_node,compilers-multiple) \ + --compilers coffee:coffee-script/register,foo:./test/compiler-fixtures/foo \ + test/compiler test-requires: @printf "==> [Test :: Requires]\n" diff --git a/test/compiler/foo.js b/test/compiler-fixtures/foo.js similarity index 100% rename from test/compiler/foo.js rename to test/compiler-fixtures/foo.js From 8710438c8de06b951b4ba99ac0e706c90fa94c91 Mon Sep 17 00:00:00 2001 From: ScottFreeCode Date: Tue, 1 Aug 2017 23:09:51 -0400 Subject: [PATCH 19/19] Work around Node 0.10 Windows flake when testing --- test/integration/glob.spec.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/integration/glob.spec.js b/test/integration/glob.spec.js index df16d28283..4d1c5a52f4 100644 --- a/test/integration/glob.spec.js +++ b/test/integration/glob.spec.js @@ -77,13 +77,22 @@ var testGlob = { shouldFail: execMochaWith(function shouldFailWithStderr (error, stderr) { expect(error && error.message).to.contain(stderr); }) }; +var isFlakeyNode = (function () { + var version = process.versions.node.split('.'); + return version[0] === '0' && version[1] === '10' && process.platform === 'win32'; +}()); + function execMochaWith (validate) { return function execMocha (glob, assertOn, done) { exec(node + ' "' + path.join('..', '..', '..', '..', 'bin', 'mocha') + '" -R json-stream ' + glob, { cwd: path.join(__dirname, 'fixtures', 'glob') }, function (error, stdout, stderr) { try { validate(error, stderr); - assertOn({ stdout: stdout, stderr: stderr }); - done(); + if (isFlakeyNode && error && (stderr === '')) { + execMocha(glob, assertOn, done); + } else { + assertOn({ stdout: stdout, stderr: stderr }); + done(); + } } catch (assertion) { done(assertion); }