diff options
author | Stefan Giehl <stefan@piwik.org> | 2017-04-18 21:43:51 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-18 21:43:51 +0300 |
commit | 6a97e43ff69795c53c1b8dff63fc6a5cbdba8ca8 (patch) | |
tree | 5d3b8790c025ba8664a9fab1dbecfbb1f2b58dca /tests/lib/mocha-3.1.2/test | |
parent | ac9d6ab9ee5cf80ad2a769d40004c20410dc1053 (diff) |
update mocha to 3.1.2 (#11625)
Diffstat (limited to 'tests/lib/mocha-3.1.2/test')
149 files changed, 7660 insertions, 0 deletions
diff --git a/tests/lib/mocha-3.1.2/test/.eslintrc.yaml b/tests/lib/mocha-3.1.2/test/.eslintrc.yaml new file mode 100644 index 0000000000..1830a0b6f4 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/.eslintrc.yaml @@ -0,0 +1,7 @@ +env: + mocha: true +globals: + expect: false + assert: false + # https://github.com/sindresorhus/globals/pull/102 + run: false diff --git a/tests/lib/mocha-3.1.2/test/acceptance/context.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/context.spec.js new file mode 100644 index 0000000000..cbcdedb49d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/context.spec.js @@ -0,0 +1,73 @@ +'use strict'; + +describe('Context', function () { + beforeEach(function () { + this.calls = ['before']; + }); + + describe('nested', function () { + beforeEach(function () { + this.calls.push('before two'); + }); + + it('should work', function () { + expect(this.calls).to.eql(['before', 'before two']); + this.calls.push('test'); + }); + + after(function () { + expect(this.calls).to.eql(['before', 'before two', 'test']); + this.calls.push('after two'); + }); + }); + + after(function () { + expect(this.calls).to.eql(['before', 'before two', 'test', 'after two']); + }); +}); + +describe('Context Siblings', function () { + beforeEach(function () { + this.calls = ['before']; + }); + + describe('sequestered sibling', function () { + beforeEach(function () { + this.calls.push('before two'); + this.hiddenFromSibling = 'This should be hidden'; + }); + + it('should work', function () { + expect(this.hiddenFromSibling).to.eql('This should be hidden'); + }); + }); + + describe('sibling verifiction', function () { + beforeEach(function () { + this.calls.push('before sibling'); + }); + + it('should not have value set within a sibling describe', function () { + expect('This should be hidden').not.to.eql(this.hiddenFromSibling); + this.visibleFromTestSibling = 'Visible from test sibling'; + }); + + it('should allow test siblings to modify shared context', function () { + expect('Visible from test sibling').to.eql(this.visibleFromTestSibling); + }); + + it('should have reset this.calls before describe', function () { + expect(this.calls).to.eql(['before', 'before sibling']); + }); + }); + + after(function () { + expect(this.calls).to.eql(['before', 'before sibling']); + }); +}); + +describe('timeout()', function () { + it('should return the timeout', function () { + expect(this.timeout()).to.equal(200); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/duration.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/duration.spec.js new file mode 100644 index 0000000000..0194d4408c --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/duration.spec.js @@ -0,0 +1,27 @@ +'use strict'; + +describe('durations', function () { + describe('when slow', function () { + it('should highlight in red', function (done) { + setTimeout(function () { + done(); + }, 100); + }); + }); + + describe('when reasonable', function () { + it('should highlight in yellow', function (done) { + setTimeout(function () { + done(); + }, 50); + }); + }); + + describe('when fast', function () { + it('should highlight in green', function (done) { + setTimeout(function () { + done(); + }, 10); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/fs.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/fs.spec.js new file mode 100644 index 0000000000..9d0357c382 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/fs.spec.js @@ -0,0 +1,22 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var os = require('os'); +var tmpFile = path.join.bind(path, os.tmpdir()); + +describe('fs.readFile()', function () { + describe('when the file exists', function () { + it('should succeed', function (done) { + fs.writeFile(tmpFile('mocha'), 'wahoo', done); + }); + }); + + describe('when the file does not exist', function () { + it('should fail', function (done) { + // uncomment + // fs.readFile(tmpFile('does-not-exist'), done); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.sh b/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.sh new file mode 100644 index 0000000000..823ba07fb9 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.sh @@ -0,0 +1,66 @@ +#!/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/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.spec.js new file mode 100644 index 0000000000..eca3733898 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/glob/glob.spec.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('globbing test', function () { + it('should find this test', function () { + // see glob.sh for details + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/globals.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/globals.spec.js new file mode 100644 index 0000000000..b87df9fd99 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/globals.spec.js @@ -0,0 +1,43 @@ +'use strict'; + +describe('global leaks', function () { + before(function () { + // uncomment to test + // foo = 'hey'; + // bar = 'hey'; + }); + + beforeEach(function () { + // uncomment to test + // foo = 'bar' + }); + + it('should cause tests to fail', function () { + // uncomment to test + // foo = 'bar'; + // bar = 'baz'; + // baz = 'raz'; + }); + + it('should pass when accepted', function () { + global.okGlobalA = 1; + global.okGlobalB = 1; + global.okGlobalC = 1; + }); + + it('should pass with wildcard', function () { + global.callback123 = 'foo'; + global.callback345 = 'bar'; + }); + + it('should pass when prefixed "mocha-"', function () { + // Opera and IE do this for HTML element IDs anyway + // but to sure we can assert this in any browser, simulate it. + global['mocha-example'] = { nodeType: 1 }; + }); + + afterEach(function () { + // uncomment to test + // foo = 'bar' + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/http.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/http.spec.js new file mode 100644 index 0000000000..b8bc2f7e26 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/http.spec.js @@ -0,0 +1,18 @@ +'use strict'; + +var http = require('http'); + +var server = http.createServer(function (req, res) { + res.end('Hello World\n'); +}); + +server.listen(8888); + +describe('http', function () { + it('should provide an example', function (done) { + http.get({ path: '/', port: 8888 }, function (res) { + expect(res).to.have.property('statusCode', 200); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/interfaces/bdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/bdd.spec.js new file mode 100644 index 0000000000..f6e24d88a8 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/bdd.spec.js @@ -0,0 +1,34 @@ +'use strict'; + +describe('integer primitives', function () { + describe('arithmetic', function () { + it('should add', function () { + expect(1 + 1).to.equal(2); + expect(2 + 2).to.equal(4); + }); + + it('should subtract', function () { + expect(1 - 1).to.equal(0); + expect(2 - 1).to.equal(1); + }); + }); +}); + +describe('integer primitives', function () { + describe('arithmetic is not', function () { + it('should add', function () { + expect(1 + 1).not.to.equal(3); + expect(2 + 2).not.to.equal(5); + }); + }); +}); + +context('test suite', function () { + beforeEach(function () { + this.number = 5; + }); + + specify('share a property', function () { + expect(this.number).to.equal(5); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/interfaces/exports.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/exports.spec.js new file mode 100644 index 0000000000..f53c6a4ca0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/exports.spec.js @@ -0,0 +1,48 @@ +'use strict'; + +var calls = []; + +exports.Array = { + before: function () { + calls.push('before'); + }, + + after: function () { + calls.push('after'); + expect(calls) + .to + .eql([ + 'before', + 'before each', + 'one', + 'after each', + 'before each', + 'two', + 'after each', + 'after' + ]); + }, + + '#indexOf()': { + beforeEach: function () { + calls.push('before each'); + }, + + afterEach: function () { + calls.push('after each'); + }, + + 'should return -1 when the value is not present': function () { + calls.push('one'); + expect([1, 2, 3].indexOf(5)).to.equal(-1); + expect([1, 2, 3].indexOf(0)).to.equal(-1); + }, + + 'should return the correct index when the value is present': function () { + calls.push('two'); + expect([1, 2, 3].indexOf(1)).to.equal(0); + expect([1, 2, 3].indexOf(2)).to.equal(1); + expect([1, 2, 3].indexOf(3)).to.equal(2); + } + } +}; diff --git a/tests/lib/mocha-3.1.2/test/acceptance/interfaces/qunit.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/qunit.spec.js new file mode 100644 index 0000000000..0d15272f0b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/qunit.spec.js @@ -0,0 +1,25 @@ +'use strict'; + +function ok (expr, msg) { + if (!expr) throw new Error(msg); +} + +suite('integer primitives'); + +test('should add', function () { + var number = 2 + 2; + ok(number === 4); +}); + +test('should decrement', function () { + var number = 3; + ok(--number === 2); + ok(--number === 1); + ok(--number === 0); +}); + +suite('String'); + +test('#length', function () { + ok('foo'.length === 3); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/interfaces/tdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/tdd.spec.js new file mode 100644 index 0000000000..c2db518d70 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/interfaces/tdd.spec.js @@ -0,0 +1,42 @@ +'use strict'; + +suite('integer primitives', function () { + suite('arithmetic', function () { + var initialValue = 41; + + suiteSetup(function (done) { + expect(initialValue).to.eql(41); + initialValue += 1; + done(); + }); + + test('should add', function () { + expect(initialValue).to.eql(42); + expect(1 + 1).to.equal(2); + expect(2 + 2).to.equal(4); + }); + + test('should subtract', function () { + expect(initialValue).to.eql(42); + expect(1 - 1).to.equal(0); + expect(2 - 1).to.equal(1); + }); + + test.skip('should skip this test', function () { + var zero = 0; + expect(zero).to.equal(1, 'this test should have been skipped'); + }); + + suite.skip('should skip this suite', function () { + test('should skip this test', function () { + var zero = 0; + expect(zero).to.equal(1, 'this test should have been skipped'); + }); + }); + + suiteTeardown(function (done) { + expect(initialValue).to.eql(42); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/lookup-files.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/lookup-files.spec.js new file mode 100644 index 0000000000..faf31b1375 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/lookup-files.spec.js @@ -0,0 +1,90 @@ +'use strict'; + +var utils = require('../../lib/utils'); +var fs = require('fs'); +var path = require('path'); +var os = require('os'); +var mkdirp = require('mkdirp'); +var rimraf = require('rimraf'); + +describe('lookupFiles', function () { + var tmpDir = path.join(os.tmpDir(), 'mocha-lookup-files'); + var existsSync = fs.existsSync; + var tmpFile = path.join.bind(path, tmpDir); + var symlinkSupported = false; + + (function testSymlinkSupport () { + makeTempDir(); + + fs.writeFileSync(tmpFile('mocha-utils.js'), 'yippy skippy ying yang yow'); + try { + fs.symlinkSync(tmpFile('mocha-utils.js'), tmpFile('mocha-utils-link.js')); + symlinkSupported = true; + } catch (ignored) { + // ignored + } finally { + removeTempDir(); + } + }()); + + beforeEach(function () { + makeTempDir(); + + fs.writeFileSync(tmpFile('mocha-utils.js'), 'yippy skippy ying yang yow'); + if (symlinkSupported) { + fs.symlinkSync(tmpFile('mocha-utils.js'), tmpFile('mocha-utils-link.js')); + } + }); + + (symlinkSupported ? it : it.skip)('should not choke on symlinks', function () { + expect(utils.lookupFiles(tmpDir, ['js'], false)) + .to + .contain(tmpFile('mocha-utils-link.js')) + .and + .contain(tmpFile('mocha-utils.js')) + .and + .have + .length(2); + expect(existsSync(tmpFile('mocha-utils-link.js'))) + .to + .be(true); + fs.renameSync(tmpFile('mocha-utils.js'), tmpFile('bob')); + expect(existsSync(tmpFile('mocha-utils-link.js'))) + .to + .be(false); + expect(utils.lookupFiles(tmpDir, ['js'], false)) + .to + .eql([]); + }); + + it('should accept a glob "path" value', function () { + var res = utils.lookupFiles(tmpFile('mocha-utils*'), ['js'], false) + .map(path.normalize.bind(path)); + + var expectedLength = 0; + var ex = expect(res) + .to + .contain(tmpFile('mocha-utils.js')); + expectedLength++; + + if (symlinkSupported) { + ex = ex.and + .contain(tmpFile('mocha-utils-link.js')); + expectedLength++; + } + + ex.and + .have + .length(expectedLength); + }); + + afterEach(removeTempDir); + + function makeTempDir () { + mkdirp.sync(tmpDir); + } + + function removeTempDir () { + rimraf.sync(tmpDir); + } +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/exit.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/exit.spec.js new file mode 100644 index 0000000000..916752f9b1 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/exit.spec.js @@ -0,0 +1,20 @@ +'use strict'; + +describe('exit', function () { + // note --bail works nicely in that it still allows an 'early exit' in an error scenario + it('should not exit even in error scenario if called with --no-exit', function (done) { + done(new Error('failure')); + }); + + it('should take a long time to exit if called with --no-exit', function (done) { + done(); + setTimeout(function () { + console.log('all done'); + }, 2500); + }); + + it('should kill all processes when SIGINT received', function () { + // uncomment to test + // while (true) {} + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/many.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/many.spec.js new file mode 100644 index 0000000000..d4e4a1e806 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/many.spec.js @@ -0,0 +1,28 @@ +'use strict'; + +// Useful for testing SIGINT handler +// use env.big_number to tune iterations so that you have time to ctrl+c + +describe('a load of tests', function () { + it('should fail the first test', function () { + throw new Error('this should appear in the summary'); + }); + + var iterations = (process.env.big_number || 1e7); + function work () { + var a = 0; + for (var i = 0; i < iterations; ++i) { + a += i; + } + } + + function addTest () { + it('should pass test ' + i, function () { + work(); + }); + } + + for (var i = 0; i < 500; ++i) { + addTest(); + } +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/nontty.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/nontty.spec.js new file mode 100644 index 0000000000..ea57b9733f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/nontty.spec.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('tests for non-tty', function () { + it('should pass', function () { + + }); + + it('should fail', function () { + throw new Error('oh noes'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd-require.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd-require.spec.js new file mode 100644 index 0000000000..14710c4cd2 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd-require.spec.js @@ -0,0 +1,20 @@ +'use strict'; + +/* jshint node: true */ + +var mocha = require('../../../../lib/mocha'); + +var beforeEach = mocha.beforeEach; +var it = mocha.it; +var describe = mocha.describe; + +describe('it.only via require("mocha")', function () { + beforeEach(function () { + this.didRunBeforeEach = true; + }); + describe('nested within a describe/context', function () { + it.only('should run all enclosing beforeEach hooks', function () { + require('assert').equal(this.didRunBeforeEach, true); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd.spec.js new file mode 100644 index 0000000000..639ab30e1b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/bdd.spec.js @@ -0,0 +1,127 @@ +'use strict'; + +describe('should only run .only test in this bdd suite', function () { + it('should not run this test', function () { + (0).should.equal(1, 'this test should have been skipped'); + }); + it.only('should run this test', function () { + (0).should.equal(0, 'this .only test should run'); + }); + it('should run this test, not (includes the title of the .only test)', function () { + (0).should.equal(1, 'this test should have been skipped'); + }); +}); + +describe('should not run this suite', function () { + it('should not run this test', function () { + (true).should.equal(false); + }); + + it('should not run this test', function () { + (true).should.equal(false); + }); + + it('should not run this test', function () { + (true).should.equal(false); + }); +}); + +describe.only('should run all tests in this bdd suite', function () { + it('should run this test #1', function () { + (true).should.equal(true); + }); + + it('should run this test #2', function () { + (1).should.equal(1); + }); + + it('should run this test #3', function () { + ('foo').should.equal('foo'); + }); +}); + +describe('should run only suites that marked as `only`', function () { + describe.only('should run all this tdd suite', function () { + it('should run this test #1', function () { + (true).should.equal(true); + }); + + it('should run this test #2', function () { + (true).should.equal(true); + }); + }); + + describe('should not run this suite', function () { + it('should run this test', function () { + (true).should.equal(false); + }); + }); +}); + +// Nested situation +describe('should not run parent tests', function () { + it('should not run this test', function () { + (true).should.equal(false); + }); + describe('and not the child tests too', function () { + it('should not run this test', function () { + (true).should.equal(false); + }); + describe.only('but run all the tests in this suite', function () { + it('should run this test #1', function () { + (true).should.equal(true); + }); + it('should run this test #2', function () { + (true).should.equal(true); + }); + }); + }); +}); + +// mark test as `only` override the suite behavior +describe.only('should run only tests that marked as `only`', function () { + it('should not run this test #1', function () { + (false).should.equal(true); + }); + + it.only('should run this test #2', function () { + (true).should.equal(true); + }); + + it('should not run this test #3', function () { + (false).should.equal(true); + }); + + it.only('should run this test #4', function () { + (true).should.equal(true); + }); +}); + +describe.only('Should run only test cases that mark as only', function () { + it.only('should runt his test', function () { + (true).should.equal(true); + }); + + it('should not run this test', function () { + (false).should.equal(true); + }); + + describe('should not run this suite', function () { + it('should not run this test', function () { + (false).should.equal(true); + }); + }); +}); + +// Root Suite +it.only('#Root-Suite, should run this test-case #1', function () { + (true).should.equal(true); +}); + +it.only('#Root-Suite, should run this test-case #2', function () { + (true).should.equal(true); +}); + +it('#Root-Suite, should not run this test', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/bdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/bdd.spec.js new file mode 100644 index 0000000000..1fc3d14384 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/bdd.spec.js @@ -0,0 +1,14 @@ +'use strict'; + +// Root-only test cases +it.only('#Root-Suite, should run this bdd test-case #1', function () { + (true).should.equal(true); +}); + +it('#Root-Suite, should not run this bdd test-case #2', function () { + (false).should.equal(true); +}); + +it('#Root-Suite, should not run this bdd test-case #3', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/qunit.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/qunit.spec.js new file mode 100644 index 0000000000..69bbd3467a --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/qunit.spec.js @@ -0,0 +1,14 @@ +'use strict'; + +// Root-only test cases +test.only('#Root-Suite, should run this qunit test-case #1', function () { + (true).should.equal(true); +}); + +test('#Root-Suite, should not run this qunit test-case #2', function () { + (false).should.equal(true); +}); + +test('#Root-Suite, should not run this qunit test-case #3', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/tdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/tdd.spec.js new file mode 100644 index 0000000000..03fdea768f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/global/tdd.spec.js @@ -0,0 +1,14 @@ +'use strict'; + +// Root-only test cases +test.only('#Root-Suite, should run this tdd test-case #1', function () { + (true).should.equal(true); +}); + +test('#Root-Suite, should not run this tdd test-case #2', function () { + (false).should.equal(true); +}); + +test('#Root-Suite, should not run this tdd test-case #3', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/qunit.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/qunit.spec.js new file mode 100644 index 0000000000..77bdfcc64f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/qunit.spec.js @@ -0,0 +1,75 @@ +'use strict'; + +// Root Suite +test.only('#Root-Suite, should run this test-case #1', function () { + (true).should.equal(true); +}); + +test.only('#Root-Suite, should run this test-case #2', function () { + (true).should.equal(true); +}); + +test('#Root-Suite, should not run this test', function () { + (false).should.equal(true); +}); + +suite('should only run .only test in this qunit suite'); + +test('should not run this test', function () { + (0).should.equal(1, 'this test should have been skipped'); +}); +test.only('should run this test', function () { + (0).should.equal(0, 'this .only test should run'); +}); +test('should run this test, not (includes the title of the .only test)', function () { + (0).should.equal(1, 'this test should have been skipped'); +}); + +// Mark suite +suite.only('should run all tests in this suite'); + +test('should run this test #1', function () { + (true).should.equal(true); +}); + +test('should run this test #2', function () { + (true).should.equal(true); +}); + +test('should run this test #3', function () { + (true).should.equal(true); +}); + +// Unmark this suite +suite('should not run any of this suite\'s tests'); + +test('should not run this test', function () { + (false).should.equal(true); +}); + +test('should not run this test', function () { + (false).should.equal(true); +}); + +test('should not run this test', function () { + (false).should.equal(true); +}); + +// Mark test as `only` override the suite behavior +suite.only('should run only tests that marked as `only`'); + +test('should not run this test #1', function () { + (false).should.equal(true); +}); + +test.only('should not run this test #2', function () { + (true).should.equal(true); +}); + +test('should not run this test #3', function () { + (false).should.equal(true); +}); + +test.only('should not run this test #4', function () { + (true).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/misc/only/tdd.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/tdd.spec.js new file mode 100644 index 0000000000..da5f45b198 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/misc/only/tdd.spec.js @@ -0,0 +1,127 @@ +'use strict'; + +suite('should only run .only test in this tdd suite', function () { + test('should not run this test', function () { + (0).should.equal(1, 'this test should have been skipped'); + }); + test.only('should run this test', function () { + (0).should.equal(0, 'this .only test should run'); + }); + test('should run this test, not (includes the title of the .only test)', function () { + (0).should.equal(1, 'this test should have been skipped'); + }); +}); + +suite('should not run this suite', function () { + test('should not run this test', function () { + (true).should.equal(false); + }); + + test('should not run this test', function () { + (true).should.equal(false); + }); + + test('should not run this test', function () { + (true).should.equal(false); + }); +}); + +suite.only('should run all tests in this tdd suite', function () { + test('should run this test #1', function () { + (true).should.equal(true); + }); + + test('should run this test #2', function () { + (1).should.equal(1); + }); + + test('should run this test #3', function () { + ('foo').should.equal('foo'); + }); +}); + +suite('should run only suites that marked as `only`', function () { + suite.only('should run all this tdd suite', function () { + test('should run this test #1', function () { + (true).should.equal(true); + }); + + test('should run this test #2', function () { + (true).should.equal(true); + }); + }); + + suite('should not run this suite', function () { + test('should not run this test', function () { + (true).should.equal(false); + }); + }); +}); + +// Nested situation +suite('should not run parent tests', function () { + test('should not run this test', function () { + (true).should.equal(false); + }); + suite('and not the child tests too', function () { + test('should not run this test', function () { + (true).should.equal(false); + }); + suite.only('but run all the tests in this suite', function () { + test('should run this test #1', function () { + (true).should.equal(true); + }); + test('should run this test #2', function () { + (true).should.equal(true); + }); + }); + }); +}); + +// mark test as `only` override the suite behavior +suite.only('should run only tests that marked as `only`', function () { + test('should not run this test #1', function () { + (false).should.equal(true); + }); + + test.only('should run this test #2', function () { + (true).should.equal(true); + }); + + test('should not run this test #3', function () { + (false).should.equal(true); + }); + + test.only('should run this test #4', function () { + (true).should.equal(true); + }); +}); + +suite.only('Should run only test cases that mark as only', function () { + test.only('should runt his test', function () { + (true).should.equal(true); + }); + + test('should not run this test', function () { + (false).should.equal(true); + }); + + suite('should not run this suite', function () { + test('should not run this test', function () { + (false).should.equal(true); + }); + }); +}); + +// Root Suite +test.only('#Root-Suite, should run this test-case #1', function () { + (true).should.equal(true); +}); + +test.only('#Root-Suite, should run this test-case #2', function () { + (true).should.equal(true); +}); + +test('#Root-Suite, should not run this test', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/overspecified-async.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/overspecified-async.spec.js new file mode 100644 index 0000000000..0f9b6c9ff5 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/overspecified-async.spec.js @@ -0,0 +1,10 @@ +'use strict'; + +describe('overspecified asynchronous resolution method', function () { + it('should fail when multiple methods are used', function (done) { + setTimeout(done, 0); + + // uncomment + // return { then: function() {} }; + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/require/a.js b/tests/lib/mocha-3.1.2/test/acceptance/require/a.js new file mode 100644 index 0000000000..949b8af2f0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/require/a.js @@ -0,0 +1,4 @@ +'use strict'; + +global.required = (global.required || []); +global.required.push('a.js'); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/require/b.coffee b/tests/lib/mocha-3.1.2/test/acceptance/require/b.coffee new file mode 100644 index 0000000000..045cc7591b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/require/b.coffee @@ -0,0 +1,2 @@ +global.required ?= [] +global.required.push 'b.coffee' diff --git a/tests/lib/mocha-3.1.2/test/acceptance/require/c.js b/tests/lib/mocha-3.1.2/test/acceptance/require/c.js new file mode 100644 index 0000000000..4d68dc4549 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/require/c.js @@ -0,0 +1,4 @@ +'use strict'; + +global.required = (global.required || []); +global.required.push('c.js'); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/require/d.coffee b/tests/lib/mocha-3.1.2/test/acceptance/require/d.coffee new file mode 100644 index 0000000000..d5ebbf60ed --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/require/d.coffee @@ -0,0 +1,2 @@ +global.required ?= [] +global.required.push 'd.coffee' diff --git a/tests/lib/mocha-3.1.2/test/acceptance/require/require.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/require/require.spec.js new file mode 100644 index 0000000000..f959a859a8 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/require/require.spec.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('require test', function () { + it('should require args in order', function () { + var req = global.required; + expect(req.indexOf('a.js')).to.equal(0); + expect(req.indexOf('b.coffee')).to.equal(1); + expect(req.indexOf('c.js')).to.equal(2); + expect(req.indexOf('d.coffee')).to.equal(3); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/required-tokens.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/required-tokens.spec.js new file mode 100644 index 0000000000..2b44dee59b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/required-tokens.spec.js @@ -0,0 +1,12 @@ +'use strict'; + +var assert = require('assert'); +var describe = require('../..').describe; +var it = require('../..').it; + +describe('using imported describe', function () { + it('using imported it', function (done) { + assert.ok(true); + done(); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/root.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/root.spec.js new file mode 100644 index 0000000000..abd8d4192e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/root.spec.js @@ -0,0 +1,13 @@ +'use strict'; + +var calls = []; + +before(function () { + calls.push('before'); +}); + +describe('root', function () { + it('should be a valid suite', function () { + expect(calls).to.eql(['before']); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/test.coffee b/tests/lib/mocha-3.1.2/test/acceptance/test.coffee new file mode 100644 index 0000000000..b8e309f515 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/test.coffee @@ -0,0 +1,6 @@ + +obj = foo: 'bar' + +describe 'coffeescript', -> + it 'should work', -> + expect(obj).to.eql foo: 'bar' diff --git a/tests/lib/mocha-3.1.2/test/acceptance/test.foo b/tests/lib/mocha-3.1.2/test/acceptance/test.foo new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/test.foo @@ -0,0 +1 @@ +1 diff --git a/tests/lib/mocha-3.1.2/test/acceptance/throw.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/throw.spec.js new file mode 100644 index 0000000000..68e8cd2c1d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/throw.spec.js @@ -0,0 +1,108 @@ +'use strict'; + +/* eslint no-throw-literal: off */ + +var Suite = require('../../lib/suite'); +var Test = require('../../lib/test'); +var Runner = require('../../lib/runner'); + +describe('a test that throws', function () { + var suite, runner; + + beforeEach(function () { + suite = new Suite('Suite', 'root'); + runner = new Runner(suite); + }); + + describe('undefined', function () { + it('should not pass if throwing sync and test is sync', function (done) { + var test = new Test('im sync and throw undefined sync', function () { + throw undefined; + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + + it('should not pass if throwing sync and test is async', function (done) { + var test = new Test('im async and throw undefined sync', function (done2) { + throw undefined; + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + + it('should not pass if throwing async and test is async', function (done) { + var test = new Test('im async and throw undefined async', function (done2) { + process.nexTick(function () { + throw undefined; + }); + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + }); + + describe('null', function () { + it('should not pass if throwing sync and test is sync', function (done) { + var test = new Test('im sync and throw null sync', function () { + throw null; + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + + it('should not pass if throwing sync and test is async', function (done) { + var test = new Test('im async and throw null sync', function (done2) { + throw null; + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + + it('should not pass if throwing async and test is async', function (done) { + var test = new Test('im async and throw null async', function (done2) { + process.nexTick(function () { + throw null; + }); + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function () { + expect(runner.failures).to.equal(1); + expect(test.state).to.equal('failed'); + done(); + }); + runner.run(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/timeout.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/timeout.spec.js new file mode 100644 index 0000000000..b3fc632a0d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/timeout.spec.js @@ -0,0 +1,79 @@ +'use strict'; + +describe('timeouts', function () { + beforeEach(function (done) { + // uncomment + // setTimeout(done, 3000); + done(); + }); + + it('should error on timeout', function (done) { + // uncomment + // setTimeout(done, 3000); + done(); + }); + + it('should allow overriding per-test', function (done) { + this.timeout(1000); + setTimeout(function () { + done(); + }, 300); + }); + + describe('disabling', function () { + it('should allow overriding per-test', function (done) { + this.enableTimeouts(false); + this.timeout(1); + setTimeout(done, 2); + }); + + it('should work with timeout(0)', function (done) { + this.timeout(0); + setTimeout(done, 1); + }); + + describe('using beforeEach', function () { + beforeEach(function () { + this.timeout(0); + }); + + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + }); + + describe('using before', function () { + before(function () { + this.timeout(0); + }); + + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + }); + + describe('using enableTimeouts(false)', function () { + this.timeout(4); + + it('should suppress timeout(4)', function (done) { + // The test is in the before() call. + this.enableTimeouts(false); + setTimeout(done, 50); + }); + }); + + describe('suite-level', function () { + this.timeout(0); + + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + + describe('nested suite', function () { + it('should work with timeout(0)', function (done) { + setTimeout(done, 1); + }); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/acceptance/utils.spec.js b/tests/lib/mocha-3.1.2/test/acceptance/utils.spec.js new file mode 100644 index 0000000000..545bdfd265 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/acceptance/utils.spec.js @@ -0,0 +1,418 @@ +'use strict'; + +var utils = require('../../lib/utils'); +var toISOString = require('../../lib/to-iso-string'); +var JSON = require('json3'); + +describe('lib/utils', function () { + describe('clean', function () { + it('should format a single line test function', function () { + var fn = [ + 'function () {', + ' var a = 1;', + '}' + ].join('\n'); + expect(utils.clean(fn)).to.equal('var a = 1;'); + }); + + it('should format a multi line test indented with spaces', function () { + // and no new lines after curly braces, shouldn't matter + var fn = [ + 'function(){ var a = 1;', + // this one has more spaces + ' var b = 2;', + ' var c = 3; }' + ].join('\n'); + expect(utils.clean(fn)).to.equal('var a = 1;\n var b = 2;\nvar c = 3;'); + }); + + it('should format a multi line test indented with tabs', function () { + var fn = [ + 'function (arg1, arg2) {', + '\tif (true) {', + '\t\tvar a = 1;', + '\t}', + '}' + ].join('\n'); + expect(utils.clean(fn)).to.equal('if (true) {\n\tvar a = 1;\n}'); + }); + + it('should format functions saved in windows style - spaces', function () { + var fn = [ + 'function (one) {', + ' do {', + ' "nothing";', + ' } while (false);', + ' }' + ].join('\r\n'); + expect(utils.clean(fn)).to.equal('do {\n "nothing";\n} while (false);'); + }); + + it('should format functions saved in windows style - tabs', function () { + var fn = [ + 'function ( ) {', + '\tif (false) {', + '\t\tvar json = {', + '\t\t\tone : 1', + '\t\t};', + '\t}', + '}' + ].join('\r\n'); + expect(utils.clean(fn)).to.equal('if (false) {\n\tvar json = {\n\t\tone : 1\n\t};\n}'); + }); + + it('should format es6 arrow functions', function () { + var fn = [ + '() => {', + ' var a = 1;', + '}' + ].join('\n'); + expect(utils.clean(fn)).to.equal('var a = 1;'); + }); + + it('should format es6 arrow functions with implicit return', function () { + var fn = '() => foo()'; + expect(utils.clean(fn)).to.equal('foo()'); + }); + }); + + describe('stringify', function () { + var stringify = utils.stringify; + + it('should return an object representation of a string created with a String constructor', function () { + /* eslint no-new-wrappers: off */ + expect(stringify(new String('foo'))).to.equal('{\n "0": "f"\n "1": "o"\n "2": "o"\n}'); + }); + + it('should return Buffer with .toJSON representation', function () { + expect(stringify(new Buffer([0x01]))).to.equal('[\n 1\n]'); + expect(stringify(new Buffer([0x01, 0x02]))).to.equal('[\n 1\n 2\n]'); + + expect(stringify(new Buffer('ABCD'))).to.equal('[\n 65\n 66\n 67\n 68\n]'); + }); + + it('should return Date object with .toISOString() + string prefix', function () { + expect(stringify(new Date(0))).to.equal('[Date: ' + shimToISOString(new Date(0)) + ']'); + + var date = new Date(); // now + expect(stringify(date)).to.equal('[Date: ' + shimToISOString(date) + ']'); + + function shimToISOString (date) { + if (date.toISOString) { + return date.toISOString(); + } else { + return toISOString(date); + } + } + }); + + it('should return invalid Date object with .toString() + string prefix', function () { + expect(stringify(new Date(''))).to.equal('[Date: ' + new Date('').toString() + ']'); + }); + + describe('#Number', function () { + it('should show the handle -0 situations', function () { + expect(stringify(-0)).to.eql('-0'); + expect(stringify(0)).to.eql('0'); + expect(stringify('-0')).to.eql('"-0"'); + }); + + it('should work well with `NaN` and `Infinity`', function () { + expect(stringify(NaN)).to.equal('NaN'); + expect(stringify(Infinity)).to.equal('Infinity'); + expect(stringify(-Infinity)).to.equal('-Infinity'); + }); + + it('floats and ints', function () { + expect(stringify(1)).to.equal('1'); + expect(stringify(1.2)).to.equal('1.2'); + expect(stringify(1e9)).to.equal('1000000000'); + }); + }); + + describe('canonicalize example', function () { + it('should represent the actual full result', function () { + var expected = { + str: 'string', + int: 90, + float: 9.99, + boolean: false, + nil: null, + undef: undefined, + regex: /^[a-z|A-Z]/, + date: new Date(0), + func: function () {}, + infi: Infinity, + nan: NaN, + zero: -0, + buffer: new Buffer([0x01, 0x02]), + array: [1, 2, 3], + empArr: [], + matrix: [[1], + [ + 2, + 3, + 4 + ] + ], + object: { a: 1, b: 2 }, + canObj: { a: { b: 1, c: 2 }, b: {} }, + empObj: {} + }; + expected.circular = expected; // Make `Circular` situation + var actual = [ + '{', + ' "array": [', + ' 1', + ' 2', + ' 3', + ' ]', + ' "boolean": false', + ' "buffer": [Buffer: [', + ' 1', + ' 2', + ' ]]', + ' "canObj": {', + ' "a": {', + ' "b": 1', + ' "c": 2', + ' }', + ' "b": {}', + ' }', + ' "circular": [Circular]', + ' "date": [Date: 1970-01-01T00:00:00.000Z]', + ' "empArr": []', + ' "empObj": {}', + ' "float": 9.99', + ' "func": [Function]', + ' "infi": Infinity', + ' "int": 90', + ' "matrix": [', + ' [', + ' 1', + ' ]', + ' [', + ' 2', + ' 3', + ' 4', + ' ]', + ' ]', + ' "nan": NaN', + ' "nil": [null]', + ' "object": {', + ' "a": 1', + ' "b": 2', + ' }', + ' "regex": /^[a-z|A-Z]/', + ' "str": "string"', + ' "undef": [undefined]', + ' "zero": -0', + '}' + ].join('\n'); + expect(stringify(expected)).to.equal(actual); + }); + }); + + it('should canonicalize the object', function () { + var travis = { name: 'travis', age: 24 }; + var travis2 = { age: 24, name: 'travis' }; + + expect(stringify(travis)).to.equal(stringify(travis2)); + }); + + it('should handle circular structures in objects', function () { + var travis = { name: 'travis' }; + travis.whoami = travis; + + expect(stringify(travis)).to.equal('{\n "name": "travis"\n "whoami": [Circular]\n}'); + }); + + it('should handle circular structures in arrays', function () { + var travis = ['travis']; + travis.push(travis); + + expect(stringify(travis)).to.equal('[\n "travis"\n [Circular]\n]'); + }); + + it('should handle circular structures in functions', function () { + var travis = function () {}; + travis.fn = travis; + + expect(stringify(travis)).to.equal('{\n "fn": [Circular]\n}'); + }); + + it('should handle various non-undefined, non-null, non-object, non-array, non-date, and non-function values', function () { + var regexp = new RegExp('(?:)'); + var regExpObj = {regexp: regexp}; + var regexpString = '/(?:)/'; + + expect(stringify(regExpObj)).to.equal('{\n "regexp": ' + regexpString + '\n}'); + expect(stringify(regexp)).to.equal(regexpString); + + var number = 1; + var numberObj = {number: number}; + var numberString = '1'; + + expect(stringify(numberObj)).to.equal('{\n "number": ' + number + '\n}'); + expect(stringify(number)).to.equal(numberString); + + var boolean = false; + var booleanObj = {boolean: boolean}; + var booleanString = 'false'; + + expect(stringify(booleanObj)).to.equal('{\n "boolean": ' + boolean + '\n}'); + expect(stringify(boolean)).to.equal(booleanString); + + var string = 'sneepy'; + var stringObj = {string: string}; + + expect(stringify(stringObj)).to.equal('{\n "string": "' + string + '"\n}'); + expect(stringify(string)).to.equal(JSON.stringify(string)); + + var nullValue = null; + var nullObj = {'null': null}; + var nullString = '[null]'; + + expect(stringify(nullObj)).to.equal('{\n "null": [null]\n}'); + expect(stringify(nullValue)).to.equal(nullString); + }); + + it('should handle arrays', function () { + var array = ['dave', 'dave', 'dave', 'dave']; + var arrayObj = {array: array}; + var arrayString = ' "dave"\n "dave"\n "dave"\n "dave"'; + + expect(stringify(arrayObj)).to.equal('{\n "array": [\n' + arrayString + '\n ]\n}'); + expect(stringify(array)).to.equal('[' + arrayString.replace(/\s+/g, '\n ') + '\n]'); + }); + + it('should handle functions', function () { + var fn = function () {}; + var fnObj = {fn: fn}; + var fnString = '[Function]'; + + expect(stringify(fnObj)).to.equal('{\n "fn": ' + fnString + '\n}'); + expect(stringify(fn)).to.equal('[Function]'); + }); + + it('should handle empty objects', function () { + expect(stringify({})).to.equal('{}'); + expect(stringify({foo: {}})).to.equal('{\n "foo": {}\n}'); + }); + + it('should handle empty arrays', function () { + expect(stringify([])).to.equal('[]'); + expect(stringify({foo: []})).to.equal('{\n "foo": []\n}'); + }); + + it('should handle non-empty arrays', function () { + expect(stringify(['a', 'b', 'c'])).to.equal('[\n "a"\n "b"\n "c"\n]'); + }); + + it('should handle empty functions (with no properties)', function () { + expect(stringify(function () {})).to.equal('[Function]'); + expect(stringify({foo: function () {}})).to.equal('{\n "foo": [Function]\n}'); + expect(stringify({foo: function () {}, bar: 'baz'})).to.equal('{\n "bar": "baz"\n "foo": [Function]\n}'); + }); + + it('should handle functions w/ properties', function () { + var fn = function () {}; + fn.bar = 'baz'; + expect(stringify(fn)).to.equal('{\n "bar": "baz"\n}'); + expect(stringify({foo: fn})).to.equal('{\n "foo": {\n "bar": "baz"\n }\n}'); + }); + + it('should handle undefined values', function () { + expect(stringify({foo: undefined})).to.equal('{\n "foo": [undefined]\n}'); + expect(stringify({foo: 'bar', baz: undefined})).to.equal('{\n "baz": [undefined]\n "foo": "bar"\n}'); + expect(stringify()).to.equal('[undefined]'); + }); + + it('should recurse', function () { + expect(stringify({foo: {bar: {baz: {quux: {herp: 'derp'}}}}})).to.equal('{\n "foo": {\n "bar": {\n "baz": {\n "quux": {\n "herp": "derp"\n }\n }\n }\n }\n}'); + }); + + it('might get confusing', function () { + expect(stringify(null)).to.equal('[null]'); + }); + + it('should not freak out if it sees a primitive twice', function () { + expect(stringify({foo: null, bar: null})).to.equal('{\n "bar": [null]\n "foo": [null]\n}'); + expect(stringify({foo: 1, bar: 1})).to.equal('{\n "bar": 1\n "foo": 1\n}'); + }); + + it('should stringify dates', function () { + var date = new Date(0); + expect(stringify(date)).to.equal('[Date: 1970-01-01T00:00:00.000Z]'); + expect(stringify({date: date})).to.equal('{\n "date": [Date: 1970-01-01T00:00:00.000Z]\n}'); + }); + + it('should handle object without an Object prototype', function () { + var a; + if (Object.create) { + a = Object.create(null); + } else { + a = {}; + } + a.foo = 1; + + expect(stringify(a)).to.equal('{\n "foo": 1\n}'); + }); + + // In old version node.js, Symbol is not available by default. + if (typeof global.Symbol === 'function') { + it('should handle Symbol', function () { + var symbol = Symbol('value'); + expect(stringify(symbol)).to.equal('Symbol(value)'); + expect(stringify({symbol: symbol})).to.equal('{\n "symbol": Symbol(value)\n}'); + }); + } + + it('should handle length properties that cannot be coerced to a number', function () { + expect(stringify({length: {nonBuiltinProperty: 0}})).to.equal('{\n "length": {\n "nonBuiltinProperty": 0\n }\n}'); + expect(stringify({length: 'a string where length should be'})).to.equal('{\n "length": "a string where length should be"\n}'); + }); + }); + + describe('type', function () { + /* eslint no-extend-native: off */ + + var type = utils.type; + var toString = Object.prototype.toString; + + beforeEach(function () { + // some JS engines such as PhantomJS 1.x exhibit this behavior + Object.prototype.toString = function () { + if (this === global) { + return '[object DOMWindow]'; + } + return toString.call(this); + }; + }); + + it('should recognize various types', function () { + expect(type({})).to.equal('object'); + expect(type([])).to.equal('array'); + expect(type(1)).to.equal('number'); + expect(type(Infinity)).to.equal('number'); + expect(type(null)).to.equal('null'); + expect(type(undefined)).to.equal('undefined'); + expect(type(new Date())).to.equal('date'); + expect(type(/foo/)).to.equal('regexp'); + expect(type('type')).to.equal('string'); + expect(type(global)).to.equal('domwindow'); + expect(type(true)).to.equal('boolean'); + }); + + describe('when toString on null or undefined stringifies window', function () { + it('should recognize null and undefined', function () { + expect(type(null)).to.equal('null'); + expect(type(undefined)).to.equal('undefined'); + }); + }); + + afterEach(function () { + Object.prototype.toString = toString; + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser-fixtures/bdd.fixture.js b/tests/lib/mocha-3.1.2/test/browser-fixtures/bdd.fixture.js new file mode 100644 index 0000000000..d19993676a --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser-fixtures/bdd.fixture.js @@ -0,0 +1,6 @@ +'use strict'; + +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('bdd'); diff --git a/tests/lib/mocha-3.1.2/test/browser-fixtures/exports.fixture.js b/tests/lib/mocha-3.1.2/test/browser-fixtures/exports.fixture.js new file mode 100644 index 0000000000..97b8b97cbe --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser-fixtures/exports.fixture.js @@ -0,0 +1,6 @@ +'use strict'; + +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('exports'); diff --git a/tests/lib/mocha-3.1.2/test/browser-fixtures/qunit.fixture.js b/tests/lib/mocha-3.1.2/test/browser-fixtures/qunit.fixture.js new file mode 100644 index 0000000000..a3fd887940 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser-fixtures/qunit.fixture.js @@ -0,0 +1,6 @@ +'use strict'; + +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('qunit'); diff --git a/tests/lib/mocha-3.1.2/test/browser-fixtures/tdd.fixture.js b/tests/lib/mocha-3.1.2/test/browser-fixtures/tdd.fixture.js new file mode 100644 index 0000000000..0c36f0c54b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser-fixtures/tdd.fixture.js @@ -0,0 +1,6 @@ +'use strict'; + +/* eslint-env browser */ + +window.mocha.timeout(200) + .ui('tdd'); diff --git a/tests/lib/mocha-3.1.2/test/browser/array.spec.js b/tests/lib/mocha-3.1.2/test/browser/array.spec.js new file mode 100644 index 0000000000..edf66ac458 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/array.spec.js @@ -0,0 +1,39 @@ +'use strict'; + +describe('Array', function () { + describe('#push()', function () { + it('should append a value', function () { + var arr = []; + arr.push('foo'); + arr.push('bar'); + arr.push('baz'); + assert(arr[0] === 'foo'); // to test indentation + assert(arr[1] === 'bar'); + assert(arr[2] === 'baz'); + }); + + it('should return the length', function () { + var arr = []; + assert(arr.push('foo') === 1); + assert(arr.push('bar') === 2); + assert(arr.push('baz') === 3); + }); + }); +}); + +describe('Array', function () { + describe('#pop()', function () { + it('should remove and return the last value', function () { + var arr = [1, 2, 3]; + assert(arr.pop() === 3); + assert(arr.pop() === 2); + assert(arr.pop() === -1); + }); + + it('should adjust .length', function () { + var arr = [1, 2, 3]; + arr.pop(); + assert(arr.length === 2); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/grep.html b/tests/lib/mocha-3.1.2/test/browser/grep.html new file mode 100644 index 0000000000..0ba47c8533 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/grep.html @@ -0,0 +1,51 @@ +<html> + <head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script>mocha.setup('bdd')</script> + <script> + function assert(expr, msg) { + if (!expr) throw new Error(msg || 'failed'); + } + </script> + <script src="grep.js"></script> + </head> + <body> + <div id="mocha"></div> + <script> + (function(window) { + var location = window.location; + mocha.checkLeaks(); + var runner = mocha.run(); + setTimeout(run, 1000); + + function run() { + var regex = [ + '.*', // All + 'm{2}', // 'mm...m' + '\\d', // Contains number + '^\\d{2}(?=\\s\\d$)', // Start with 2 numbers and end with one + '^@.*(?=\\(\\)$)', // Run @Array and @Function suite, but only function + '^@(?!.*\\)$)', // Run @Array and @Function suite, but only properties + '^co', // Start with 'co' + 'first$', // Ends with 'first' + '^co.*(?=second$)', // Starts with 'co', ends with 'second' + '^Date:\\s01\/0(?:[1-4])\/2015$', // Run all tests between '01/[01-04]/2015' + encodeURIComponent('^#'), // Run encoded => start with '#' + encodeURIComponent('^[^a-z|0-9]+$') // Run encoded => only uppercase suites(include `it` fns), e.g: CONSTANTS + ] + , qs = location.search.replace('?grep=', '') + , re = ~qs.indexOf('%') ? qs : decodeURIComponent(qs) + , grep = regex[regex.indexOf(re) + 1]; + + return grep + ? location.search = 'grep=' + grep + : false; + } + })(window); + </script> + </body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/grep.spec.js b/tests/lib/mocha-3.1.2/test/browser/grep.spec.js new file mode 100644 index 0000000000..6c5a83aeb5 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/grep.spec.js @@ -0,0 +1,110 @@ +'use strict'; + +// numbers +describe('21', function () { + it('1', function () { + assert(true); + }); + it('2', function () { + assert(true); + }); +}); +// symbols +describe('@Array', function () { + it('.pop()', function () { + assert(true); + }); + it('.push()', function () { + assert(true); + }); + it('.length', function () { + assert(true); + }); +}); + +describe('@Function', function () { + it('.call()', function () { + assert(true); + }); + it('.apply()', function () { + assert(true); + }); + it('.length', function () { + assert(true); + }); + it('.name', function () { + assert(true); + }); + it('.prototype', function () { + assert(true); + }); +}); + +// url with hashtags +describe('#Services', function () { + describe('#http', function () { + it('.createClient()', function () { + assert(true); + }); + it('.Server()', function () { + assert(true); + }); + }); + describe('#crypto', function () { + it('.randomBytes()', function () { + assert(true); + }); + it('.Hmac()', function () { + assert(true); + }); + }); +}); + +// Uppercase +describe('CONSTANTS', function () { + it('.STATUS_CODES', function () { + assert(true); + }); +}); + +// Dates +describe('Date:', function () { + it('01/02/2015', function () { + assert(true); + }); + it('01/03/2015', function () { + assert(true); + }); + it('01/06/2015', function () { + assert(true); + }); +}); + +// etc.. +describe('booking/summary', function () { + it('should be run last', function () { + assert(true); + }); +}); + +describe('component/booking/summary', function () { + it('should be run second', function () { + assert(true); + }); +}); + +describe('component/booking/intro', function () { + it('should be run first', function () { + assert(true); + }); +}); + +describe('contains numbers', function () { + it('should run if the number 92 matching', function () { + assert(true); + }); + + it('should run if the number 8 matching', function () { + assert(true); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/index.html b/tests/lib/mocha-3.1.2/test/browser/index.html new file mode 100644 index 0000000000..9200b977e5 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/index.html @@ -0,0 +1,33 @@ +<html> + <head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script>mocha.setup('bdd')</script> + <script> + function assert(expr, msg) { + if (!expr) throw new Error(msg || 'failed'); + } + </script> + <script src="array.js"></script> + <script src="../acceptance/duration.js"></script> + <script src="../acceptance/timeout.js"></script> + <script src="multiple-done.js"></script> + <script> + onload = function(){ + mocha.checkLeaks(); + mocha.globals(['foo']); + var runner = mocha.run(); + + // runner.on('test end', function(test){ + // console.log(test.fullTitle()); + // }); + }; + </script> + </head> + <body> + <div id="mocha"></div> + </body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/large.html b/tests/lib/mocha-3.1.2/test/browser/large.html new file mode 100644 index 0000000000..1804b3a000 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/large.html @@ -0,0 +1,24 @@ +<html> + <head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script>mocha.setup('bdd')</script> + <script> + function assert(expr, msg) { + if (!expr) throw new Error(msg || 'failed'); + } + </script> + <script src="large.js"></script> + <script> + onload = function(){ + mocha.run(); + }; + </script> + </head> + <body> + <div id="mocha"></div> + </body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/large.spec.js b/tests/lib/mocha-3.1.2/test/browser/large.spec.js new file mode 100644 index 0000000000..7dfa62f2a2 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/large.spec.js @@ -0,0 +1,49 @@ +'use strict'; + +var n = 30; +while (n--) { + describe('Array ' + n, function () { + var arr; + + beforeEach(function () { + arr = [1, 2, 3]; + }); + + describe('#indexOf()', function () { + it('should return -1 when the value is not present', function () { + assert(arr.indexOf(5) === -1); + }); + + it('should return the correct index when the value is present', function (done) { + assert(arr.indexOf(1) === 0); + assert(arr.indexOf(2) === 1); + done(); + }); + }); + }); +} + +describe('something', function () { + it('should provide a useful error', function (done) { + setTimeout(function () { + throw new Error('boom'); + }, 1); + }); + + it('should provide an even better error on phantomjs', function (done) { + setTimeout(function () { + var AssertionError = function (message, actual, expected) { + this.message = message; + this.actual = actual; + this.expected = expected; + this.showDiff = true; + }; + AssertionError.prototype = Object.create(Error.prototype); + AssertionError.prototype.name = 'AssertionError'; + AssertionError.prototype.constructor = AssertionError; + + mocha.throwError(new AssertionError('kabooom', 'text with a typo', 'text without a typo')); + done(); + }, 1); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/multiple-done.spec.js b/tests/lib/mocha-3.1.2/test/browser/multiple-done.spec.js new file mode 100644 index 0000000000..ddb536735e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/multiple-done.spec.js @@ -0,0 +1,18 @@ +'use strict'; + +describe('Multiple Done calls', function () { + it('should report an error if done was called more than once', function (done) { + done(); + done(); + }); + + it('should report an error if an exception happened async after done was called', function (done) { + done(); + setTimeout(done, 50); + }); + + it('should report an error if an exception happened after done was called', function (done) { + done(); + throw new Error('thrown error'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/opts.html b/tests/lib/mocha-3.1.2/test/browser/opts.html new file mode 100644 index 0000000000..ec49a418fc --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/opts.html @@ -0,0 +1,30 @@ +<html> + <head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script> + mocha.setup({ + ui: 'bdd', + globals: ['okGlobalA', 'okGlobalB', 'okGlobalC', 'callback*'] + }).timeout(1500) + </script> + <script> + function assert(expr, msg) { + if (!expr) throw new Error(msg || 'failed'); + } + </script> + <script src="opts.js"></script> + <script src="../acceptance/globals.js"></script> + <script> + onload = function(){ + var runner = mocha.run(); + }; + </script> + </head> + <body> + <div id="mocha"></div> + </body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/opts.spec.js b/tests/lib/mocha-3.1.2/test/browser/opts.spec.js new file mode 100644 index 0000000000..7b93f22615 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/opts.spec.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('Options', function () { + it('should set timeout value', function () { + assert(this.test._timeout === 1500); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/stack-trace.html b/tests/lib/mocha-3.1.2/test/browser/stack-trace.html new file mode 100644 index 0000000000..0f267dab98 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/stack-trace.html @@ -0,0 +1,24 @@ +<html> +<head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script>mocha.setup('bdd')</script> + <script> + function assert(expr, err) { + if (!expr) throw err; + } + </script> + <script src="stack-trace.js"></script> + <script> + onload = function() { + mocha.run(); + }; + </script> +</head> +<body> +<div id="mocha"></div> +</body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/stack-trace.spec.js b/tests/lib/mocha-3.1.2/test/browser/stack-trace.spec.js new file mode 100644 index 0000000000..a4801bf32f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/stack-trace.spec.js @@ -0,0 +1,22 @@ +'use strict'; +describe('Stack trace', function () { + it('should prettify the stack-trace', function () { + var err = new Error(); + // We do this fake stack-trace because we under development, + // and our root isn't `node_modules`, `bower` or `components` + err.stack = [ + 'Error: failed', + 'at assert (stack-trace.html:11:30)', + 'at Context.<anonymous> (stack-trace.js:5:5)', + 'at callFn (http://localhost:63342/node_modules/mocha.js:4546:21)', + 'at Test.require.register.Runnable.run (http://localhost:63342/node_modules/mocha.js:4539:7)', + 'at Runner.require.register.Runner.runTest (http://localhost:63342/node_modules/mocha.js:4958:10)', + 'at http://localhost:63342/bower_components/mocha.js:5041:12', + 'at next (http://localhost:63342/bower_components/mocha.js:4883:14)', + 'at http://localhost:63342/bower_components/mocha.js:4893:7', + 'at next (http://localhost:63342/bower_components/mocha.js:4828:23)', + 'at http://localhost:63342/bower_components/mocha.js:4860:5' + ].join('\n'); + assert(false, err); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/browser/ui.html b/tests/lib/mocha-3.1.2/test/browser/ui.html new file mode 100644 index 0000000000..071c7798a0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/ui.html @@ -0,0 +1,46 @@ +<html> + <head> + <title>Mocha</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <link rel="stylesheet" href="../../mocha.css" /> + <script src="../../mocha.js"></script> + <script>mocha.setup('bdd')</script> + <script> + function assert(expr, msg) { + if (!expr) throw new Error(msg || 'failed'); + } + </script> + <script src="ui.js"></script> + </head> + <body> + <div id="mocha"></div> + <script> + (function(window) { + var location = window.location; + mocha.checkLeaks(); + var runner = mocha.run(); + var count = 0; + setTimeout(run, 1000); + + function run() { + var regex = [ + '', // All + '%5C%24%5C.jQuery', // $.jQuery + '%5C%24%5C.jQuery%20%5C.on%5C(%5C)', // $.jQuery .on() + ] + , qs = location.search.replace('?grep=', '') + , re = ~qs.indexOf('%') ? qs : decodeURIComponent(qs) + , grep = regex[regex.indexOf(re) + 1] + , anchors = document.getElementsByTagName('a'); + + // Locate first 'a' element w/ matching grep param; click it + for (var i = 0; i < anchors.length; i++) { + if (anchors[i].href && anchors[i].href.indexOf(grep) > -1) + return void anchors[i].click(); + } + } + })(window); + </script> + </body> +</html> diff --git a/tests/lib/mocha-3.1.2/test/browser/ui.spec.js b/tests/lib/mocha-3.1.2/test/browser/ui.spec.js new file mode 100644 index 0000000000..159cab6d95 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/browser/ui.spec.js @@ -0,0 +1,33 @@ +'use strict'; + +// test titles containing regex-conflicting characters + +// leading $ +describe('$.jQuery', function () { + // parens + describe('.on()', function () { + it('should set an event', function () { + assert(true); + }); + }); + + describe('.off()', function () { + it('should remove an event', function () { + + }); + }); +}); + +// another generic describe block to verify it is absent +// when greeping on $.jQuery +describe('@Array', function () { + it('.pop()', function () { + assert(true); + }); + it('.push()', function () { + assert(true); + }); + it('.length', function () { + assert(true); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/color.spec.js b/tests/lib/mocha-3.1.2/test/color.spec.js new file mode 100644 index 0000000000..bffd30e6eb --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/color.spec.js @@ -0,0 +1,20 @@ +'use strict'; + +var assert = require('assert'); +var childProcess = require('child_process'); +var path = require('path'); + +describe('Mocha', function () { + this.timeout(2000); + + it('should not output colors to pipe', function (cb) { + var command = [path.join('bin', 'mocha'), '--grep', 'missing-test']; + childProcess.execFile(process.execPath, command, function (err, stdout, stderr) { + if (err) return cb(err); + + assert(stdout.indexOf('[90m') === -1); + + cb(null); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/compiler/foo.js b/tests/lib/mocha-3.1.2/test/compiler/foo.js new file mode 100644 index 0000000000..753d08e740 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/compiler/foo.js @@ -0,0 +1,10 @@ +'use strict'; + +var fs = require('fs'); +require.extensions['.foo'] = function (module, filename) { + var content; + content = fs.readFileSync(filename, 'utf8'); + var test = 'describe("custom compiler",function(){ it("should work",function() { ' + + content + '.should.eql(1); }); });'; + return module._compile(test, filename); +}; diff --git a/tests/lib/mocha-3.1.2/test/grep.spec.js b/tests/lib/mocha-3.1.2/test/grep.spec.js new file mode 100644 index 0000000000..dd21cf0090 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/grep.spec.js @@ -0,0 +1,67 @@ +'use strict'; + +var Mocha = require('../'); + +describe('Mocha', function () { + describe('"grep" option', function () { + it('should add a RegExp to the mocha.options object', function () { + var mocha = new Mocha({ grep: /foo.*/ }); + mocha.options.grep.toString().should.equal('/foo.*/'); + }); + + it('should convert string to a RegExp', function () { + var mocha = new Mocha({ grep: 'foo.*' }); + mocha.options.grep.toString().should.equal('/foo.*/'); + }); + }); + + describe('"fgrep" option', function () { + it('should escape and convert string to a RegExp', function () { + var mocha = new Mocha({ fgrep: 'foo.*' }); + mocha.options.grep.toString().should.equal('/foo\\.\\*/'); + }); + }); + + describe('.grep()', function () { + // Test helper + function testGrep (mocha) { + return function testGrep (grep, expected) { + mocha.grep(grep); + mocha.options.grep.toString().should.equal(expected); + }; + } + + it('should add a RegExp to the mocha.options object', function () { + var test = testGrep(new Mocha()); + test(/foo/, '/foo/'); + }); + + it('should convert grep string to a RegExp', function () { + var test = testGrep(new Mocha()); + test('foo', '/foo/'); + test('^foo.*bar$', '/^foo.*bar$/'); + test('^@.*(?=\\(\\)$)', '/^@.*(?=\\(\\)$)/'); + }); + + it('should covert grep regex-like string to a RegExp', function () { + var test = testGrep(new Mocha()); + test('/foo/', '/foo/'); + // Keep the flags + test('/baz/i', '/baz/i'); + test('/bar/g', '/bar/g'); + test('/^foo(.*)bar/g', '/^foo(.*)bar/g'); + }); + + it('should return it\'s parent Mocha object for chainability', function () { + var mocha = new Mocha(); + mocha.grep().should.equal(mocha); + }); + }); + + describe('"invert" option', function () { + it('should add a Boolean to the mocha.options object', function () { + var mocha = new Mocha({ invert: true }); + mocha.options.invert.should.be.ok; + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/hook-async.spec.js b/tests/lib/mocha-3.1.2/test/hook-async.spec.js new file mode 100644 index 0000000000..a03821e32c --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/hook-async.spec.js @@ -0,0 +1,135 @@ +'use strict'; + +describe('async', function () { + var calls = []; + + before(function () { + calls.push('root before all'); + }); + + after(function () { + calls.push('root after all'); + calls.should.eql([ + 'root before all', + 'before all', + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two', + 'two', + 'after', + 'after test two passed', + 'parent after', + 'parent before', + 'before', + 'before test three', + 'three', + 'after', + 'after test three passed', + 'parent after', + 'after all', + 'root after all' + ]); + }); + + beforeEach(function () { + calls.push('parent before'); + }); + + afterEach(function () { + calls.push('parent after'); + }); + + describe('hooks', function () { + before(function () { + calls.push('before all'); + }); + + after(function () { + calls.push('after all'); + }); + + beforeEach(function (done) { + var ctx = this; + process.nextTick(function () { + calls.push('before'); + if (ctx.currentTest) { + calls.push('before test ' + ctx.currentTest.title); + } + done(); + }); + }); + + it('one', function (done) { + calls.should.eql([ + 'root before all', + 'before all', + 'parent before', + 'before', + 'before test one' + ]); + calls.push('one'); + process.nextTick(done); + }); + + it('two', function () { + calls.should.eql([ + 'root before all', + 'before all', + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two' + ]); + calls.push('two'); + }); + + it('three', function () { + calls.should.eql([ + 'root before all', + 'before all', + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two', + 'two', + 'after', + 'after test two passed', + 'parent after', + 'parent before', + 'before', + 'before test three' + ]); + calls.push('three'); + }); + + afterEach(function (done) { + var ctx = this; + process.nextTick(function () { + calls.push('after'); + if (ctx.currentTest) { + calls.push('after test ' + ctx.currentTest.title + ' ' + ctx.currentTest.state); + } + done(); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/hook-sync-nested.spec.js b/tests/lib/mocha-3.1.2/test/hook-sync-nested.spec.js new file mode 100644 index 0000000000..3f1929f547 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/hook-sync-nested.spec.js @@ -0,0 +1,104 @@ +'use strict'; + +describe('serial', function () { + describe('nested', function () { + var calls = []; + + beforeEach(function () { + calls.push('parent before'); + if (this.currentTest) { + calls.push('parent before test ' + this.currentTest.title); + } + }); + + afterEach(function () { + calls.push('parent after'); + if (this.currentTest) { + calls.push('parent after test ' + this.currentTest.title + ' ' + this.currentTest.state); + } + }); + + it('foo', function () { + calls.should.eql([ + 'parent before', + 'parent before test foo' + ]); + calls.push('foo'); + }); + + it('bar', function () { + calls.should.eql([ + 'parent before', + 'parent before test foo', + 'foo', + 'parent after', + 'parent after test foo passed', + 'parent before', + 'parent before test bar' + ]); + }); + + describe('hooks', function () { + beforeEach(function () { + calls.push('before'); + if (this.currentTest) { + calls.push('before test ' + this.currentTest.title); + } + }); + + it('one', function () { + calls.should.eql([ + 'parent before', + 'parent before test foo', + 'foo', + 'parent after', + 'parent after test foo passed', + 'parent before', + 'parent before test bar', + 'parent after', + 'parent after test bar passed', + 'parent before', + 'parent before test one', + 'before', + 'before test one' + ]); + calls.push('one'); + }); + + it('two', function () { + calls.should.eql([ + 'parent before', + 'parent before test foo', + 'foo', + 'parent after', + 'parent after test foo passed', + 'parent before', + 'parent before test bar', + 'parent after', + 'parent after test bar passed', + 'parent before', + 'parent before test one', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent after test one passed', + 'parent before', + 'parent before test two', + 'before', + 'before test two' + ]); + calls.push('two'); + }); + + afterEach(function () { + calls.push('after'); + if (this.currentTest) { + calls.push('after test ' + this.currentTest.title + ' ' + this.currentTest.state); + } + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/hook-sync.spec.js b/tests/lib/mocha-3.1.2/test/hook-sync.spec.js new file mode 100644 index 0000000000..b1138a6db8 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/hook-sync.spec.js @@ -0,0 +1,103 @@ +'use strict'; + +describe('serial', function () { + var calls = []; + + beforeEach(function () { + calls.push('parent before'); + }); + + afterEach(function () { + calls.push('parent after'); + }); + + describe('hooks', function () { + beforeEach(function () { + calls.push('before'); + if (this.currentTest) { + calls.push('before test ' + this.currentTest.title); + } + }); + + it('one', function () { + calls.should.eql([ + 'parent before', + 'before', + 'before test one' + ]); + calls.push('one'); + }); + + it('two', function () { + calls.should.eql([ + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two' + ]); + calls.push('two'); + }); + + it('three', function () { + calls.should.eql([ + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two', + 'two', + 'after', + 'after test two passed', + 'parent after', + 'parent before', + 'before', + 'before test three' + ]); + calls.push('three'); + }); + + afterEach(function () { + calls.push('after'); + if (this.currentTest) { + calls.push('after test ' + this.currentTest.title + ' ' + this.currentTest.state); + } + }); + + after(function () { + calls.should.eql([ + 'parent before', + 'before', + 'before test one', + 'one', + 'after', + 'after test one passed', + 'parent after', + 'parent before', + 'before', + 'before test two', + 'two', + 'after', + 'after test two passed', + 'parent after', + 'parent before', + 'before', + 'before test three', + 'three', + 'after', + 'after test three passed', + 'parent after' + ]); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/hook-timeout.spec.js b/tests/lib/mocha-3.1.2/test/hook-timeout.spec.js new file mode 100644 index 0000000000..c16c3011fb --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/hook-timeout.spec.js @@ -0,0 +1,10 @@ +'use strict'; + +before(function (done) { + this.timeout(100); + setTimeout(done, 50); +}); + +it('should work', function (done) { + done(); +}); diff --git a/tests/lib/mocha-3.1.2/test/http-meta-2.spec.js b/tests/lib/mocha-3.1.2/test/http-meta-2.spec.js new file mode 100644 index 0000000000..4530969041 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/http-meta-2.spec.js @@ -0,0 +1,92 @@ +'use strict'; + +var http = require('http'); + +var PORT = 8899; + +var server = http.createServer(function (req, res) { + var accept = req.headers.accept || ''; + var json = ~accept.indexOf('json'); + + switch (req.url) { + case '/': + res.end('hello'); + break; + case '/users': + if (json) { + res.end('["tobi","loki","jane"]'); + } else { + res.end('tobi, loki, jane'); + } + break; + } +}); + +function get (url) { + var fields; + var expected; + var header = {}; + + function request (done) { + http.get({ path: url, port: PORT, headers: header }, function (res) { + var buf = ''; + res.should.have.property('statusCode', 200); + res.setEncoding('utf8'); + res.on('data', function (chunk) { buf += chunk; }); + res.on('end', function () { + buf.should.equal(expected); + done(); + }); + }); + } + + return { + set: function (field, val) { + header[field] = val; + return this; + }, + + should: { + respond: function (body) { + fields = Object.keys(header).map(function (field) { + return field + ': ' + header[field]; + }).join(', '); + + expected = body; + describe('GET ' + url, function () { + this.timeout(500); + if (fields) { + describe('when given ' + fields, function () { + it('should respond with "' + body + '"', request); + }); + } else { + it('should respond with "' + body + '"', request); + } + }); + } + } + }; +} + +describe('http server', function () { + before(function (done) { + server.listen(PORT, done); + }); + + after(function () { + server.close(); + }); + + get('/') + .should + .respond('hello'); + + get('/users') + .should + .respond('tobi, loki, jane'); + + get('/users') + .set('Accept', 'application/json') + .should + .respond('["tobi","loki","jane"]'); +}); diff --git a/tests/lib/mocha-3.1.2/test/http-meta.spec.js b/tests/lib/mocha-3.1.2/test/http-meta.spec.js new file mode 100644 index 0000000000..c92dbd2307 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/http-meta.spec.js @@ -0,0 +1,65 @@ +'use strict'; + +var http = require('http'); + +var PORT = 8889; + +var server = http.createServer(function (req, res) { + var accept = req.headers.accept || ''; + var json = ~accept.indexOf('json'); + + switch (req.url) { + case '/': + res.end('hello'); + break; + case '/users': + if (json) { + res.end('["tobi","loki","jane"]'); + } else { + res.end('tobi, loki, jane'); + } + break; + } +}); + +function get (url, body, header) { + return function (done) { + http.get({ + path: url, + port: PORT, + headers: header || {} + }, function (res) { + var buf = ''; + res.should.have.property('statusCode', 200); + res.setEncoding('utf8'); + res.on('data', function (chunk) { buf += chunk; }); + res.on('end', function () { + buf.should.equal(body); + done(); + }); + }); + }; +} + +describe('http requests', function () { + before(function (done) { + server.listen(PORT, done); + }); + + after(function () { + server.close(); + }); + + describe('GET /', function () { + it('should respond with hello', + get('/', 'hello')); + }); + + describe('GET /users', function () { + it('should respond with users', + get('/users', 'tobi, loki, jane')); + + it('should respond with users', + get('/users', '["tobi","loki","jane"]', { Accept: 'application/json' })); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/diffs.spec.js b/tests/lib/mocha-3.1.2/test/integration/diffs.spec.js new file mode 100644 index 0000000000..7d620e7489 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/diffs.spec.js @@ -0,0 +1,46 @@ +'use strict'; + +var assert = require('assert'); +var helpers = require('./helpers'); +var run = helpers.runMocha; +var fs = require('fs'); +var getDiffs = helpers.getDiffs; + +function getExpectedOutput () { + var output = fs.readFileSync('test/integration/fixtures/diffs/output', 'UTF8'); + + // Diffs are delimited in file by "// DIFF" + return output.split(/\s*\/\/ DIFF/).slice(1).map(function (diff) { + return diff.split('\n').filter(Boolean).join('\n'); + }); +} + +describe('diffs', function () { + var diffs, expected; + + before(function (done) { + run('diffs/diffs.fixture.js', ['-C'], function (err, res) { + expected = getExpectedOutput(); + diffs = getDiffs(res.output); + done(err); + }); + }); + + [ + 'should display a diff for small strings', + 'should display a diff of canonicalized objects', + 'should display a diff for medium strings', + 'should display a diff for entire object dumps', + 'should display a diff for multi-line strings', + 'should display a diff for entire object dumps', + 'should display a full-comparison with escaped special characters', + 'should display a word diff for large strings', + 'should work with objects', + 'should show value diffs and not be affected by commas', + 'should display diff by data and not like an objects' + ].forEach(function (title, i) { + it(title, function () { + assert.equal(diffs[i], expected[i]); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/cascade.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/cascade.fixture.js new file mode 100644 index 0000000000..259c81af2d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/cascade.fixture.js @@ -0,0 +1,59 @@ +'use strict'; + +describe('one', function () { + before(function () { + console.log('before one'); + }); + + after(function () { + console.log('after one'); + }); + + beforeEach(function () { + console.log(' before each one'); + }); + + afterEach(function () { + console.log(' after each one'); + }); + + describe('two', function () { + before(function () { + console.log(' before two'); + }); + + after(function () { + console.log(' after two'); + }); + + beforeEach(function () { + console.log(' before each two'); + }); + + afterEach(function () { + console.log(' after each two'); + }); + + describe('three', function () { + before(function () { + console.log(' before three'); + }); + + after(function () { + console.log(' after three'); + }); + + beforeEach(function () { + console.log(' before each three'); + }); + + afterEach(function () { + console.log(' after each three'); + }); + + it('should three', function () { + console.log(' TEST three'); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.in b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.in new file mode 100644 index 0000000000..09a3ca5363 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.in @@ -0,0 +1,9 @@ +body { + font: "Helvetica Neue", Helvetica, arial, sans-serif; + background: black; + color: white; +} + +a { + color: blue +} diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.out b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.out new file mode 100644 index 0000000000..53b3ec906e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.css.out @@ -0,0 +1,13 @@ +body { + font: "Helvetica Neue", Helvetica, arial, sans-serif; + background: black; + color: #fff; +} + +a { + color: blue; +} + +foo { + bar: 'baz'; +} diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.fixture.js new file mode 100644 index 0000000000..50ea00bee0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/diffs.fixture.js @@ -0,0 +1,113 @@ +'use strict'; + +var fs = require('fs'); +var cssin = fs.readFileSync('test/integration/fixtures/diffs/diffs.css.in', 'ascii'); +var cssout = fs.readFileSync('test/integration/fixtures/diffs/diffs.css.out', 'ascii'); + +describe('diffs', function () { + var actual, expected; + + it('should display a diff for small strings', function () { + actual = 'foo rar baz'; + expected = 'foo bar baz'; + actual.should.equal(expected); + }); + + it('should display a diff of canonicalized objects', function () { + actual = { name: 'travis j', age: 23 }; + expected = { age: 23, name: 'travis' }; + actual.should.equal(expected); + }); + + it('should display a diff for medium strings', function () { + actual = 'foo bar baz\nfoo rar baz\nfoo bar raz'; + expected = 'foo bar baz\nfoo bar baz\nfoo bar baz'; + actual.should.equal(expected); + }); + + it('should display a diff for entire object dumps', function () { + actual = { + name: 'joel', + age: 30, + address: { + city: 'new york', + country: 'usa' + } + }; + expected = { + name: 'joe', + age: 30, + address: { + city: 'new york', + country: 'us' + } + }; + actual.should.equal(expected); + }); + + it('should display a diff for multi-line strings', function () { + actual = 'one two three\nfour zzzz six\nseven eight nine'; + expected = 'one two three\nfour five six\nseven eight nine'; + actual.should.equal(expected); + }); + + it('should display a diff for entire object dumps', function () { + actual = { + name: 'joel', + age: 30, + address: { + city: 'new york', + country: 'usa' + } + }; + expected = { + name: 'joe', + age: 30, + address: { + city: 'new york', + country: 'us' + } + }; + actual.should.equal(expected); + }); + + it('should display a full-comparison with escaped special characters', function () { + actual = 'one\ttab\ntwo\t\t\ttabs'; + expected = 'one\ttab\ntwo\t\ttabs'; + actual.should.equal(expected); + }); + + it('should display a word diff for large strings', function () { + cssin.should.equal(cssout); + }); + + it('should work with objects', function () { + actual = { + name: 'tobi', + species: 'ferret', + color: 'white', + age: 2 + }; + + expected = { + name: 'loki', + species: 'ferret', + color: 'brown', + age: 2 + }; + + actual.should.eql(expected); + }); + + it('should show value diffs and not be affected by commas', function () { + actual = { a: 123 }; + expected = { a: 123, b: 456 }; + actual.should.equal(expected); + }); + + it('should display diff by data and not like an objects', function () { + actual = new Buffer([0x01]); + expected = new Buffer([0x02]); + actual.should.equal(expected); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/output b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/output new file mode 100644 index 0000000000..bf56a96397 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/diffs/output @@ -0,0 +1,91 @@ +// DIFF + -foo rar baz + +foo bar baz + +// DIFF + { + "age": 23 + - "name": "travis j" + + "name": "travis" + } + +// DIFF + foo bar baz + -foo rar baz + -foo bar raz + +foo bar baz + +foo bar baz + +// DIFF + { + "address": { + "city": "new york" + - "country": "usa" + + "country": "us" + } + "age": 30 + - "name": "joel" + + "name": "joe" + } + +// DIFF + one two three + -four zzzz six + +four five six + seven eight nine + +// DIFF + { + "address": { + "city": "new york" + - "country": "usa" + + "country": "us" + } + "age": 30 + - "name": "joel" + + "name": "joe" + } + +// DIFF + one tab + -two tabs + +two tabs + +// DIFF + body { + font: "Helvetica Neue", Helvetica, arial, sans-serif; + background: black; + - color: white; + + color: #fff; + } + + a { + - color: blue + + color: blue; + } + + + +foo { + + bar: 'baz'; + +} + +// DIFF + { + "age": 2 + - "color": "white" + - "name": "tobi" + + "color": "brown" + + "name": "loki" + "species": "ferret" + } + +// DIFF + { + "a": 123 + + "b": 456 + } + +// DIFF + [ + - 1 + + 2 + ] diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-async-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-async-error.fixture.js new file mode 100644 index 0000000000..f3dfe7e1ae --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-async-error.fixture.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('spec 1', function () { + after(function (done) { + console.log('after'); + process.nextTick(function () { + throw new Error('after hook error'); + }); + }); + it('should be called because error is in after hook', function () { + console.log('test 1'); + }); + it('should be called because error is in after hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-error.fixture.js new file mode 100644 index 0000000000..7fc258f46d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/after-hook-error.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('spec 1', function () { + after(function () { + console.log('after'); + throw new Error('after hook error'); + }); + it('should be called because error is in after hook', function () { + console.log('test 1'); + }); + it('should be called because error is in after hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-async-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-async-error.fixture.js new file mode 100644 index 0000000000..442ad9321f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-async-error.fixture.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('spec 1', function () { + afterEach(function (done) { + console.log('after'); + process.nextTick(function () { + throw new Error('after each hook error'); + }); + }); + it('should be called because error is in after each hook', function () { + console.log('test 1'); + }); + it('should not be called', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-error.fixture.js new file mode 100644 index 0000000000..5fb9a36c8d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/afterEach-hook-error.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('spec 1', function () { + afterEach(function () { + console.log('after'); + throw new Error('after each hook error'); + }); + it('should be called because error is in after each hook', function () { + console.log('test 1'); + }); + it('should not be called', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js new file mode 100644 index 0000000000..04801c1946 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error-tip.fixture.js @@ -0,0 +1,13 @@ +'use strict'; + +describe('spec 1', function () { + it('should not blame me', function () { }); +}); +describe('spec 2', function () { + before(function (done) { + process.nextTick(function () { + throw new Error('before hook error'); + }); + }); + it('skipped'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error.fixture.js new file mode 100644 index 0000000000..2530eec783 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-async-error.fixture.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('spec 1', function () { + before(function (done) { + console.log('before'); + process.nextTick(function () { + throw new Error('before hook error'); + }); + }); + it('should not be called because of error in before hook', function () { + console.log('test 1'); + }); + it('should not be called because of error in before hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error-tip.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error-tip.fixture.js new file mode 100644 index 0000000000..64df731573 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error-tip.fixture.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('spec 1', function () { + it('should not blame me', function () { }); +}); +describe('spec 2', function () { + before(function () { + throw new Error('before hook error'); + }); + it('skipped'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error.fixture.js new file mode 100644 index 0000000000..547e54a243 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/before-hook-error.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('spec 1', function () { + before(function () { + console.log('before'); + throw new Error('before hook error'); + }); + it('should not be called because of error in before hook', function () { + console.log('test 1'); + }); + it('should not be called because of error in before hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-async-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-async-error.fixture.js new file mode 100644 index 0000000000..6ce27784a6 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-async-error.fixture.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('spec 1', function () { + beforeEach(function (done) { + console.log('before'); + process.nextTick(function () { + throw new Error('before each hook error'); + }); + }); + it('should not be called because of error in before each hook', function () { + console.log('test 1'); + }); + it('should not be called because of error in before each hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-error.fixture.js new file mode 100644 index 0000000000..4c0ab2f237 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/beforeEach-hook-error.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('spec 1', function () { + beforeEach(function () { + console.log('before'); + throw new Error('before each hook error'); + }); + it('should not be called because of error in before each hook', function () { + console.log('test 1'); + }); + it('should not be called because of error in before each hook', function () { + console.log('test 2'); + }); +}); +describe('spec 2', function () { + it('should be called, because hook error was in a sibling suite', function () { + console.log('test 3'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-async-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-async-error.fixture.js new file mode 100644 index 0000000000..858bbb3c5e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-async-error.fixture.js @@ -0,0 +1,141 @@ +'use strict'; + +before(function () { + console.log('root before'); +}); +beforeEach(function () { + console.log('root before each'); +}); +describe('1', function () { + beforeEach(function () { + console.log('1 before each'); + }); + + describe('1-1', function () { + before(function () { + console.log('1-1 before'); + }); + beforeEach(function (done) { + console.log('1-1 before each'); + process.nextTick(function () { + throw new Error('1-1 before each hook failed'); + }); + }); + it('1-1 test 1', function () { + console.log('1-1 test 1'); + }); + it('1-1 test 2', function () { + console.log('1-1 test 2'); + }); + afterEach(function () { + console.log('1-1 after each'); + }); + after(function (done) { + console.log('1-1 after'); + process.nextTick(function () { + throw new Error('1-1 after hook failed'); + }); + }); + }); + + describe('1-2', function () { + before(function () { + console.log('1-2 before'); + }); + beforeEach(function () { + console.log('1-2 before each'); + }); + it('1-2 test 1', function () { + console.log('1-2 test 1'); + }); + it('1-2 test 2', function () { + console.log('1-2 test 2'); + }); + afterEach(function (done) { + console.log('1-2 after each'); + process.nextTick(function () { + throw new Error('1-2 after each hook failed'); + }); + }); + after(function () { + console.log('1-2 after'); + }); + }); + + afterEach(function () { + console.log('1 after each'); + }); + + after(function () { + console.log('1 after'); + }); +}); + +describe('2', function () { + beforeEach(function (done) { + console.log('2 before each'); + process.nextTick(function () { + throw new Error('2 before each hook failed'); + }); + }); + + describe('2-1', function () { + before(function () { + console.log('2-1 before'); + }); + beforeEach(function () { + console.log('2-1 before each'); + }); + it('2-1 test 1', function () { + console.log('2-1 test 1'); + }); + it('2-1 test 2', function () { + console.log('2-1 test 2'); + }); + afterEach(function () { + console.log('2-1 after each'); + }); + after(function () { + console.log('2-1 after'); + }); + }); + + describe('2-2', function () { + before(function () { + console.log('2-2 before'); + }); + beforeEach(function () { + console.log('2-2 before each'); + }); + it('2-2 test 1', function () { + console.log('2-2 test 1'); + }); + it('2-2 test 2', function () { + console.log('2-2 test 2'); + }); + afterEach(function () { + console.log('2-2 after each'); + }); + after(function () { + console.log('2-2 after'); + }); + }); + + afterEach(function (done) { + console.log('2 after each'); + process.nextTick(function () { + throw new Error('2 after each hook failed'); + }); + }); + + after(function () { + console.log('2 after'); + }); +}); + +after(function () { + console.log('root after'); +}); +afterEach(function () { + console.log('root after each'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-error.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-error.fixture.js new file mode 100644 index 0000000000..085978ef79 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/hooks/multiple-hook-error.fixture.js @@ -0,0 +1,131 @@ +'use strict'; + +before(function () { + console.log('root before'); +}); +beforeEach(function () { + console.log('root before each'); +}); +describe('1', function () { + beforeEach(function () { + console.log('1 before each'); + }); + + describe('1-1', function () { + before(function () { + console.log('1-1 before'); + }); + beforeEach(function () { + console.log('1-1 before each'); + throw new Error('1-1 before each hook failed'); + }); + it('1-1 test 1', function () { + console.log('1-1 test 1'); + }); + it('1-1 test 2', function () { + console.log('1-1 test 2'); + }); + afterEach(function () { + console.log('1-1 after each'); + }); + after(function () { + console.log('1-1 after'); + throw new Error('1-1 after hook failed'); + }); + }); + + describe('1-2', function () { + before(function () { + console.log('1-2 before'); + }); + beforeEach(function () { + console.log('1-2 before each'); + }); + it('1-2 test 1', function () { + console.log('1-2 test 1'); + }); + it('1-2 test 2', function () { + console.log('1-2 test 2'); + }); + afterEach(function () { + console.log('1-2 after each'); + throw new Error('1-2 after each hook failed'); + }); + after(function () { + console.log('1-2 after'); + }); + }); + + afterEach(function () { + console.log('1 after each'); + }); + + after(function () { + console.log('1 after'); + }); +}); + +describe('2', function () { + beforeEach(function () { + console.log('2 before each'); + throw new Error('2 before each hook failed'); + }); + + describe('2-1', function () { + before(function () { + console.log('2-1 before'); + }); + beforeEach(function () { + console.log('2-1 before each'); + }); + it('2-1 test 1', function () { + console.log('2-1 test 1'); + }); + it('2-1 test 2', function () { + console.log('2-1 test 2'); + }); + afterEach(function () { + console.log('2-1 after each'); + }); + after(function () { + console.log('2-1 after'); + }); + }); + + describe('2-2', function () { + before(function () { + console.log('2-2 before'); + }); + beforeEach(function () { + console.log('2-2 before each'); + }); + it('2-2 test 1', function () { + console.log('2-2 test 1'); + }); + it('2-2 test 2', function () { + console.log('2-2 test 2'); + }); + afterEach(function () { + console.log('2-2 after each'); + }); + after(function () { + console.log('2-2 after'); + }); + }); + + afterEach(function () { + console.log('2 after each'); + throw new Error('2 after each hook failed'); + }); + + after(function () { + console.log('2 after'); + }); +}); + +after(function () { + console.log('root after'); +}); +afterEach(function () { + console.log('root after each'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-before.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-before.fixture.js new file mode 100644 index 0000000000..1e1bc71a16 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-before.fixture.js @@ -0,0 +1,12 @@ +'use strict'; + +describe('suite', function () { + before(function (done) { + setTimeout(done, 10); + setTimeout(done, 30); + }); + + it('test1', function (done) { + setTimeout(done, 50); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-beforeEach.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-beforeEach.fixture.js new file mode 100644 index 0000000000..32de2bf442 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-beforeEach.fixture.js @@ -0,0 +1,16 @@ +'use strict'; + +describe('suite', function () { + beforeEach(function (done) { + setTimeout(done, 10); + setTimeout(done, 20); + }); + + it('test1', function (done) { + setTimeout(done, 50); + }); + + it('test2', function (done) { + setTimeout(done, 50); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-specs.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-specs.fixture.js new file mode 100644 index 0000000000..a8ae6d1ac4 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done-specs.fixture.js @@ -0,0 +1,12 @@ +'use strict'; + +describe('suite', function () { + it('test1', function (done) { + done(); + setTimeout(done, 10); + }); + + it('test2', function (done) { + setTimeout(done, 20); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done.fixture.js new file mode 100644 index 0000000000..f1b471c678 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/multiple-done.fixture.js @@ -0,0 +1,20 @@ +'use strict'; + +// The suite below should result in an additional error, but does +// not. Uncomment once this bug is resolved. + +// describe('suite', function() { +// beforeEach(function(done) { +// done(); +// done(); +// }); + +// it('test', function() {}); +// }); + +it('should fail in a test-case', function (done) { + process.nextTick(function () { + done(); + done(); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-async.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-async.fixture.js new file mode 100644 index 0000000000..d5ba2b37a0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-async.fixture.js @@ -0,0 +1,5 @@ +'use strict'; + +it('should pass', function (done) { + done(); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-sync.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-sync.fixture.js new file mode 100644 index 0000000000..512fd0e4db --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/async-only-sync.fixture.js @@ -0,0 +1,3 @@ +'use strict'; + +it('throws an error', function () {}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/bail.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/bail.fixture.js new file mode 100644 index 0000000000..5095e63158 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/bail.fixture.js @@ -0,0 +1,23 @@ +'use strict'; + +describe('suite1', function () { + it('should display this spec', function () {}); + + it('should only display this error', function (done) { + throw new Error('this should be displayed'); + }); + + it('should not display this error', function (done) { + throw new Error('this should not be displayed'); + }); +}); + +describe('suite2', function () { + before(function (done) { + throw new Error('this hook should not be displayed'); + }); + + it('should not display this error', function (done) { + throw new Error('this should not be displayed'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay-fail.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay-fail.fixture.js new file mode 100644 index 0000000000..644cbc0281 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay-fail.fixture.js @@ -0,0 +1,8 @@ +'use strict'; + +setTimeout(function () { + throw new Error('oops'); + /* eslint no-unreachable: off */ + it('test', function () {}); + run(); +}, 100); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay.fixture.js new file mode 100644 index 0000000000..b2d49217db --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/delay.fixture.js @@ -0,0 +1,16 @@ +'use strict'; + +var assert = require('assert'); +var delay = 500; + +setTimeout(function () { + describe('delayed execution', function () { + it('should have no effect if attempted twice in the same suite', function () { + assert(true); + run(); + assert(true); + }); + }); + + run(); +}, delay); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/grep.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/grep.fixture.js new file mode 100644 index 0000000000..0939d084ec --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/grep.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('grep', function () { + describe('Match', function () { + it('should run', function () {}); + it('should also run', function () {}); + }); + + describe('match', function () { + it('should run', function () {}); + it('should also run', function () {}); + }); + + describe('fail', function () { + it('should not be ran', function () { + throw new Error('Spec should not run'); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/bdd.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/bdd.fixture.js new file mode 100644 index 0000000000..39323f3567 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/bdd.fixture.js @@ -0,0 +1,72 @@ +'use strict'; + +describe.only('should run this suite', function () { + it('should run this test', function () {}); + + it('should run this test', function () {}); + + it('should run this test', function () {}); +}); + +describe('should not run this suite', function () { + it('should not run this test', function () { + (true).should.equal(false); + }); + + it('should not run this test', function () { + (true).should.equal(false); + }); + + it('should not run this test', function () { + (true).should.equal(false); + }); +}); + +describe.only('should run this suite too', function () { + describe('should run this nested suite', function () { + it('should run this test', function () {}); + + it('should run this test', function () {}); + + it('should run this test', function () {}); + }); +}); + +describe.only('should run this suite, even', function () { + describe('should run this nested suite, even', function () { + describe('should run this doubly-nested suite!', function () { + it('should run this test', function () {}); + + it('should run this test', function () {}); + + it('should run this test', function () {}); + }); + }); +}); + +describe('should run this suite with an exclusive test', function () { + it.only('should run this test', function () {}); + + describe('should not run this nested suite', function () { + describe.only('should not run this doubly-nested suite', function () { + it('should not run this test', function () {}); + + it('should not run this test', function () {}); + + it('should not run this test', function () {}); + }); + }); +}); + +describe('should run this suite with an exclusive test (reverse order)', function () { + describe('should not run this nested suite', function () { + describe.only('should not run this doubly-nested suite', function () { + it('should not run this test', function () {}); + + it('should not run this test', function () {}); + + it('should not run this test', function () {}); + }); + }); + it.only('should run this test', function () {}); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/qunit.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/qunit.fixture.js new file mode 100644 index 0000000000..8bc598030d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/qunit.fixture.js @@ -0,0 +1,27 @@ +'use strict'; + +suite.only('should run all tests in this suite'); + +test('should run this test #1', function () {}); + +test('should run this test #2', function () {}); + +test('should run this test #3', function () {}); + +test('should run this test #4', function () {}); + +test('should run this test #5', function () {}); + +suite('should not run any of this suite\'s tests'); + +test('should not run this test', function () { + (false).should.equal(true); +}); + +test('should not run this test', function () { + (false).should.equal(true); +}); + +test('should not run this test', function () { + (false).should.equal(true); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/tdd.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/tdd.fixture.js new file mode 100644 index 0000000000..987ee6bfba --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/only/tdd.fixture.js @@ -0,0 +1,37 @@ +'use strict'; + +suite.only('should run all tests in this tdd suite', function () { + test('should run this test #1', function () {}); + + test('should run this test #2', function () {}); + + test('should run this test #3', function () {}); + + test('should run this test #4', function () {}); +}); + +suite('should not run this suite', function () { + test('should not run this test', function () { + (true).should.equal(false); + }); + + test('should not run this test', function () { + (true).should.equal(false); + }); + + test('should not run this test', function () { + (true).should.equal(false); + }); +}); + +suite.only('should run this suite too', function () { + suite('should run this nested suite', function () { + test('should run this test', function () {}); + + test('should run this test', function () {}); + + test('should run this test', function () {}); + + test('should run this test', function () {}); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/retries.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/retries.fixture.js new file mode 100644 index 0000000000..8d2b0a40b6 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/retries.fixture.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('retries', function () { + it('should fail', function () { + throw new Error('retry failure'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-alpha.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-alpha.fixture.js new file mode 100644 index 0000000000..dd74303163 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-alpha.fixture.js @@ -0,0 +1,9 @@ +'use strict'; + +describe('alpha', function () { + it('should be executed first', function () { + if (global.beta) { + throw new Error('alpha was not executed first'); + } + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-beta.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-beta.fixture.js new file mode 100644 index 0000000000..56da4a6523 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/options/sort-beta.fixture.js @@ -0,0 +1,7 @@ +'use strict'; + +describe('beta', function () { + it('should be executed second', function () { + global.beta = 1; + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/passing.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/passing.fixture.js new file mode 100644 index 0000000000..baf142026d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/passing.fixture.js @@ -0,0 +1,13 @@ +'use strict'; + +var assert = require('assert'); + +describe('suite', function () { + it('test1', function () { + assert(true); + }); + + it('test2', function () { + assert(true); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-before.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-before.fixture.js new file mode 100644 index 0000000000..efeaa93899 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-before.fixture.js @@ -0,0 +1,18 @@ +'use strict'; + +describe('skip in before', function () { + before(function (done) { + var self = this; + setTimeout(function () { + self.skip(); + }, 50); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-beforeEach.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-beforeEach.fixture.js new file mode 100644 index 0000000000..d6225564ba --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-beforeEach.fixture.js @@ -0,0 +1,18 @@ +'use strict'; + +describe('skip in beforeEach', function () { + beforeEach(function (done) { + var self = this; + setTimeout(function () { + self.skip(); + }, 50); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-spec.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-spec.fixture.js new file mode 100644 index 0000000000..44707b026c --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-async-spec.fixture.js @@ -0,0 +1,14 @@ +'use strict'; + +describe('skip in test', function () { + it('should skip async', function (done) { + var self = this; + setTimeout(function () { + self.skip(); + }, 50); + }); + + it('should run other tests in the suite', function () { + // Do nothing + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-before.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-before.fixture.js new file mode 100644 index 0000000000..5e3b208efa --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-before.fixture.js @@ -0,0 +1,15 @@ +'use strict'; + +describe('skip in before', function () { + before(function () { + this.skip(); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js new file mode 100644 index 0000000000..0bd155ba55 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-beforeEach.fixture.js @@ -0,0 +1,15 @@ +'use strict'; + +describe('skip in beforeEach', function () { + beforeEach(function () { + this.skip(); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); + + it('should never run this test', function () { + throw new Error('never thrown'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-spec.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-spec.fixture.js new file mode 100644 index 0000000000..1d22f0b77d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/skip-sync-spec.fixture.js @@ -0,0 +1,12 @@ +'use strict'; + +describe('skip in test', function () { + it('should skip immediately', function () { + this.skip(); + throw new Error('never thrown'); + }); + + it('should run other tests in the suite', function () { + // Do nothing + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/spec.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/spec.fixture.js new file mode 100644 index 0000000000..d750fcad1a --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/pending/spec.fixture.js @@ -0,0 +1,5 @@ +'use strict'; + +describe('suite', function () { + it('pending spec'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/issue-1794.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/issue-1794.fixture.js new file mode 100644 index 0000000000..8867369546 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/issue-1794.fixture.js @@ -0,0 +1,5 @@ +'use strict'; + +test('pass', function () { + // pass +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/simple-ui.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/simple-ui.js new file mode 100644 index 0000000000..5cfde0465f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/1794/simple-ui.js @@ -0,0 +1,28 @@ +'use strict'; + +var path = '../../../../../lib/'; +var Mocha = require(path + 'mocha'); +var Test = require(path + 'test'); + +/** + * A simple UI that only exposes a single function: test + */ +module.exports = Mocha.interfaces['simple-ui'] = function (suite) { + suite.on('pre-require', function (context, file, mocha) { + var common = require(path + 'interfaces/common')([suite], context); + + context.run = mocha.options.delay && common.runWithSuite(suite); + + /** + * Describes a specification or test-case with the given `title` + * and callback `fn` acting as a thunk. + */ + context.test = function (title, fn) { + var test = new Test(title, fn); + test.file = file; + suite.addTest(test); + + return test; + }; + }); +}; diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1327.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1327.fixture.js new file mode 100644 index 0000000000..e788278d6d --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1327.fixture.js @@ -0,0 +1,17 @@ +'use strict'; + +it('test 1', function () { + console.log('testbody1'); + process.nextTick(function () { + throw new Error('Too bad'); + }); +}); + +it('test 2', function () { + console.log('testbody2'); +}); + +it('test 3', function () { + console.log('testbody3'); + throw new Error('OUCH'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1417.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1417.js new file mode 100644 index 0000000000..13ce053784 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1417.js @@ -0,0 +1,22 @@ +'use strict'; + +/** + * This file should generate only one failure per spec for the thrown error. + * It should not report misleading 'multiple calls to done()'. + */ + +it('fails exactly once when a global error is thrown synchronously and done errors', function (done) { + setTimeout(function () { + done(new Error('test error')); + }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition + + throw new Error('sync error'); +}); + +it('fails exactly once when a global error is thrown synchronously and done completes', function (done) { + setTimeout(function () { + done(); + }, 1); // Not 0 - it will 'succeed', but won't test the breaking condition + + throw new Error('sync error'); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1991.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1991.fixture.js new file mode 100644 index 0000000000..024f02519f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-1991.fixture.js @@ -0,0 +1,49 @@ +'use strict'; + +/* eslint no-unused-vars: off */ + +function MemoryLeak () { + this.myArr = []; + for (var i = 0; i < 1000000; i++) { + this.myArr.push(i); + } +} + +var numOfTests = 300; +for (var i = 0; i < numOfTests; i += 1) { + /* + * This Test suite will crash V8 due to: + * 'FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory' + * if all the deferred functions references have not been cleared + */ + describe('Memory Leak Suite #' + i, function () { + // The <closureVar> variable will be accessed by the test below. + // As long as those test's functions are + // referenced in memory, the closure variable may not be garbage collected + // as it is still referenced. + // * In a chrome heap snapshot it will appear under "system / Context" (a scope) + var closureVar; + + before(function () { + var x = closureVar ? 1 : 2; + }); + + after(function () { + var x = closureVar[0]; + }); + + beforeEach(function () { + var x = closureVar ? 1 : 2; + }); + + afterEach(function () { + var x = closureVar[0]; + }); + + it('access a variable via a closure', function () { + // slow performance on older node.js versions + this.timeout(1000); + closureVar = new MemoryLeak(); + }); + }); +} diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2315.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2315.js new file mode 100644 index 0000000000..fe18841d1c --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2315.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('issue-2315: cannot read property currentRetry of undefined', function () { + before(function () { + process.nextTick(function () { + throw new Error(); + }); + }); + + it('something', function () {}); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2406.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2406.fixture.js new file mode 100644 index 0000000000..b3770014dd --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2406.fixture.js @@ -0,0 +1,17 @@ +'use strict'; + +describe('outer describe', function () { + it('should not run this test', function () {}); + describe('this suite should not run', function () { + it('should not run this test', function () {}); + }); + describe.only('this .only suite should run', function () { + describe('this suite should run', function () { + it('should run this test in a nested suite', function () {}); + }); + it('should run this test', function () {}); + }); + describe('this suite should not run', function () { + it('should not run this test', function () {}); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2417.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2417.fixture.js new file mode 100644 index 0000000000..58f49cf846 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/regression/issue-2417.fixture.js @@ -0,0 +1,9 @@ +'use strict'; + +describe('outer describe', function () { + describe.only('outer describe.only', function () { + it.only('inner it.only', function () { + // should run and exit without error + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/async.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/async.fixture.js new file mode 100644 index 0000000000..56d067fc05 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/async.fixture.js @@ -0,0 +1,30 @@ +'use strict'; + +describe('retries', function () { + var times = 0; + before(function () { + console.log('before'); + }); + + after(function () { + console.log('after'); + }); + + beforeEach(function () { + console.log('before each', times); + }); + + afterEach(function () { + console.log('after each', times); + }); + + it('should allow override and run appropriate hooks', function (done) { + this.timeout(200); + this.retries(2); + console.log('TEST', times); + if (++times < 3) { + return setTimeout(done, 300); + } + setTimeout(done, 50); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/early-pass.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/early-pass.fixture.js new file mode 100644 index 0000000000..ddad40399e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/early-pass.fixture.js @@ -0,0 +1,13 @@ +'use strict'; + +describe('retries', function () { + this.retries(1); + var times = 0; + + it('should pass after 1 retry', function () { + times++; + if (times !== 2) { + throw new Error('retry error ' + times); + } + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/hooks.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/hooks.fixture.js new file mode 100644 index 0000000000..b4fc081aaa --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/hooks.fixture.js @@ -0,0 +1,27 @@ +'use strict'; + +describe('retries', function () { + var times = 0; + before(function () { + console.log('before'); + }); + + after(function () { + console.log('after'); + }); + + beforeEach(function () { + console.log('before each', times); + }); + + afterEach(function () { + console.log('after each', times); + }); + + it('should allow override and run appropriate hooks', function () { + this.retries(4); + console.log('TEST', times); + times++; + throw new Error('retry error'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/nested.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/nested.fixture.js new file mode 100644 index 0000000000..877d519d7f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/retries/nested.fixture.js @@ -0,0 +1,11 @@ +'use strict'; + +describe('retries', function () { + this.retries(3); + describe('nested', function () { + it('should fail after only 1 retry', function () { + this.retries(1); + throw new Error('retry error'); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-no-callback.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-no-callback.fixture.js new file mode 100644 index 0000000000..80d046438f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-no-callback.fixture.js @@ -0,0 +1,3 @@ +'use strict'; + +describe('a suite without a callback'); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-callback.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-callback.fixture.js new file mode 100644 index 0000000000..6def25de7f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-callback.fixture.js @@ -0,0 +1,3 @@ +'use strict'; + +xdescribe('a pending suite with a callback', function () {}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js new file mode 100644 index 0000000000..e9381159bf --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/suite/suite-skipped-no-callback.fixture.js @@ -0,0 +1,3 @@ +'use strict'; + +xdescribe('a pending suite without a callback'); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/timeout.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/timeout.fixture.js new file mode 100644 index 0000000000..d237436811 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/timeout.fixture.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('timeout', function () { + this.timeout(1); + + it('should be honored with sync suites', function () { + sleep(2); + }); + + it('should be honored with async suites', function (done) { + sleep(2); + done(); + }); + + function sleep (ms) { + var start = Date.now(); + while (start + ms > Date.now()); + } +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught-hook.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught-hook.fixture.js new file mode 100644 index 0000000000..54f30c56e9 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught-hook.fixture.js @@ -0,0 +1,15 @@ +'use strict'; + +describe('uncaught', function () { + beforeEach(function (done) { + process.nextTick(function () { + throw new Error('oh noes'); + }); + }); + + it('test', function (done) { + process.nextTick(function () { + throw new Error("I'm uncaught!"); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught.fixture.js b/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught.fixture.js new file mode 100644 index 0000000000..6a2ded880c --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/fixtures/uncaught.fixture.js @@ -0,0 +1,22 @@ +'use strict'; + +/** + * This file should only generate one failure per spec despite the fact that + * Mocha is capable of detecting two distinct exceptions during test execution. + */ + +it('fails exactly once when a global error is thrown first', function (done) { + setTimeout(function () { + throw new Error('global error'); + }, 0); +}); + +it('fails exactly once when a global error is thrown second', function (done) { + setTimeout(function () { + done(new Error('test error')); + }, 0); + + setTimeout(function () { + throw new Error('global error'); + }, 0); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/helpers.js b/tests/lib/mocha-3.1.2/test/integration/helpers.js new file mode 100644 index 0000000000..7f6a608a6f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/helpers.js @@ -0,0 +1,193 @@ +'use strict'; + +var spawn = require('child_process').spawn; +var path = require('path'); +var fs = require('fs'); +var baseReporter = require('../../lib/reporters/base'); + +module.exports = { + /** + * Invokes the mocha binary for the given fixture with color output disabled. + * 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 {string} fixturePath + * @param {array} args + * @param {function} fn + */ + runMocha: function (fixturePath, args, fn) { + var path; + + path = resolveFixturePath(fixturePath); + args = args || []; + + invokeMocha(args.concat(['-C', path]), function (err, res) { + if (err) return fn(err); + + fn(null, getSummary(res)); + }); + }, + + /** + * 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. + * + * @param {string} fixturePath + * @param {array} args + * @param {function} fn + */ + runMochaJSON: function (fixturePath, args, fn) { + var path; + + path = resolveFixturePath(fixturePath); + args = args || []; + + invokeMocha(args.concat(['--reporter', 'json', path]), function (err, res) { + if (err) return fn(err); + + try { + var result = JSON.parse(res.output); + result.code = res.code; + } catch (err) { + return fn(err); + } + + fn(null, result); + }); + }, + + /** + * Returns an array of diffs corresponding to exceptions thrown from specs, + * given the plaintext output (-C) of a mocha run. + * + * @param {string} output + * returns {string[]} + */ + getDiffs: function (output) { + var diffs, i, inDiff, inStackTrace; + + diffs = []; + output.split('\n').forEach(function (line) { + if (line.match(/^\s{2}\d+\)/)) { + // New spec, e.g. "1) spec title" + diffs.push([]); + i = diffs.length - 1; + inStackTrace = false; + inDiff = false; + } else if (!diffs.length || inStackTrace) { + // Haven't encountered a spec yet + // or we're in the middle of a stack trace + return; + } else if (line.indexOf('+ expected - actual') !== -1) { + inDiff = true; + } else if (line.match(/at Context/)) { + // At the start of a stack trace + inStackTrace = true; + inDiff = false; + } else if (inDiff) { + diffs[i].push(line); + } + }); + + // Ignore empty lines before/after diff + return diffs.map(function (diff) { + return diff.slice(1, -3).join('\n'); + }); + }, + + /** + * regular expression used for splitting lines based on new line / dot symbol. + */ + splitRegExp: new RegExp('[\\n' + baseReporter.symbols.dot + ']+') +}; + +function invokeMocha (args, fn) { + var output, mocha, listener; + + output = ''; + args = [path.join('bin', 'mocha')].concat(args); + mocha = spawn(process.execPath, args); + + listener = function (data) { + output += data; + }; + + mocha.stdout.on('data', listener); + mocha.stderr.on('data', listener); + mocha.on('error', fn); + + mocha.on('close', function (code) { + fn(null, { + output: output.split('\n').join('\n'), + code: code + }); + }); +} + +function resolveFixturePath (fixture) { + return path.join('./test/integration/fixtures', fixture); +} + +function getSummary (res) { + return ['passing', 'pending', 'failing'].reduce(function (summary, type) { + var pattern, match; + + pattern = new RegExp(' (\\d+) ' + type + '\\s'); + match = pattern.exec(res.output); + summary[type] = (match) ? parseInt(match, 10) : 0; + + return summary; + }, res); +} diff --git a/tests/lib/mocha-3.1.2/test/integration/hook-err.spec.js b/tests/lib/mocha-3.1.2/test/integration/hook-err.spec.js new file mode 100644 index 0000000000..fbdd7e8e38 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/hook-err.spec.js @@ -0,0 +1,217 @@ +'use strict'; + +var assert = require('assert'); +var runMocha = require('./helpers').runMocha; +var splitRegExp = require('./helpers').splitRegExp; +var bang = require('../../lib/reporters/base').symbols.bang; + +describe('hook error handling', function () { + var lines; + + describe('before hook error', function () { + before(run('hooks/before-hook-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['before', bang + 'test 3'] + ); + }); + }); + + describe('before hook error tip', function () { + before(run('hooks/before-hook-error-tip.fixture.js', onlyErrorTitle)); + it('should verify results', function () { + assert.deepEqual( + lines, + ['1) spec 2 "before all" hook:'] + ); + }); + }); + + describe('before each hook error', function () { + before(run('hooks/beforeEach-hook-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['before', bang + 'test 3'] + ); + }); + }); + + describe('after hook error', function () { + before(run('hooks/after-hook-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['test 1', 'test 2', 'after', bang + 'test 3'] + ); + }); + }); + + describe('after each hook error', function () { + before(run('hooks/afterEach-hook-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['test 1', 'after', bang + 'test 3'] + ); + }); + }); + + describe('multiple hook errors', function () { + before(run('hooks/multiple-hook-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + [ + 'root before', + '1-1 before', + 'root before each', + '1 before each', + '1-1 before each', + bang + '1-1 after each', + '1 after each', + 'root after each', + '1-1 after', + bang + '1-2 before', + 'root before each', + '1 before each', + '1-2 before each', + '1-2 test 1', + '1-2 after each', + bang + '1 after each', + 'root after each', + '1-2 after', + '1 after', + '2-1 before', + 'root before each', + '2 before each', + bang + '2 after each', + bang + 'root after each', + '2-1 after', + '2 after', + 'root after' + ] + ); + }); + }); + + describe('async - before hook error', function () { + before(run('hooks/before-hook-async-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['before', bang + 'test 3'] + ); + }); + }); + + describe('async - before hook error tip', function () { + before(run('hooks/before-hook-async-error-tip.fixture.js', onlyErrorTitle)); + it('should verify results', function () { + assert.deepEqual( + lines, + ['1) spec 2 "before all" hook:'] + ); + }); + }); + + describe('async - before each hook error', function () { + before(run('hooks/beforeEach-hook-async-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['before', bang + 'test 3'] + ); + }); + }); + + describe('async - after hook error', function () { + before(run('hooks/after-hook-async-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['test 1', 'test 2', 'after', bang + 'test 3'] + ); + }); + }); + + describe('async - after each hook error', function () { + before(run('hooks/afterEach-hook-async-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + ['test 1', 'after', bang + 'test 3'] + ); + }); + }); + + describe('async - multiple hook errors', function () { + before(run('hooks/multiple-hook-async-error.fixture.js')); + it('should verify results', function () { + assert.deepEqual( + lines, + [ + 'root before', + '1-1 before', + 'root before each', + '1 before each', + '1-1 before each', + bang + '1-1 after each', + '1 after each', + 'root after each', + '1-1 after', + bang + '1-2 before', + 'root before each', + '1 before each', + '1-2 before each', + '1-2 test 1', + '1-2 after each', + bang + '1 after each', + 'root after each', + '1-2 after', + '1 after', + '2-1 before', + 'root before each', + '2 before each', + bang + '2 after each', + bang + 'root after each', + '2-1 after', + '2 after', + 'root after' + ] + ); + }); + }); + + function run (fnPath, outputFilter) { + return function (done) { + runMocha(fnPath, [], function (err, res) { + assert.ifError(err); + + lines = res.output + .split(splitRegExp) + .map(function (line) { + return line.trim(); + }) + .filter(outputFilter || onlyConsoleOutput()); + + done(); + }); + }; + } +}); + +function onlyConsoleOutput () { + var foundSummary = false; + return function (line) { + if (!foundSummary) { + foundSummary = !!(/\(\d+ms\)/).exec(line); + } + return !foundSummary && line.length > 0; + }; +} + +function onlyErrorTitle (line) { + return !!(/^1\)/).exec(line); +} diff --git a/tests/lib/mocha-3.1.2/test/integration/hooks.spec.js b/tests/lib/mocha-3.1.2/test/integration/hooks.spec.js new file mode 100644 index 0000000000..0d31cbfdf4 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/hooks.spec.js @@ -0,0 +1,45 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMocha; +var splitRegExp = require('./helpers').splitRegExp; +var args = []; + +describe('hooks', function () { + it('are ran in correct order', function (done) { + run('cascade.fixture.js', args, function (err, res) { + var lines, expected; + + assert(!err); + + lines = res.output.split(splitRegExp).map(function (line) { + return line.trim(); + }).filter(function (line) { + return line.length; + }).slice(0, -1); + + expected = [ + 'before one', + 'before two', + 'before three', + 'before each one', + 'before each two', + 'before each three', + 'TEST three', + 'after each three', + 'after each two', + 'after each one', + 'after three', + 'after two', + 'after one' + ]; + + expected.forEach(function (line, i) { + assert.equal(lines[i], line); + }); + + assert.equal(res.code, 0); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/multiple-done.spec.js b/tests/lib/mocha-3.1.2/test/integration/multiple-done.spec.js new file mode 100644 index 0000000000..76a6483115 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/multiple-done.spec.js @@ -0,0 +1,98 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMochaJSON; +var args = []; + +describe('multiple calls to done()', function () { + var res; + describe('from a spec', function () { + before(function (done) { + run('multiple-done.fixture.js', args, function (err, result) { + res = result; + done(err); + }); + }); + + it('results in failures', function () { + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + }); + + it('throws a descriptive error', function () { + assert.equal(res.failures[0].err.message, + 'done() called multiple times'); + }); + }); + + describe('with multiple specs', function () { + before(function (done) { + run('multiple-done-specs.fixture.js', args, function (err, result) { + res = result; + done(err); + }); + }); + + it('results in a failure', function () { + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 2); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + }); + + it('correctly attributes the error', function () { + assert.equal(res.failures[0].fullTitle, 'suite test1'); + assert.equal(res.failures[0].err.message, + 'done() called multiple times'); + }); + }); + + describe('from a before hook', function () { + before(function (done) { + run('multiple-done-before.fixture.js', args, function (err, result) { + res = result; + done(err); + }); + }); + + it('results in a failure', function () { + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + }); + + it('correctly attributes the error', function () { + assert.equal(res.failures[0].fullTitle, 'suite "before all" hook'); + assert.equal(res.failures[0].err.message, + 'done() called multiple times'); + }); + }); + + describe('from a beforeEach hook', function () { + before(function (done) { + run('multiple-done-beforeEach.fixture.js', args, function (err, result) { + res = result; + done(err); + }); + }); + + it('results in a failure', function () { + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 2); + assert.equal(res.stats.failures, 2); + assert.equal(res.code, 2); + }); + + it('correctly attributes the errors', function () { + assert.equal(res.failures.length, 2); + res.failures.forEach(function (failure) { + assert.equal(failure.fullTitle, 'suite "before each" hook'); + assert.equal(failure.err.message, + 'done() called multiple times'); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/only.spec.js b/tests/lib/mocha-3.1.2/test/integration/only.spec.js new file mode 100644 index 0000000000..b37a4b263e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/only.spec.js @@ -0,0 +1,45 @@ +'use strict'; + +var run = require('./helpers').runMochaJSON; +var assert = require('assert'); + +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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 11); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 8); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 5); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/options.spec.js b/tests/lib/mocha-3.1.2/test/integration/options.spec.js new file mode 100644 index 0000000000..7c7a3cc75e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/options.spec.js @@ -0,0 +1,183 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMochaJSON; +var args = []; + +describe('options', function () { + describe('--async-only', function () { + before(function () { + args = ['--async-only']; + }); + + it('should fail synchronous specs', function (done) { + run('options/async-only-sync.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 1); + + assert.equal(res.failures[0].title, 'throws an error'); + assert.equal(res.code, 1); + done(); + }); + }); + + it('should allow asynchronous specs', function (done) { + run('options/async-only-async.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + + assert.equal(res.passes[0].title, 'should pass'); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + describe('--bail', function () { + before(function () { + args = ['--bail']; + }); + + it('should stop after the first error', function (done) { + run('options/bail.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 1); + + assert.equal(res.passes[0].title, 'should display this spec'); + assert.equal(res.failures[0].title, 'should only display this error'); + assert.equal(res.code, 1); + done(); + }); + }); + }); + + describe('--sort', function () { + before(function () { + args = ['--sort']; + }); + + it('should sort tests in alphabetical order', function (done) { + run('options/sort*', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 2); + assert.equal(res.stats.failures, 0); + + assert.equal(res.passes[0].fullTitle, + 'alpha should be executed first'); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + describe('--delay', function () { + before(function () { + args = ['--delay']; + }); + + it('should run the generated test suite', function (done) { + run('options/delay.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + + assert.equal(res.passes[0].title, + 'should have no effect if attempted twice in the same suite'); + assert.equal(res.code, 0); + done(); + }); + }); + + 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 1); + + assert.equal(res.failures[0].title, + 'Uncaught error outside test suite'); + assert.equal(res.code, 1); + done(); + }); + }); + }); + + describe('--grep', function () { + it('runs specs matching a string', function (done) { + args = ['--grep', 'match']; + run('options/grep.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 2); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + + describe('runs specs matching a RegExp', 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 4); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + + it('string as pattern', function (done) { + args = ['--grep', '.*']; + run('options/grep.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 4); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + done(); + }); + }); + }); + + describe('with --invert', 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 4); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + }); + + describe('--retries', function () { + it('retries after a certain threshold', function (done) { + args = ['--retries', '3']; + run('options/retries.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.tests, 1); + assert.equal(res.tests[0].currentRetry, 3); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + done(); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/pending.spec.js b/tests/lib/mocha-3.1.2/test/integration/pending.spec.js new file mode 100644 index 0000000000..19ae30ad3a --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/pending.spec.js @@ -0,0 +1,102 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMochaJSON; +var args = []; + +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); + assert.equal(res.stats.pending, 1); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + describe('synchronous skip()', 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); + assert.equal(res.stats.pending, 1); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + }); + + describe('asynchronous skip()', 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); + assert.equal(res.stats.pending, 1); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + + 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); + assert.equal(res.stats.pending, 2); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/regression.spec.js b/tests/lib/mocha-3.1.2/test/integration/regression.spec.js new file mode 100644 index 0000000000..ffd17aa979 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/regression.spec.js @@ -0,0 +1,119 @@ +'use strict'; + +var assert = require('assert'); +var fs = require('fs'); +var path = require('path'); +var run = require('./helpers').runMocha; +var runJSON = require('./helpers').runMochaJSON; + +describe('regressions', function () { + it('issue-1327: should run all 3 specs exactly once', function (done) { + var args = []; + run('regression/issue-1327.fixture.js', args, function (err, res) { + var occurences = function (str) { + var pattern = new RegExp(str, 'g'); + return (res.output.match(pattern) || []).length; + }; + + assert(!err); + assert.equal(occurences('testbody1'), 1); + assert.equal(occurences('testbody2'), 1); + assert.equal(occurences('testbody3'), 1); + + assert.equal(res.code, 1); + done(); + }); + }); + + it('should not duplicate mocha.opts args in process.argv', function () { + var processArgv = process.argv.join(''); + var mochaOpts = fs.readFileSync(path.join(__dirname, '..', 'mocha.opts'), 'utf-8').split(/[\s]+/).join(''); + assert.notEqual(processArgv.indexOf(mochaOpts), -1, 'process.argv missing mocha.opts'); + assert.equal(processArgv.indexOf(mochaOpts), processArgv.lastIndexOf(mochaOpts), 'process.argv contains duplicated mocha.opts'); + }); + + it('issue-1794: Can\'t --require custom UI and use it', function (done) { + 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); + assert.equal(res.code, 0, 'Custom UI should be loaded'); + done(); + }); + }); + + it('issue-1991: Declarations do not get cleaned up unless you set them to `null` - Memory Leak', function (done) { + // on a modern MBP takes ±5 seconds on node 4.0, but on older laptops with node 0.12 ±40 seconds. + // 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); + 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(); + }); + }); + + describe('issue-2286: after doesn\'t execute if test was skipped in beforeEach', function () { + var afterWasRun = false; + describe('suite with skipped test for meta test', function () { + beforeEach(function () { this.skip(); }); + after(function () { afterWasRun = true; }); + it('should be pending', function () {}); + }); + after('meta test', function () { + afterWasRun.should.be.ok(); + }); + }); + + it('issue-2315: cannot read property currentRetry of undefined', function (done) { + runJSON('regression/issue-2315.js', [], function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 1); + assert.equal(res.code, 1); + done(); + }); + }); + + 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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 2); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + done(); + }); + }); + + it('issue-2417: should not recurse infinitely with .only suites nested within each other', function () { + runJSON('regression/issue-2417.fixture.js', [], function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + assert.equal(res.code, 0); + }); + }); + + it('issue-1417 uncaught exceptions from async specs', function (done) { + runJSON('regression/issue-1417.js', [], function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 2); + + assert.equal(res.failures[0].title, + 'fails exactly once when a global error is thrown synchronously and done errors'); + assert.equal(res.failures[0].err.message, 'sync error'); + assert.equal(res.failures[1].title, + 'fails exactly once when a global error is thrown synchronously and done completes'); + assert.equal(res.failures[1].err.message, 'sync error'); + assert.equal(res.code, 2); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/reporters.spec.js b/tests/lib/mocha-3.1.2/test/integration/reporters.spec.js new file mode 100644 index 0000000000..5cfee57037 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/reporters.spec.js @@ -0,0 +1,63 @@ +'use strict'; + +var assert = require('assert'); +var os = require('os'); +var fs = require('fs'); +var crypto = require('crypto'); +var path = require('path'); +var run = require('./helpers').runMocha; + +describe('reporters', function () { + describe('markdown', function () { + var res; + + before(function (done) { + run('passing.fixture.js', ['--reporter', 'markdown'], function (err, result) { + res = result; + done(err); + }); + }); + + it('does not exceed maximum callstack (issue: 1875)', function () { + assert(res.output.indexOf('RangeError') === -1, 'Threw RangeError'); + }); + + it('contains spec src', function () { + var src = [ + '```js', + 'assert(true);', + '```' + ].join('\n'); + + assert(res.output.indexOf(src) !== -1, 'No assert found'); + }); + }); + + describe('xunit', function () { + it('prints test cases with --reporter-options output (issue: 1864)', function (done) { + var randomStr = crypto.randomBytes(8).toString('hex'); + var tmpDir = os.tmpDir().replace(new RegExp(path.sep + '$'), ''); + var tmpFile = tmpDir + path.sep + 'test-issue-1864-' + randomStr + '.xml'; + + var args = ['--reporter=xunit', '--reporter-options', 'output=' + tmpFile]; + var expectedOutput = [ + '<testcase classname="suite" name="test1" time="', + '<testcase classname="suite" name="test2" time="', + '</testsuite>' + ]; + + run('passing.fixture.js', args, function (err, result) { + if (err) return done(err); + + var xml = fs.readFileSync(tmpFile, 'utf8'); + fs.unlinkSync(tmpFile); + + expectedOutput.forEach(function (line) { + assert(xml.indexOf(line) !== -1, 'XML did not contain ' + line); + }); + + done(err); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/retries.spec.js b/tests/lib/mocha-3.1.2/test/integration/retries.spec.js new file mode 100644 index 0000000000..28ed702c5f --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/retries.spec.js @@ -0,0 +1,108 @@ +'use strict'; + +var assert = require('assert'); +var helpers = require('./helpers'); +var args = []; +var bang = require('../../lib/reporters/base').symbols.bang; + +describe('retries', function () { + it('are ran in correct order', function (done) { + helpers.runMocha('retries/hooks.fixture.js', args, function (err, res) { + var lines, expected; + + assert(!err); + + lines = res.output.split(helpers.splitRegExp).map(function (line) { + return line.trim(); + }).filter(function (line) { + return line.length; + }).slice(0, -1); + + expected = [ + 'before', + 'before each 0', + 'TEST 0', + 'after each 1', + 'before each 1', + 'TEST 1', + 'after each 2', + 'before each 2', + 'TEST 2', + 'after each 3', + 'before each 3', + 'TEST 3', + 'after each 4', + 'before each 4', + 'TEST 4', + bang + 'after each 5', + 'after' + ]; + + expected.forEach(function (line, i) { + assert.equal(lines[i], line); + }); + + assert.equal(res.code, 1); + done(); + }); + }); + + it('should exit early if test passes', function (done) { + helpers.runMochaJSON('retries/early-pass.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.passes, 1); + assert.equal(res.stats.failures, 0); + assert.equal(res.tests[0].currentRetry, 1); + assert.equal(res.stats.tests, 1); + assert.equal(res.code, 0); + done(); + }); + }); + + it('should let test override', function (done) { + helpers.runMochaJSON('retries/nested.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 1); + assert.equal(res.stats.tests, 1); + assert.equal(res.tests[0].currentRetry, 1); + assert.equal(res.code, 1); + done(); + }); + }); + + it('should not hang w/ async test', function (done) { + helpers.runMocha('retries/async.fixture.js', args, function (err, res) { + var lines, expected; + + assert(!err); + + lines = res.output.split(helpers.splitRegExp).map(function (line) { + return line.trim(); + }).filter(function (line) { + return line.length; + }).slice(0, -1); + + expected = [ + 'before', + 'before each 0', + 'TEST 0', + 'after each 1', + 'before each 1', + 'TEST 1', + 'after each 2', + 'before each 2', + 'TEST 2', + 'after each 3', + 'after' + ]; + + expected.forEach(function (line, i) { + assert.equal(lines[i], line); + }); + + assert.equal(res.code, 0); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/suite.spec.js b/tests/lib/mocha-3.1.2/test/integration/suite.spec.js new file mode 100644 index 0000000000..171a929ed1 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/suite.spec.js @@ -0,0 +1,43 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMocha; +var args = []; + +describe('suite w/no callback', function () { + this.timeout(1000); + 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); + var result = res.output.match(/no callback was supplied/) || []; + assert.equal(result.length, 1); + done(); + }); + }); +}); + +describe('skipped suite w/no callback', function () { + this.timeout(1000); + 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); + var pattern = new RegExp('Error', 'g'); + var result = res.output.match(pattern) || []; + assert.equal(result.length, 0); + done(); + }); + }); +}); + +describe('skipped suite w/ callback', function () { + this.timeout(1000); + 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); + var pattern = new RegExp('Error', 'g'); + var result = res.output.match(pattern) || []; + assert.equal(result.length, 0); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/timeout.spec.js b/tests/lib/mocha-3.1.2/test/integration/timeout.spec.js new file mode 100644 index 0000000000..4e0f989e86 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/timeout.spec.js @@ -0,0 +1,18 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMochaJSON; +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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 2); + assert.equal(res.code, 2); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/integration/uncaught.spec.js b/tests/lib/mocha-3.1.2/test/integration/uncaught.spec.js new file mode 100644 index 0000000000..92e39c195e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/integration/uncaught.spec.js @@ -0,0 +1,37 @@ +'use strict'; + +var assert = require('assert'); +var run = require('./helpers').runMochaJSON; +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); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 1); + + assert.equal(res.failures[0].fullTitle, + 'uncaught "before each" hook'); + assert.equal(res.code, 1); + done(); + }); + }); + + it('handles uncaught exceptions from async specs', function (done) { + run('uncaught.fixture.js', args, function (err, res) { + assert(!err); + assert.equal(res.stats.pending, 0); + assert.equal(res.stats.passes, 0); + assert.equal(res.stats.failures, 2); + + assert.equal(res.failures[0].title, + 'fails exactly once when a global error is thrown first'); + assert.equal(res.failures[1].title, + 'fails exactly once when a global error is thrown second'); + assert.equal(res.code, 2); + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/jsapi/index.js b/tests/lib/mocha-3.1.2/test/jsapi/index.js new file mode 100644 index 0000000000..42133578e0 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/jsapi/index.js @@ -0,0 +1,30 @@ +'use strict'; + +var Mocha = require('../../'); + +var mocha = new Mocha({ + ui: 'bdd', + globals: ['okGlobalA', 'okGlobalB', 'okGlobalC', 'callback*'], + // ignoreLeaks: true, + growl: true +}); + +// mocha.reporter('spec'); +require('should'); + +mocha.addFile('test/suite.spec.js'); +mocha.addFile('test/runner.spec.js'); +mocha.addFile('test/runnable.spec.js'); +mocha.addFile('test/hook-sync.spec.js'); +mocha.addFile('test/hook-sync-nested.spec.js'); +mocha.addFile('test/hook-async.spec.js'); +mocha.addFile('test/acceptance/duration.spec.js'); +mocha.addFile('test/acceptance/fs.spec.js'); +mocha.addFile('test/acceptance/globals.spec.js'); +mocha.addFile('test/acceptance/timeout.spec.js'); + +mocha.run(function () { + console.log('done'); +}).on('pass', function (test) { + // console.log('... %s', test.title); +}); diff --git a/tests/lib/mocha-3.1.2/test/mocha.opts b/tests/lib/mocha-3.1.2/test/mocha.opts new file mode 100644 index 0000000000..36146eb65e --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/mocha.opts @@ -0,0 +1,8 @@ +--require should +--require ./test/setup +--reporter dot +--ui bdd +--globals okGlobalA,okGlobalB +--globals okGlobalC +--globals callback* +--timeout 200 diff --git a/tests/lib/mocha-3.1.2/test/mocha.spec.js b/tests/lib/mocha-3.1.2/test/mocha.spec.js new file mode 100644 index 0000000000..618742cdbd --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/mocha.spec.js @@ -0,0 +1,35 @@ +'use strict'; + +var Mocha = require('../'); +var Test = Mocha.Test; + +describe('Mocha', function () { + var blankOpts = { reporter: function () {} }; // no output + + describe('.run(fn)', function () { + it('should not raise errors if callback was not provided', function () { + var mocha = new Mocha(blankOpts); + mocha.run(); + }); + + it('should execute the callback when complete', function (done) { + var mocha = new Mocha(blankOpts); + mocha.run(function () { + done(); + }); + }); + + it('should execute the callback with the number of failures ' + + 'as parameter', function (done) { + var mocha = new Mocha(blankOpts); + var failingTest = new Test('failing test', function () { + throw new Error('such fail'); + }); + mocha.suite.addTest(failingTest); + mocha.run(function (failures) { + failures.should.equal(1); + done(); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/ms.spec.js b/tests/lib/mocha-3.1.2/test/ms.spec.js new file mode 100644 index 0000000000..26f5c30209 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/ms.spec.js @@ -0,0 +1,82 @@ +'use strict'; +var ms = require('../lib/ms'); + +describe('.ms()', function () { + // Helpers + var time = { + minutes: function (n) { return n * 60 * 1000; }, + hours: function (n) { return n * this.minutes(60); }, + days: function (n) { return n * this.hours(24); }, + years: function (n) { return n * this.days(365.25); } + }; + describe('get a value that less than 1 second', function () { + it('should return milliseconds representation', function () { + ms(200).should.equal('200ms'); + ms(30).should.equal('30ms'); + ms(2000).should.not.equal('2000ms'); + }); + }); + + describe('seconds representation', function () { + it('should return short format', function () { + ms(2000).should.equal('2s'); + }); + + it('should return long format', function () { + ms(2000, { long: true }).should.equal('2 seconds'); + ms(1000, { long: true }).should.equal('1 second'); + ms(1010, { long: true }).should.equal('1 second'); + }); + }); + + describe('minutess representation', function () { + it('should return short format', function () { + ms(time.minutes(1)).should.equal('1m'); + }); + + it('should return long format', function () { + ms(time.minutes(1), { long: true }).should.equal('1 minute'); + ms(time.minutes(3), { long: true }).should.equal('3 minutes'); + }); + }); + + describe('hours representation', function () { + it('should return short format', function () { + ms(time.hours(1)).should.equal('1h'); + }); + + it('should return long format', function () { + ms(time.hours(1), { long: true }).should.equal('1 hour'); + ms(time.hours(3), { long: true }).should.equal('3 hours'); + }); + }); + + describe('days representation', function () { + it('should return short format', function () { + ms(time.days(1)).should.equal('1d'); + }); + + it('should return long format', function () { + ms(time.days(1), { long: true }).should.equal('1 day'); + ms(time.days(3), { long: true }).should.equal('3 days'); + }); + }); + + describe('Getting string value', function () { + it('should return the milliseconds representation(Number)', function () { + ms('1 second').should.equal(1000); + + ms('1 minute').should.equal(time.minutes(1)); + ms('6 minutes').should.equal(time.minutes(6)); + + ms('1 hour').should.equal(time.hours(1)); + ms('5 hours').should.equal(time.hours(5)); + + ms('1 day').should.equal(time.days(1)); + ms('3 days').should.equal(time.days(3)); + + ms('1 year').should.equal(time.years(1)); + ms('2 years').should.equal(time.years(2)); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/reporters/base.spec.js b/tests/lib/mocha-3.1.2/test/reporters/base.spec.js new file mode 100644 index 0000000000..6282d882ff --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/reporters/base.spec.js @@ -0,0 +1,213 @@ +'use strict'; + +var assert = require('assert'); + +var Base = require('../../lib/reporters/base'); +var Assert = require('assert').AssertionError; + +function makeTest (err) { + return { + err: err, + fullTitle: function () { + return 'test title'; + } + }; +} + +describe('Base reporter', function () { + var stdout; + var stdoutWrite; + var useColors; + + beforeEach(function () { + stdout = []; + stdoutWrite = process.stdout.write; + process.stdout.write = function (string) { + stdout.push(string); + }; + useColors = Base.useColors; + Base.useColors = false; + }); + + afterEach(function () { + process.stdout.write = stdoutWrite; + Base.useColors = useColors; + }); + + describe('showDiff', function () { + it('should show diffs by default', function () { + var err = new Assert({ actual: 'foo', expected: 'bar' }); + var errOut; + + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.match(/\- actual/); + errOut.should.match(/\+ expected/); + }); + + it('should show diffs if property set to `true`', function () { + var err = new Assert({ actual: 'foo', expected: 'bar' }); + var errOut; + + err.showDiff = true; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.match(/\- actual/); + errOut.should.match(/\+ expected/); + }); + + it('should not show diffs when showDiff property set to `false`', function () { + var err = new Assert({ actual: 'foo', expected: 'bar' }); + var errOut; + + err.showDiff = false; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.not.match(/\- actual/); + errOut.should.not.match(/\+ expected/); + }); + + it('should not show diffs when expected is not defined', function () { + var err = new Error('ouch'); + var errOut; + + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.not.match(/\- actual/); + errOut.should.not.match(/\+ expected/); + }); + }); + + describe('Getting two strings', function () { + // Fix regression V1.2.1(see: issue #1241) + it('should show strings diff as is', function () { + var err = new Error('test'); + var errOut; + + err.actual = 'foo\nbar'; + err.expected = 'foo\nbaz'; + err.showDiff = true; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + + errOut.should.not.match(/"foo\\nbar"/); + errOut.should.match(/foo/).and.match(/bar/); + errOut.should.match(/test/); + errOut.should.match(/actual/); + errOut.should.match(/expected/); + }); + }); + + it('should stringify objects', function () { + var err = new Error('test'); + var errOut; + + err.actual = {key: 'a1'}; + err.expected = {key: 'e1'}; + err.showDiff = true; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.match(/"key"/); + errOut.should.match(/test/); + errOut.should.match(/\- actual/); + errOut.should.match(/\+ expected/); + }); + + it('should stringify Object.create(null)', function () { + var err = new Error('test'); + var errOut; + + err.actual = Object.create(null); + err.actual.hasOwnProperty = 1; + err.expected = Object.create(null); + err.expected.hasOwnProperty = 2; + err.showDiff = true; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.match(/"hasOwnProperty"/); + errOut.should.match(/test/); + errOut.should.match(/\- actual/); + errOut.should.match(/\+ expected/); + }); + + it('should handle error messages that are not strings', function () { + var errOut; + + try { + assert(false, true); + } catch (err) { + err.actual = false; + err.expected = true; + err.showDiff = true; + var test = makeTest(err); + + Base.list([test]); + + errOut = stdout.join('\n'); + errOut.should.match(/\+true/); + errOut.should.match(/\-false/); + errOut.should.match(/\- actual/); + errOut.should.match(/\+ expected/); + } + }); + + it('should remove message from stack', function () { + var err = { + message: 'Error', + stack: 'Error\nfoo\nbar', + showDiff: false + }; + var test = makeTest(err); + + Base.list([test]); + + var errOut = stdout.join('\n').trim(); + errOut.should.equal('1) test title:\n Error\n foo\n bar'); + }); + + it('should use the inspect() property if `message` is not set', function () { + var err = { + showDiff: false, + inspect: function () { return 'an error happened'; } + }; + var test = makeTest(err); + Base.list([test]); + var errOut = stdout.join('\n').trim(); + errOut.should.equal('1) test title:\n an error happened'); + }); + + it('should not modify stack if it does not contain message', function () { + var err = { + message: 'Error', + stack: 'foo\nbar', + showDiff: false + }; + var test = makeTest(err); + + Base.list([test]); + + var errOut = stdout.join('\n').trim(); + errOut.should.equal('1) test title:\n Error\n foo\n bar'); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/reporters/json.spec.js b/tests/lib/mocha-3.1.2/test/reporters/json.spec.js new file mode 100644 index 0000000000..74151fdc8b --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/reporters/json.spec.js @@ -0,0 +1,63 @@ +'use strict'; + +var Mocha = require('../../'); +var Suite = Mocha.Suite; +var Runner = Mocha.Runner; +var Test = Mocha.Test; + +describe('json reporter', function () { + var suite, runner; + + beforeEach(function () { + var mocha = new Mocha({ + reporter: 'json' + }); + suite = new Suite('JSON suite', 'root'); + runner = new Runner(suite); + /* eslint no-unused-vars: off */ + var mochaReporter = new mocha._reporter(runner); + }); + + it('should have 1 test failure', function (done) { + var testTitle = 'json test 1'; + var error = { message: 'oh shit' }; + + suite.addTest(new Test(testTitle, function (done) { + done(new Error(error.message)); + })); + + runner.run(function (failureCount) { + failureCount.should.be.exactly(1); + runner.should.have.property('testResults'); + runner.testResults.should.have.property('failures'); + runner.testResults.failures.should.be.an.instanceOf(Array); + runner.testResults.failures.should.have.a.lengthOf(1); + + var failure = runner.testResults.failures[0]; + failure.should.have.property('title', testTitle); + failure.err.message.should.equal(error.message); + failure.should.have.properties('err'); + + done(); + }); + }); + + it('should have 1 test pending', function (done) { + var testTitle = 'json test 1'; + + suite.addTest(new Test(testTitle)); + + runner.run(function (failureCount) { + failureCount.should.be.exactly(0); + runner.should.have.property('testResults'); + runner.testResults.should.have.property('pending'); + runner.testResults.pending.should.be.an.instanceOf(Array); + runner.testResults.pending.should.have.a.lengthOf(1); + + var pending = runner.testResults.pending[0]; + pending.should.have.property('title', testTitle); + + done(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/reporters/nyan.spec.js b/tests/lib/mocha-3.1.2/test/reporters/nyan.spec.js new file mode 100644 index 0000000000..07c455efd3 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/reporters/nyan.spec.js @@ -0,0 +1,31 @@ +'use strict'; + +var reporters = require('../../').reporters; +var NyanCat = reporters.Nyan; + +describe('nyan face', function () { + it('nyan face:(x .x) when "failures" at least one', function () { + var nyanCat = new NyanCat({on: function () {}}); + nyanCat.stats = { passes: 2, pending: 1, failures: 1 }; + nyanCat.face().should.equal('( x .x)'); + }); + + it('expected nyan face:(x .x) when "pending" at least one and no failing', function () { + var nyanCat = new NyanCat({on: function () {}}); + nyanCat.stats = { passes: 2, pending: 1, failures: 0 }; + nyanCat.face().should.equal('( o .o)'); + }); + + it('expected nyan face:(^ .^) when "passing" only', function () { + var nyanCat = new NyanCat({on: function () {}}); + nyanCat.stats = { passes: 1, pending: 0, failures: 0 }; + nyanCat.face().should.equal('( ^ .^)'); + }); + + it('nyan face:(- .-) when otherwise', function (done) { + var nyanCat = new NyanCat({on: function () {}}); + nyanCat.stats = { passes: 0, pending: 0, failures: 0 }; + nyanCat.face().should.equal('( - .-)'); + done(); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/runnable.spec.js b/tests/lib/mocha-3.1.2/test/runnable.spec.js new file mode 100644 index 0000000000..67cfcca38a --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/runnable.spec.js @@ -0,0 +1,466 @@ +'use strict'; + +var mocha = require('../'); +var utils = mocha.utils; +var Runnable = mocha.Runnable; + +describe('Runnable(title, fn)', function () { + // For every test we poison the global time-related methods. + // runnable.js etc. should keep its own local copy, in order to fix GH-237. + // NB: we can't poison global.Date because the normal implementation of + // global.setTimeout uses it [1] so if the runnable.js keeps a copy of + // global.setTimeout (like it's supposed to), that will blow up. + // [1]: https://github.com/joyent/node/blob/7fc835afe362ebd30a0dbec81d3360bd24525222/lib/timers.js#L74 + var setTimeout = global.setTimeout; + var setInterval = global.setInterval; + var clearTimeout = global.clearTimeout; + var clearInterval = global.clearInterval; + + function poisonPill () { + throw new Error("Don't use global time-related stuff."); + } + + beforeEach(function () { + global.setTimeout = + global.setInterval = + global.clearTimeout = + global.clearInterval = poisonPill; + }); + + afterEach(function () { + global.setTimeout = setTimeout; + global.setInterval = setInterval; + global.clearTimeout = clearTimeout; + global.clearInterval = clearInterval; + }); + + describe('#timeout(ms)', function () { + it('should set the timeout', function () { + var run = new Runnable(); + run.timeout(1000); + run.timeout().should.equal(1000); + }); + }); + + describe('#timeout(ms) when ms>2^31', function () { + it('should set disabled', function () { + var run = new Runnable(); + run.timeout(1e10); + run.enableTimeouts().should.be.false; + }); + }); + + describe('#enableTimeouts(enabled)', function () { + it('should set enabled', function () { + var run = new Runnable(); + run.enableTimeouts(false); + run.enableTimeouts().should.equal(false); + }); + }); + + describe('#slow(ms)', function () { + var run; + + beforeEach(function () { + run = new Runnable(); + }); + + it('should set the slow threshold', function () { + run.slow(100); + run.slow().should.equal(100); + }); + + it('should not set the slow threshold if the parameter is not passed', function () { + run.slow(); + run.slow().should.equal(75); + }); + + it('should not set the slow threshold if the parameter is undefined', function () { + run.slow(undefined); + run.slow().should.equal(75); + }); + }); + + describe('.title', function () { + it('should be present', function () { + new Runnable('foo').title.should.equal('foo'); + }); + }); + + describe('when arity >= 1', function () { + it('should be .async', function () { + var run = new Runnable('foo', function (done) {}); + run.async.should.equal(1); + run.sync.should.be.false(); + }); + }); + + describe('when arity == 0', function () { + it('should be .sync', function () { + var run = new Runnable('foo', function () {}); + run.async.should.be.equal(0); + run.sync.should.be.true(); + }); + }); + + describe('#globals', function () { + it('should allow for whitelisting globals', function (done) { + var test = new Runnable('foo', function () {}); + test.async.should.be.equal(0); + test.sync.should.be.true(); + test.globals(['foobar']); + test.run(done); + }); + }); + + describe('#retries(n)', function () { + it('should set the number of retries', function () { + var run = new Runnable(); + run.retries(1); + run.retries().should.equal(1); + }); + }); + + describe('.run(fn)', function () { + describe('when .pending', function () { + it('should not invoke the callback', function (done) { + var test = new Runnable('foo', function () { + throw new Error('should not be called'); + }); + + test.pending = true; + test.run(done); + }); + }); + + describe('when sync', function () { + describe('without error', function () { + it('should invoke the callback', function (done) { + var calls = 0; + var test = new Runnable('foo', function () { + ++calls; + }); + + test.run(function (err) { + calls.should.equal(1); + test.duration.should.be.type('number'); + done(err); + }); + }); + }); + + describe('when an exception is thrown', function () { + it('should invoke the callback', function (done) { + var calls = 0; + var test = new Runnable('foo', function () { + ++calls; + throw new Error('fail'); + }); + + test.run(function (err) { + calls.should.equal(1); + err.message.should.equal('fail'); + done(); + }); + }); + }); + + describe('when an exception is thrown and is allowed to remain uncaught', function () { + it('throws an error when it is allowed', function (done) { + var test = new Runnable('foo', function () { + throw new Error('fail'); + }); + test.allowUncaught = true; + function fail () { + test.run(function () {}); + } + fail.should.throw('fail'); + done(); + }); + }); + }); + + describe('when timeouts are disabled', function () { + it('should not error with timeout', function (done) { + var test = new Runnable('foo', function (done) { + setTimeout(process.nextTick.bind(undefined, done), 2); + }); + test.timeout(1); + test.enableTimeouts(false); + test.run(done); + }); + }); + + describe('when async', function () { + describe('without error', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function (done) { + process.nextTick(done); + }); + + test.run(done); + }); + }); + + describe('when the callback is invoked several times', function () { + describe('without an error', function () { + it('should emit a single "error" event', function (done) { + var calls = 0; + var errCalls = 0; + + var test = new Runnable('foo', function (done) { + process.nextTick(done); + process.nextTick(done); + process.nextTick(done); + process.nextTick(done); + }); + + test.on('error', function (err) { + ++errCalls; + err.message.should.equal('done() called multiple times'); + calls.should.equal(1); + errCalls.should.equal(1); + done(); + }); + + test.run(function () { + ++calls; + }); + }); + }); + + describe('with an error', function () { + it('should emit a single "error" event', function (done) { + var calls = 0; + var errCalls = 0; + + var test = new Runnable('foo', function (done) { + done(new Error('fail')); + process.nextTick(done); + done(new Error('fail')); + process.nextTick(done); + process.nextTick(done); + }); + + test.on('error', function (err) { + ++errCalls; + err.message.should.equal('fail'); + calls.should.equal(1); + errCalls.should.equal(1); + done(); + }); + + test.run(function () { + ++calls; + }); + }); + }); + }); + + describe('when an exception is thrown', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function (done) { + throw new Error('fail'); + }); + + test.run(function (err) { + err.message.should.equal('fail'); + done(); + }); + }); + + it('should not throw its own exception if passed a non-object', function (done) { + var test = new Runnable('foo', function (done) { + /* eslint no-throw-literal: off */ + throw null; + }); + + test.run(function (err) { + err.message.should.equal(utils.undefinedError().message); + done(); + }); + }); + }); + + describe('when an exception is thrown and is allowed to remain uncaught', function () { + it('throws an error when it is allowed', function (done) { + var test = new Runnable('foo', function (done) { + throw new Error('fail'); + }); + test.allowUncaught = true; + function fail () { + test.run(function () {}); + } + fail.should.throw('fail'); + done(); + }); + }); + + describe('when an error is passed', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function (done) { + done(new Error('fail')); + }); + + test.run(function (err) { + err.message.should.equal('fail'); + done(); + }); + }); + }); + + describe('when done() is invoked with a non-Error object', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function (done) { + done({ error: 'Test error' }); + }); + + test.run(function (err) { + err.message.should.equal('done() invoked with non-Error: {"error":"Test error"}'); + done(); + }); + }); + }); + + describe('when done() is invoked with a string', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function (done) { + done('Test error'); + }); + + test.run(function (err) { + err.message.should.equal('done() invoked with non-Error: Test error'); + done(); + }); + }); + }); + + it('should allow updating the timeout', function (done) { + var callCount = 0; + var increment = function () { + callCount++; + }; + var test = new Runnable('foo', function (done) { + setTimeout(increment, 1); + setTimeout(increment, 100); + }); + test.timeout(10); + test.run(function (err) { + err.should.be.ok(); + callCount.should.equal(1); + done(); + }); + }); + + it('should allow a timeout of 0'); + }); + + describe('when fn returns a promise', function () { + describe('when the promise is fulfilled with no value', function () { + var fulfilledPromise = { + then: function (fulfilled, rejected) { + process.nextTick(fulfilled); + } + }; + + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function () { + return fulfilledPromise; + }); + + test.run(done); + }); + }); + + describe('when the promise is fulfilled with a value', function () { + var fulfilledPromise = { + then: function (fulfilled, rejected) { + process.nextTick(function () { + fulfilled({}); + }); + } + }; + + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function () { + return fulfilledPromise; + }); + + test.run(done); + }); + }); + + describe('when the promise is rejected', function () { + var expectedErr = new Error('fail'); + var rejectedPromise = { + then: function (fulfilled, rejected) { + process.nextTick(function () { + rejected(expectedErr); + }); + } + }; + + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function () { + return rejectedPromise; + }); + + test.run(function (err) { + err.should.equal(expectedErr); + done(); + }); + }); + }); + + describe('when the promise is rejected without a reason', function () { + var expectedErr = new Error('Promise rejected with no or falsy reason'); + var rejectedPromise = { + then: function (fulfilled, rejected) { + process.nextTick(function () { + rejected(); + }); + } + }; + + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function () { + return rejectedPromise; + }); + + test.run(function (err) { + err.should.eql(expectedErr); + done(); + }); + }); + }); + + describe('when the promise takes too long to settle', function () { + var foreverPendingPromise = { + then: function () { } + }; + + it('should give the timeout error', function (done) { + var test = new Runnable('foo', function () { + return foreverPendingPromise; + }); + + test.timeout(10); + test.run(function (err) { + err.should.be.ok(); + done(); + }); + }); + }); + }); + + describe('when fn returns a non-promise', function () { + it('should invoke the callback', function (done) { + var test = new Runnable('foo', function () { + return { then: 'i ran my tests' }; + }); + + test.run(done); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/runner.spec.js b/tests/lib/mocha-3.1.2/test/runner.spec.js new file mode 100644 index 0000000000..7c69846ec8 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/runner.spec.js @@ -0,0 +1,436 @@ +'use strict'; + +var mocha = require('../'); +var Suite = mocha.Suite; +var Runner = mocha.Runner; +var Test = mocha.Test; +var Hook = mocha.Hook; +var path = require('path'); +var noop = mocha.utils.noop; + +describe('Runner', function () { + var suite; + var runner; + + beforeEach(function () { + suite = new Suite('Suite', 'root'); + runner = new Runner(suite); + }); + + describe('.grep()', function () { + it('should update the runner.total with number of matched tests', function () { + suite.addTest(new Test('im a test about lions', noop)); + suite.addTest(new Test('im another test about lions', noop)); + suite.addTest(new Test('im a test about bears', noop)); + var newRunner = new Runner(suite); + newRunner.grep(/lions/); + newRunner.total.should.equal(2); + }); + + it('should update the runner.total with number of matched tests when inverted', function () { + suite.addTest(new Test('im a test about lions', noop)); + suite.addTest(new Test('im another test about lions', noop)); + suite.addTest(new Test('im a test about bears', noop)); + var newRunner = new Runner(suite); + newRunner.grep(/lions/, true); + newRunner.total.should.equal(1); + }); + }); + + describe('.grepTotal()', function () { + it('should return the total number of matched tests', function () { + suite.addTest(new Test('im a test about lions', noop)); + suite.addTest(new Test('im another test about lions', noop)); + suite.addTest(new Test('im a test about bears', noop)); + runner.grep(/lions/); + runner.grepTotal(suite).should.equal(2); + }); + + it('should return the total number of matched tests when inverted', function () { + suite.addTest(new Test('im a test about lions', noop)); + suite.addTest(new Test('im another test about lions', noop)); + suite.addTest(new Test('im a test about bears', noop)); + runner.grep(/lions/, true); + runner.grepTotal(suite).should.equal(1); + }); + }); + + describe('.globalProps()', function () { + it('should include common non enumerable globals', function () { + var props = runner.globalProps(); + props.should.containEql('setTimeout'); + props.should.containEql('clearTimeout'); + props.should.containEql('setInterval'); + props.should.containEql('clearInterval'); + props.should.containEql('Date'); + props.should.containEql('XMLHttpRequest'); + }); + }); + + describe('.globals()', function () { + it('should default to the known globals', function () { + runner.globals().length.should.be.above(16); + }); + + it('should white-list globals', function () { + runner.globals(['foo', 'bar']); + runner.globals().should.containEql('foo'); + runner.globals().should.containEql('bar'); + }); + }); + + describe('.checkGlobals(test)', function () { + it('should allow variables that match a wildcard', function (done) { + runner.globals(['foo*', 'giz*']); + global.foo = 'baz'; + global.gizmo = 'quux'; + runner.checkGlobals(); + delete global.foo; + delete global.gizmo; + done(); + }); + + it('should emit "fail" when a new global is introduced', function (done) { + var test = new Test('im a test', noop); + runner.checkGlobals(); + global.foo = 'bar'; + runner.on('fail', function (_test, err) { + _test.should.equal(test); + err.message.should.equal('global leak detected: foo'); + delete global.foo; + done(); + }); + runner.checkGlobals(test); + }); + + it('should emit "fail" when a single new disallowed global is introduced after a single extra global is allowed', function (done) { + var doneCalled = false; + runner.globals('good'); + global.bad = 1; + runner.on('fail', function () { + delete global.bad; + done(); + doneCalled = true; + }); + runner.checkGlobals(new Test('yet another test', noop)); + if (!doneCalled) { + done(Error('Expected test failure did not occur.')); + } + }); + + it('should not fail when a new common global is introduced', function () { + // verify that the prop isn't enumerable + delete global.XMLHttpRequest; + global.propertyIsEnumerable('XMLHttpRequest').should.not.be.ok(); + + // create a new runner and keep a reference to the test. + var test = new Test('im a test about bears', noop); + suite.addTest(test); + var newRunner = new Runner(suite); + + // make the prop enumerable again. + global.XMLHttpRequest = function () {}; + global.propertyIsEnumerable('XMLHttpRequest').should.be.ok(); + + // verify the test hasn't failed. + newRunner.checkGlobals(test); + test.should.not.have.key('state'); + + // clean up our global space. + delete global.XMLHttpRequest; + }); + + it('should pluralize the error message when several are introduced', function (done) { + var test = new Test('im a test', noop); + runner.checkGlobals(); + global.foo = 'bar'; + global.bar = 'baz'; + runner.on('fail', function (_test, err) { + _test.should.equal(test); + err.message.should.equal('global leaks detected: foo, bar'); + delete global.foo; + delete global.bar; + done(); + }); + runner.checkGlobals(test); + }); + + it('should respect per test whitelisted globals', function () { + var test = new Test('im a test about lions', noop); + test.globals(['foo']); + + suite.addTest(test); + var runner = new Runner(suite); + + global.foo = 'bar'; + + // verify the test hasn't failed. + runner.checkGlobals(test); + test.should.not.have.key('state'); + + delete global.foo; + }); + + it('should respect per test whitelisted globals but still detect other leaks', function (done) { + var test = new Test('im a test about lions', noop); + test.globals(['foo']); + + suite.addTest(test); + + global.foo = 'bar'; + global.bar = 'baz'; + runner.on('fail', function (test, err) { + test.title.should.equal('im a test about lions'); + err.message.should.equal('global leak detected: bar'); + delete global.foo; + done(); + }); + runner.checkGlobals(test); + }); + + it('should emit "fail" when a global beginning with d is introduced', function (done) { + global.derp = 'bar'; + runner.on('fail', function () { + delete global.derp; + done(); + }); + runner.checkGlobals(new Test('herp', function () {})); + }); + }); + + describe('.hook(name, fn)', function () { + it('should execute hooks after failed test if suite bail is true', function (done) { + runner.fail(new Test('failed test', noop)); + suite.bail(true); + suite.afterEach(function () { + suite.afterAll(function () { + done(); + }); + }); + runner.hook('afterEach', function () {}); + runner.hook('afterAll', function () {}); + }); + }); + + describe('.fail(test, err)', function () { + it('should increment .failures', function () { + runner.failures.should.equal(0); + runner.fail(new Test('one', noop), {}); + runner.failures.should.equal(1); + runner.fail(new Test('two', noop), {}); + runner.failures.should.equal(2); + }); + + it('should set test.state to "failed"', function () { + var test = new Test('some test', noop); + runner.fail(test, 'some error'); + test.state.should.equal('failed'); + }); + + it('should emit "fail"', function (done) { + var test = new Test('some other test', noop); + var err = {}; + runner.on('fail', function (test, err) { + test.should.equal(test); + err.should.equal(err); + done(); + }); + runner.fail(test, err); + }); + + it('should emit a helpful message when failed with a string', function (done) { + var test = new Test('helpful test', noop); + var err = 'string'; + runner.on('fail', function (test, err) { + err.message.should.equal('the string "string" was thrown, throw an Error :)'); + done(); + }); + runner.fail(test, err); + }); + + it('should emit a the error when failed with an Error instance', function (done) { + var test = new Test('a test', noop); + var err = new Error('an error message'); + runner.on('fail', function (test, err) { + err.message.should.equal('an error message'); + done(); + }); + runner.fail(test, err); + }); + + it('should emit the error when failed with an Error-like object', function (done) { + var test = new Test('a test', noop); + var err = { message: 'an error message' }; + runner.on('fail', function (test, err) { + err.message.should.equal('an error message'); + done(); + }); + runner.fail(test, err); + }); + + it('should emit a helpful message when failed with an Object', function (done) { + var test = new Test('a test', noop); + var err = { x: 1 }; + runner.on('fail', function (test, err) { + err.message.should.equal('the object {\n "x": 1\n} was thrown, throw an Error :)'); + done(); + }); + runner.fail(test, err); + }); + + it('should emit a helpful message when failed with an Array', function (done) { + var test = new Test('a test', noop); + var err = [ + 1, + 2 + ]; + runner.on('fail', function (test, err) { + err.message.should.equal('the array [\n 1\n 2\n] was thrown, throw an Error :)'); + done(); + }); + runner.fail(test, err); + }); + + it('should recover if the error stack is not writable', function (done) { + var err = new Error('not evil'); + Object.defineProperty(err, 'stack', { + value: err.stack + }); + var test = new Test('a test', noop); + + runner.on('fail', function (test, err) { + err.message.should.equal('not evil'); + done(); + }); + + runner.fail(test, err); + }); + }); + + describe('.failHook(hook, err)', function () { + it('should increment .failures', function () { + runner.failures.should.equal(0); + runner.failHook(new Test('fail hook 1', noop), {}); + runner.failures.should.equal(1); + runner.failHook(new Test('fail hook 2', noop), {}); + runner.failures.should.equal(2); + }); + + it('should augment hook title with current test title', function () { + var hook = new Hook('"before each" hook'); + hook.ctx = { currentTest: new Test('should behave', noop) }; + + runner.failHook(hook, {}); + hook.title.should.equal('"before each" hook for "should behave"'); + + hook.ctx.currentTest = new Test('should obey', noop); + runner.failHook(hook, {}); + hook.title.should.equal('"before each" hook for "should obey"'); + }); + + it('should emit "fail"', function (done) { + var hook = new Hook(); + var err = {}; + runner.on('fail', function (hook, err) { + hook.should.equal(hook); + err.should.equal(err); + done(); + }); + runner.failHook(hook, err); + }); + + it('should emit "end" if suite bail is true', function (done) { + var hook = new Hook(); + var err = {}; + suite.bail(true); + runner.on('end', done); + runner.failHook(hook, err); + }); + + it('should not emit "end" if suite bail is not true', function (done) { + var hook = new Hook(); + var err = {}; + suite.bail(false); + runner.on('end', function () { + throw new Error('"end" was emit, but the bail is false'); + }); + runner.failHook(hook, err); + done(); + }); + }); + + describe('allowUncaught', function () { + it('should allow unhandled errors to propagate through', function (done) { + var newRunner = new Runner(suite); + newRunner.allowUncaught = true; + newRunner.test = new Test('failing test', function () { + throw new Error('allow unhandled errors'); + }); + function fail () { + newRunner.runTest(); + } + fail.should.throw('allow unhandled errors'); + done(); + }); + }); + + describe('stackTrace', function () { + var stack = [ + 'AssertionError: foo bar', + 'at EventEmitter.<anonymous> (/usr/local/dev/test.js:16:12)', + 'at Context.<anonymous> (/usr/local/dev/test.js:19:5)', + 'Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)', + 'Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:374:10)', + '/usr/local/lib/node_modules/mocha/lib/runner.js:452:12', + 'next (/usr/local/lib/node_modules/mocha/lib/runner.js:299:14)', + '/usr/local/lib/node_modules/mocha/lib/runner.js:309:7', + 'next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)', + 'Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)', + 'at processImmediate [as _immediateCallback] (timers.js:321:17)' + ]; + + describe('shortStackTrace', function () { + beforeEach(function () { + if (path.sep !== '/') { + this.skip(); + } + }); + + it('should prettify the stack-trace', function (done) { + var hook = new Hook(); + var err = new Error(); + // Fake stack-trace + err.stack = stack.join('\n'); + + runner.on('fail', function (hook, err) { + err.stack.should.equal(stack.slice(0, 3).join('\n')); + done(); + }); + runner.failHook(hook, err); + }); + }); + + describe('longStackTrace', function () { + beforeEach(function () { + if (path.sep !== '/') { + this.skip(); + } + }); + + it('should display the full stack-trace', function (done) { + var hook = new Hook(); + var err = new Error(); + // Fake stack-trace + err.stack = stack.join('\n'); + // Add --stack-trace option + runner.fullStackTrace = true; + + runner.on('fail', function (hook, err) { + err.stack.should.equal(stack.join('\n')); + done(); + }); + runner.failHook(hook, err); + }); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/sanity/sanity.spec.js b/tests/lib/mocha-3.1.2/test/sanity/sanity.spec.js new file mode 100644 index 0000000000..b918f1c4f9 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/sanity/sanity.spec.js @@ -0,0 +1,9 @@ +'use strict'; + +var assert = require('assert'); + +describe('a production installation of Mocha', function () { + it('should be able to execute a test', function () { + assert.ok(true); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/setup.js b/tests/lib/mocha-3.1.2/test/setup.js new file mode 100644 index 0000000000..0ffe34c7e5 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/setup.js @@ -0,0 +1,4 @@ +'use strict'; + +global.expect = require('expect.js'); +global.assert = require('assert'); diff --git a/tests/lib/mocha-3.1.2/test/suite.spec.js b/tests/lib/mocha-3.1.2/test/suite.spec.js new file mode 100644 index 0000000000..4cb62dd290 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/suite.spec.js @@ -0,0 +1,440 @@ +'use strict'; + +var mocha = require('../'); +var Suite = mocha.Suite; +var Test = mocha.Test; + +describe('Suite', function () { + describe('.clone()', function () { + beforeEach(function () { + this.suite = new Suite('To be cloned'); + this.suite._timeout = 3043; + this.suite._slow = 101; + this.suite._bail = true; + this.suite.suites.push(1); + this.suite.tests.push('hello'); + this.suite._beforeEach.push(2); + this.suite._beforeAll.push(3); + this.suite._afterEach.push(4); + this.suite._afterAll.push(5); + }); + + it('should copy the title', function () { + this.suite.clone().title.should.equal('To be cloned'); + }); + + it('should copy the timeout value', function () { + this.suite.clone().timeout().should.equal(3043); + }); + + it('should copy the slow value', function () { + this.suite.clone().slow().should.equal(101); + }); + + it('should copy the bail value', function () { + this.suite.clone().bail().should.be.true(); + }); + + it('should not copy the values from the suites array', function () { + this.suite.clone().suites.should.be.empty(); + }); + + it('should not copy the values from the tests array', function () { + this.suite.clone().tests.should.be.empty(); + }); + + it('should not copy the values from the _beforeEach array', function () { + this.suite.clone()._beforeEach.should.be.empty(); + }); + + it('should not copy the values from the _beforeAll array', function () { + this.suite.clone()._beforeAll.should.be.empty(); + }); + + it('should not copy the values from the _afterEach array', function () { + this.suite.clone()._afterEach.should.be.empty(); + }); + + it('should not copy the values from the _afterAll array', function () { + this.suite.clone()._afterAll.should.be.empty(); + }); + }); + + describe('.timeout()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when no argument is passed', function () { + it('should return the timeout value', function () { + this.suite.timeout().should.equal(2000); + }); + }); + + describe('when argument is passed', function () { + it('should return the Suite object', function () { + var newSuite = this.suite.timeout(5000); + newSuite.timeout().should.equal(5000); + }); + }); + }); + + describe('.slow()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when given a string', function () { + it('should parse it', function () { + this.suite.slow('5 seconds'); + this.suite.slow().should.equal(5000); + }); + }); + + describe('when no argument is passed', function () { + it('should return the slow value', function () { + this.suite.slow().should.equal(75); + }); + }); + + describe('when argument is passed', function () { + it('should return the Suite object', function () { + var newSuite = this.suite.slow(5000); + newSuite.slow().should.equal(5000); + }); + }); + }); + + describe('.bail()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + this.suite._bail = true; + }); + + describe('when no argument is passed', function () { + it('should return the bail value', function () { + this.suite.bail().should.be.true(); + }); + }); + + describe('when argument is passed', function () { + it('should return the Suite object', function () { + var newSuite = this.suite.bail(false); + newSuite.bail().should.be.false(); + }); + }); + }); + + describe('.beforeAll()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('wraps the passed in function in a Hook', function () { + it('adds it to _beforeAll', function () { + var fn = function () {}; + this.suite.beforeAll(fn); + + this.suite._beforeAll.should.have.length(1); + var beforeAllItem = this.suite._beforeAll[0]; + beforeAllItem.title.should.match(/^"before all" hook/); + beforeAllItem.fn.should.equal(fn); + }); + + it('appends title to hook', function () { + var fn = function () {}; + this.suite.beforeAll('test', fn); + + this.suite._beforeAll.should.have.length(1); + var beforeAllItem = this.suite._beforeAll[0]; + beforeAllItem.title.should.equal('"before all" hook: test'); + beforeAllItem.fn.should.equal(fn); + + function namedFn () {} + this.suite.beforeAll(namedFn); + this.suite._beforeAll.should.have.length(2); + beforeAllItem = this.suite._beforeAll[1]; + beforeAllItem.title.should.equal('"before all" hook: namedFn'); + beforeAllItem.fn.should.equal(namedFn); + }); + }); + }); + + describe('.afterAll()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('wraps the passed in function in a Hook', function () { + it('adds it to _afterAll', function () { + var fn = function () {}; + this.suite.afterAll(fn); + + this.suite._afterAll.should.have.length(1); + var afterAllItem = this.suite._afterAll[0]; + afterAllItem.title.should.match(/^"after all" hook/); + afterAllItem.fn.should.equal(fn); + }); + it('appends title to hook', function () { + var fn = function () {}; + this.suite.afterAll('test', fn); + + this.suite._afterAll.should.have.length(1); + var beforeAllItem = this.suite._afterAll[0]; + beforeAllItem.title.should.equal('"after all" hook: test'); + beforeAllItem.fn.should.equal(fn); + + function namedFn () {} + this.suite.afterAll(namedFn); + this.suite._afterAll.should.have.length(2); + beforeAllItem = this.suite._afterAll[1]; + beforeAllItem.title.should.equal('"after all" hook: namedFn'); + beforeAllItem.fn.should.equal(namedFn); + }); + }); + }); + + describe('.beforeEach()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('wraps the passed in function in a Hook', function () { + it('adds it to _beforeEach', function () { + var fn = function () {}; + this.suite.beforeEach(fn); + + this.suite._beforeEach.should.have.length(1); + var beforeEachItem = this.suite._beforeEach[0]; + beforeEachItem.title.should.match(/^"before each" hook/); + beforeEachItem.fn.should.equal(fn); + }); + + it('appends title to hook', function () { + var fn = function () {}; + this.suite.beforeEach('test', fn); + + this.suite._beforeEach.should.have.length(1); + var beforeAllItem = this.suite._beforeEach[0]; + beforeAllItem.title.should.equal('"before each" hook: test'); + beforeAllItem.fn.should.equal(fn); + + function namedFn () {} + this.suite.beforeEach(namedFn); + this.suite._beforeEach.should.have.length(2); + beforeAllItem = this.suite._beforeEach[1]; + beforeAllItem.title.should.equal('"before each" hook: namedFn'); + beforeAllItem.fn.should.equal(namedFn); + }); + }); + }); + + describe('.afterEach()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('wraps the passed in function in a Hook', function () { + it('adds it to _afterEach', function () { + var fn = function () {}; + this.suite.afterEach(fn); + + this.suite._afterEach.should.have.length(1); + var afterEachItem = this.suite._afterEach[0]; + afterEachItem.title.should.match(/^"after each" hook/); + afterEachItem.fn.should.equal(fn); + }); + + it('appends title to hook', function () { + var fn = function () {}; + this.suite.afterEach('test', fn); + + this.suite._afterEach.should.have.length(1); + var beforeAllItem = this.suite._afterEach[0]; + beforeAllItem.title.should.equal('"after each" hook: test'); + beforeAllItem.fn.should.equal(fn); + + function namedFn () {} + this.suite.afterEach(namedFn); + this.suite._afterEach.should.have.length(2); + beforeAllItem = this.suite._afterEach[1]; + beforeAllItem.title.should.equal('"after each" hook: namedFn'); + beforeAllItem.fn.should.equal(namedFn); + }); + }); + }); + + describe('.addSuite()', function () { + beforeEach(function () { + this.first = new Suite('First suite'); + this.first.timeout(4002); + this.first.slow(200); + this.second = new Suite('Second suite'); + this.first.addSuite(this.second); + }); + + it('sets the parent on the added Suite', function () { + this.second.parent.should.equal(this.first); + }); + + it('copies the timeout value', function () { + this.second.timeout().should.equal(4002); + }); + + it('copies the slow value', function () { + this.second.slow().should.equal(200); + }); + + it('adds the suite to the suites collection', function () { + this.first.suites.should.have.length(1); + this.first.suites[0].should.equal(this.second); + }); + + it('treats suite as pending if its parent is pending', function () { + this.first.pending = true; + this.second.isPending.should.be.true; + }); + }); + + // describe('.addTest()', function(){ + // beforeEach(function(){ + // this.suite = new Suite('A Suite', new Context); + // this.suite.timeout(4002); + // this.test = new Test('test'); + // this.suite.addTest(this.test); + // }); + // + // it('sets the parent on the added test', function(){ + // this.test.parent.should.equal(this.suite); + // }); + // + // it('copies the timeout value', function(){ + // this.test.timeout().should.equal(4002); + // }); + // + // it('adds the test to the tests collection', function(){ + // this.suite.tests.should.have.length(1); + // this.suite.tests[0].should.equal(this.test); + // }); + // }); + + describe('.fullTitle()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when there is no parent', function () { + it('returns the suite title', function () { + this.suite.fullTitle().should.equal('A Suite'); + }); + }); + + describe('when there is a parent', function () { + it('returns the combination of parent\'s and suite\'s title', function () { + var parentSuite = new Suite('I am a parent'); + parentSuite.addSuite(this.suite); + this.suite.fullTitle().should.equal('I am a parent A Suite'); + }); + }); + }); + + describe('.total()', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when there are no nested suites or tests', function () { + it('should return 0', function () { + this.suite.total().should.equal(0); + }); + }); + + describe('when there are several tests in the suite', function () { + it('should return the number', function () { + this.suite.addTest(new Test('a child test')); + this.suite.addTest(new Test('another child test')); + this.suite.total().should.equal(2); + }); + }); + }); + + describe('.eachTest(fn)', function () { + beforeEach(function () { + this.suite = new Suite('A Suite'); + }); + + describe('when there are no nested suites or tests', function () { + it('should return 0', function () { + var n = 0; + function fn () { n++; } + this.suite.eachTest(fn); + n.should.equal(0); + }); + }); + + describe('when there are several tests in the suite', function () { + it('should return the number', function () { + this.suite.addTest(new Test('a child test')); + this.suite.addTest(new Test('another child test')); + + var n = 0; + function fn () { n++; } + this.suite.eachTest(fn); + n.should.equal(2); + }); + }); + + describe('when there are several levels of nested suites', function () { + it('should return the number', function () { + this.suite.addTest(new Test('a child test')); + var suite = new Suite('a child suite'); + suite.addTest(new Test('a test in a child suite')); + this.suite.addSuite(suite); + + var n = 0; + function fn () { n++; } + this.suite.eachTest(fn); + n.should.equal(2); + }); + }); + }); + + describe('initialization', function () { + /* eslint no-new: off */ + it('should throw an error if the title isn\'t a string', function () { + (function () { + new Suite(undefined, 'root'); + }).should.throw(); + + (function () { + new Suite(function () {}, 'root'); + }).should.throw(); + }); + + it('should not throw if the title is a string', function () { + (function () { + new Suite('Bdd suite', 'root'); + }).should.not.throw(); + }); + }); +}); + +describe('Test', function () { + describe('initialization', function () { + it('should throw an error if the title isn\'t a string', function () { + (function () { + new Test(function () {}); + }).should.throw(); + + (function () { + new Test(undefined, function () {}); + }).should.throw(); + }); + + it('should not throw if the title is a string', function () { + (function () { + new Test('test-case', function () {}); + }).should.not.throw(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/test.spec.js b/tests/lib/mocha-3.1.2/test/test.spec.js new file mode 100644 index 0000000000..73c09b3b06 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/test.spec.js @@ -0,0 +1,77 @@ +'use strict'; + +var mocha = require('../'); +var should = require('should'); +var Test = mocha.Test; + +describe('Test', function () { + describe('.clone()', function () { + beforeEach(function () { + this._test = new Test('To be cloned', function () {}); + this._test._timeout = 3043; + this._test._slow = 101; + this._test._enableTimeouts = true; + this._test._retries = 3; + this._test._currentRetry = 1; + this._test._allowedGlobals = ['foo']; + this._test.parent = 'foo'; + this._test.file = 'bar'; + }); + + it('should copy the title', function () { + this._test.clone().title.should.equal('To be cloned'); + }); + + it('should copy the timeout value', function () { + this._test.clone().timeout().should.equal(3043); + }); + + it('should copy the slow value', function () { + this._test.clone().slow().should.equal(101); + }); + + it('should copy the enableTimeouts value', function () { + this._test.clone().enableTimeouts().should.be.true(); + }); + + it('should copy the retries value', function () { + this._test.clone().retries().should.equal(3); + }); + + it('should copy the currentRetry value', function () { + this._test.clone().currentRetry().should.equal(1); + }); + + it('should copy the globals value', function () { + this._test.clone().globals().should.not.be.empty(); + }); + + it('should copy the parent value', function () { + this._test.clone().parent.should.equal('foo'); + }); + + it('should copy the file value', function () { + this._test.clone().file.should.equal('bar'); + }); + }); + + describe('.isPending()', function () { + beforeEach(function () { + this._test = new Test('Is it skipped', function () {}); + }); + + it('should not be pending by default', function () { + should(this._test.isPending()).not.be.ok(); + }); + + it('should be pending when marked as such', function () { + this._test.pending = true; + should(this._test.isPending()).be.ok(); + }); + + it('should be pending when its parent is pending', function () { + this._test.parent = { isPending: function () { return true; } }; + should(this._test.isPending()).be.ok(); + }); + }); +}); diff --git a/tests/lib/mocha-3.1.2/test/utils.spec.js b/tests/lib/mocha-3.1.2/test/utils.spec.js new file mode 100644 index 0000000000..ccfd861a78 --- /dev/null +++ b/tests/lib/mocha-3.1.2/test/utils.spec.js @@ -0,0 +1,263 @@ +'use strict'; + +var mocha = require('..'); +var utils = mocha.utils; +var path = require('path'); +var JSON = require('json3'); + +describe('utils', function () { + describe('.clean()', function () { + var clean = utils.clean; + it('should remove the wrapping function declaration', function () { + clean('function (one, two, three) {\n//code\n}').should.equal('//code'); + }); + + it('should handle newlines in the function declaration', function () { + clean('function (one, two, three)\n {\n//code\n}').should.equal('//code'); + }); + + it('should remove space character indentation from the function body', function () { + clean(' //line1\n //line2').should.equal('//line1\n //line2'); + }); + + it('should remove tab character indentation from the function body', function () { + clean('\t//line1\n\t\t//line2').should.equal('//line1\n\t//line2'); + }); + + it('should handle functions with tabs in their declarations', function () { + clean('function\t(\t)\t{\n//code\n}').should.equal('//code'); + }); + + it('should handle named functions without space after name', function () { + clean('function withName() {\n//code\n}').should.equal('//code'); + }); + + it('should handle named functions with space after name', function () { + clean('function withName () {\n//code\n}').should.equal('//code'); + }); + + it('should handle functions with no space between the end and the closing brace', function () { + clean('function() {/*code*/}').should.equal('/*code*/'); + }); + + it('should handle functions with parentheses in the same line', function () { + clean('function() { if (true) { /* code */ } }').should.equal('if (true) { /* code */ }'); + }); + + it('should handle empty functions', function () { + clean('function() {}').should.equal(''); + }); + }); + + describe('.isBuffer()', function () { + var isBuffer = utils.isBuffer; + it('should test if object is a Buffer', function () { + isBuffer(new Buffer([0x01])).should.equal(true); + isBuffer({}).should.equal(false); + }); + }); + + describe('.map()', function () { + var map = utils.map; + it('should behave same as Array.prototype.map', function () { + var arr = [1, 2, 3]; + map(arr, JSON.stringify).should.eql(arr.map(JSON.stringify)); + }); + + it('should call the callback with 3 arguments[currentValue, index, array]', function () { + var index = 0; + map([1, 2, 3], function (e, i, arr) { + e.should.equal(arr[index]); + i.should.equal(index++); + }); + }); + + it('should apply with the given scope', function () { + var scope = {}; + map(['a', 'b', 'c'], function () { + this.should.equal(scope); + }, scope); + }); + }); + + describe('.parseQuery()', function () { + var parseQuery = utils.parseQuery; + it('should get queryString and return key-value object', function () { + parseQuery('?foo=1&bar=2&baz=3').should.eql({ + foo: '1', + bar: '2', + baz: '3' + }); + + parseQuery('?r1=^@(?!.*\\)$)&r2=m{2}&r3=^co.*').should.eql({ + r1: '^@(?!.*\\)$)', + r2: 'm{2}', + r3: '^co.*' + }); + }); + }); + + describe('.stackTraceFilter()', function () { + describe('on node', function () { + var filter = utils.stackTraceFilter(); + + describe('on POSIX OS', function () { + before(function () { + if (path.sep !== '/') { + this.skip(); + } + }); + + it('should get a stack-trace as a string and prettify it', function () { + var stack = [ + 'AssertionError: foo bar', + 'at EventEmitter.<anonymous> (/usr/local/dev/test.js:16:12)', + 'at Context.<anonymous> (/usr/local/dev/test.js:19:5)', + 'Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)', + 'Runner.runTest (/usr/local/lib/node_modules/mocha/lib/runner.js:374:10)', + '/usr/local/lib/node_modules/mocha/lib/runner.js:452:12', + 'next (/usr/local/lib/node_modules/mocha/lib/runner.js:299:14)', + '/usr/local/lib/node_modules/mocha/lib/runner.js:309:7', + 'next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)', + 'Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)', + 'at processImmediate [as _immediateCallback] (timers.js:321:17)' + ]; + filter(stack.join('\n')) + .should + .equal(stack.slice(0, 3) + .join('\n')); + + stack = [ + 'AssertionError: bar baz', + 'at /usr/local/dev/some-test-file.js:25:8', + 'at tryCatcher (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/util.js:24:31)', + 'at Promise._resolveFromResolver (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:439:31)', + 'at new Promise (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:53:37)', + 'at yourFunction (/usr/local/dev/own/tmp/test1.js:24:13)', + 'at Context.<anonymous> (/usr/local/dev/some-test-file:30:4)', + 'Test.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:218:15)', + 'next (/usr/local/lib/node_modules/mocha/lib/runner.js:248:23)', + 'Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)', + 'at processImmediate [as _immediateCallback] (timers.js:321:17)' + ]; + + filter(stack.join('\n')) + .should + .equal(stack.slice(0, 7) + .join('\n')); + }); + + it('does not ignore other bower_components and components', + function () { + var stack = [ + 'Error: failed', + 'at assert (index.html:11:26)', + 'at Context.<anonymous> (test.js:17:18)', + 'at bower_components/should/should.js:4827:7', + 'at next (file:///.../bower_components/should/should.js:4766:23)', + 'at components/should/5.0.0/should.js:4827:7', + 'at next (file:///.../components/should/5.0.0/should.js:4766:23)', + 'at file:///.../bower_components/mocha/mocha.js:4794:5', + 'at timeslice (.../components/mocha/mocha.js:6218:27)', + 'at Test.require.register.Runnable.run (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4463:15)', + 'at Runner.require.register.Runner.runTest (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4892:10)', + 'at file:///.../components/mochajs/mocha/2.1.0/mocha.js:4970:12', + 'at next (file:///.../components/mochajs/mocha/2.1.0/mocha.js:4817:14)' + ]; + filter(stack.join('\n')) + .should + .equal(stack.slice(0, 7) + .join('\n')); + }); + + it('should replace absolute with relative paths', function () { + var stack = [ + 'Error: ' + process.cwd() + '/bla.js has a problem', + 'at foo (' + process.cwd() + '/foo/index.js:13:226)', + 'at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)' + ]; + + var expected = [ + 'Error: ' + process.cwd() + '/bla.js has a problem', + 'at foo (foo/index.js:13:226)', + 'at bar (/usr/local/dev/own/tmp/node_modules/bluebird/js/main/promise.js:11:26)' + ]; + + filter(stack.join('\n')) + .should + .equal(expected.join('\n')); + }); + }); + + describe('on Windows', function () { + before(function () { + if (path.sep === '/') { + this.skip(); + } + }); + + it('should work on Windows', function () { + var stack = [ + 'Error: failed', + 'at Context.<anonymous> (C:\\Users\\ishida\\src\\test\\test\\mytest.js:5:9)', + 'at callFn (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runnable.js:326:21)', + 'at Test.Runnable.run (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runnable.js:319:7)', + 'at Runner.runTest (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:422:10)', + 'at C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:528:12', + 'at next (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:342:14)', + 'at C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:352:7', + 'at next (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:284:14)', + 'at Immediate._onImmediate (C:\\Users\\ishida\\src\\test\\node_modules\\mocha\\lib\\runner.js:320:5)' + ]; + filter(stack.join('\n')) + .should + .equal(stack.slice(0, 2) + .join('\n')); + }); + }); + }); + + describe('on browser', function () { + var filter; + before(function () { + global.document = true; + global.location = { href: 'localhost:3000/foo/bar/index.html' }; + filter = utils.stackTraceFilter(); + }); + it('does not strip out other bower_components', function () { + var stack = [ + 'Error: failed', + 'at assert (index.html:11:26)', + 'at Context.<anonymous> (test.js:17:18)', + 'at bower_components/should/should.js:4827:7', + 'at next (bower_components/should/should.js:4766:23)', + 'at components/should/5.0.0/should.js:4827:7', + 'at next (components/should/5.0.0/should.js:4766:23)', + 'at Runner.require.register.Runner.runTest (node_modules/mocha.js:4892:10)', + 'at localhost:3000/foo/bar/node_modules/mocha.js:4970:12', + 'at next (node_modules/mocha.js:4817:14)' + ]; + filter(stack.join('\n')).should.equal(stack.slice(0, 7).join('\n')); + }); + + after(function () { + delete global.document; + delete global.location; + }); + }); + }); + + describe('.isPromise', function () { + it('should return true if the value is Promise-ish', function () { + utils.isPromise({then: function () {}}).should.be.true; + }); + + it('should return false if the value is not an object', function () { + utils.isPromise(1).should.be.false; + }); + + it('should return false if the value is an object w/o a "then" function', function () { + utils.isPromise({}).should.be.false; + }); + }); +}); |