diff --git a/lib/mocha.js b/lib/mocha.js index d7d1d54709..1210f7ecfb 100644 --- a/lib/mocha.js +++ b/lib/mocha.js @@ -202,24 +202,24 @@ Mocha.prototype.reporter = function(reporter, reporterOptions) { _reporter = require(reporter); } catch (err) { if ( - err.code !== 'MODULE_NOT_FOUND' || - err.message.indexOf('Cannot find module') !== -1 + err.code === 'MODULE_NOT_FOUND' || + err.message.indexOf('Cannot find module') >= 0 ) { // Try to load reporters from a path (absolute or relative) try { - _reporter = require(path.resolve(process.cwd(), reporter)); + _reporter = require(path.resolve(reporter)); } catch (_err) { - _err.code !== 'MODULE_NOT_FOUND' || - _err.message.indexOf('Cannot find module') !== -1 - ? console.warn(sQuote(reporter) + ' reporter not found') - : console.warn( + _err.code === 'MODULE_NOT_FOUND' || + _err.message.indexOf('Cannot find module') >= 0 + ? utils.warn(sQuote(reporter) + ' reporter not found') + : utils.warn( sQuote(reporter) + ' reporter blew up with error:\n' + err.stack ); } } else { - console.warn( + utils.warn( sQuote(reporter) + ' reporter blew up with error:\n' + err.stack ); } diff --git a/package-lock.json b/package-lock.json index a7c70cbcdf..21ae2b1c3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -978,7 +978,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, @@ -1838,7 +1838,7 @@ }, "bl": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, "requires": { @@ -1861,7 +1861,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", "dev": true }, "body-parser": { @@ -3106,7 +3106,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -3149,7 +3149,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -3427,7 +3427,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { @@ -3630,7 +3630,7 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -3725,7 +3725,7 @@ }, "slice-ansi": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, @@ -4321,7 +4321,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -4334,7 +4334,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -4349,7 +4349,7 @@ "createerror": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/createerror/-/createerror-1.3.0.tgz", - "integrity": "sha512-w9UZUtkaGd8MfS7eMG7Sa0lV5vCJghqQfiOnwNVrPhbZScUp5h0jwYoAF933MKlotlG1JAJOCCT3xU6r+SDKNw==", + "integrity": "sha1-xma9TNa5TjVBU5ZWnUZJ3QzbMxM=", "dev": true }, "cross-env": { @@ -4422,7 +4422,7 @@ }, "css-color-names": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", "dev": true }, @@ -5059,7 +5059,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -5269,7 +5269,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, @@ -5573,7 +5573,7 @@ }, "es6-promisify": { "version": "5.0.0", - "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { @@ -6186,7 +6186,7 @@ }, "event-stream": { "version": "3.3.4", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { @@ -6214,7 +6214,7 @@ "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", "dev": true, "requires": { "md5.js": "^1.3.4", @@ -7223,7 +7223,7 @@ }, "debug": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", "dev": true, "requires": { @@ -7232,7 +7232,7 @@ }, "ms": { "version": "0.7.1", - "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", "dev": true }, @@ -7633,7 +7633,7 @@ "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "integrity": "sha1-5w2EuU2lOqN14R/jo1G+ZkLKRvg=", "dev": true, "requires": { "whatwg-encoding": "^1.0.1" @@ -7662,7 +7662,7 @@ }, "htmlescape": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true }, @@ -8591,7 +8591,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -9360,7 +9360,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -10392,7 +10392,7 @@ }, "map-stream": { "version": "0.1.0", - "resolved": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", "dev": true }, @@ -10601,7 +10601,7 @@ "markdown-toc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/markdown-toc/-/markdown-toc-1.2.0.tgz", - "integrity": "sha512-eOsq7EGd3asV0oBfmyqngeEIhrbkc7XVP63OwcJBIhH2EpG2PzFcbZdhy1jutXSlRBBVMNXHvMtSr5LAxSUvUg==", + "integrity": "sha1-RKFWBoREkDFK/ARESD+eexEiwzk=", "dev": true, "requires": { "concat-stream": "^1.5.2", @@ -10812,7 +10812,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -10828,7 +10828,7 @@ "dependencies": { "lru-cache": { "version": "2.5.0", - "resolved": "http://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.5.0.tgz", "integrity": "sha1-2COIrpyWC+y+oMc7uet5tsbOmus=", "dev": true } @@ -10853,7 +10853,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { @@ -10995,7 +10995,7 @@ "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -11283,7 +11283,7 @@ "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "integrity": "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw=", "dev": true, "requires": { "lower-case": "^1.1.1" @@ -12235,7 +12235,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, @@ -12256,7 +12256,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -12626,7 +12626,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -12712,7 +12712,7 @@ "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", "dev": true, "requires": { "chalk": "^1.1.3", @@ -12760,7 +12760,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -13559,7 +13559,7 @@ "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", "dev": true, "requires": { "chalk": "^1.1.3", @@ -14631,9 +14631,9 @@ "dev": true }, "rewiremock": { - "version": "3.13.9", - "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.13.9.tgz", - "integrity": "sha512-FDk5uCyvfwgYZtZ9MKdpg6QiSSdjB/a/vU5luKjoJddaqcZz5+u4dXhc3Qf4vNMvDXvnOyodNd1riE5yeqoxaA==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.1.tgz", + "integrity": "sha512-fxjaEv7Iq/mXURg0WLhcss/9jr5VJ8pPduTnYxwjwVaPNSaUZxVowxU9WwLdrQllxWLecb72WnGkurFL1m8Cxw==", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -14642,7 +14642,7 @@ "lodash.template": "^4.4.0", "node-libs-browser": "^2.1.0", "path-parse": "^1.0.5", - "wipe-node-cache": "^2.1.0", + "wipe-node-cache": "^2.1.2", "wipe-webpack-cache": "^2.1.0" } }, @@ -14730,7 +14730,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -14800,7 +14800,7 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "integrity": "sha1-KBYjTiN4vdxOU1T6tcqold9xANk=", "dev": true }, "saxes": { @@ -14853,7 +14853,7 @@ "dependencies": { "commander": { "version": "2.8.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, "requires": { @@ -15163,7 +15163,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -15246,7 +15246,7 @@ }, "shasum": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "requires": { @@ -15851,7 +15851,7 @@ }, "split": { "version": "0.3.3", - "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { @@ -15950,7 +15950,7 @@ }, "starts-with": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/starts-with/-/starts-with-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/starts-with/-/starts-with-1.0.2.tgz", "integrity": "sha1-Fnk6cp2J1M89T7LtovkIrjV/GW8=", "dev": true }, @@ -16005,7 +16005,7 @@ }, "stream-combiner": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", "dev": true, "requires": { @@ -16598,7 +16598,7 @@ "dependencies": { "bluebird": { "version": "2.9.34", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.9.34.tgz", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.9.34.tgz", "integrity": "sha1-L3tOyAIWMoqf3evfacjUlC/v99g=", "dev": true }, @@ -16758,7 +16758,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -16839,7 +16839,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -18465,7 +18465,7 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "integrity": "sha1-qFWYCx8LazWbodXZ+zmulB+qY60=", "dev": true }, "whatwg-encoding": { @@ -18537,9 +18537,9 @@ "dev": true }, "wipe-node-cache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.1.tgz", - "integrity": "sha512-b2LdVay9YDim1Y5CTGYXZFxi8MuB5H1QHFApQu9+SERwqYuS8dwh8M4hhXEBut/z8pi1BCfAtEQM8280iT/oJg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.2.tgz", + "integrity": "sha512-m7NXa8qSxBGMtdQilOu53ctMaIBXy93FOP04EC1Uf4bpsE+r+adfLKwIMIvGbABsznaSNxK/ErD4xXDyY5og9w==", "dev": true }, "wipe-webpack-cache": { diff --git a/package.json b/package.json index 777d26bd28..73b65cfb12 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "remark": "^11.0.2", "remark-github": "^8.0.0", "remark-inline-links": "^3.1.3", - "rewiremock": "^3.13.9", + "rewiremock": "^3.14.1", "rimraf": "^3.0.2", "sinon": "^9.0.1", "strip-ansi": "^6.0.0", diff --git a/test/node-unit/fixtures/wonky-reporter.fixture.js b/test/node-unit/fixtures/wonky-reporter.fixture.js new file mode 100644 index 0000000000..7ef80c00ac --- /dev/null +++ b/test/node-unit/fixtures/wonky-reporter.fixture.js @@ -0,0 +1 @@ +throw new Error('bad weirdness in this one'); diff --git a/test/node-unit/mocha.spec.js b/test/node-unit/mocha.spec.js index 456232da75..f716f7e8ea 100644 --- a/test/node-unit/mocha.spec.js +++ b/test/node-unit/mocha.spec.js @@ -1,31 +1,62 @@ 'use strict'; -const Mocha = require('../../lib/mocha'); -const utils = require('../../lib/utils'); +const path = require('path'); +const rewiremock = require('rewiremock/node'); const {createSandbox} = require('sinon'); +const {EventEmitter} = require('events'); -describe('Mocha', function() { - const opts = {reporter: utils.noop}; // no output - const dumbFilepath = require.resolve('./fixtures/dumb-module.fixture.js'); - const dumberFilepath = require.resolve('./fixtures/dumber-module.fixture.js'); +const MODULE_PATH = require.resolve('../../lib/mocha.js'); +const DUMB_FIXTURE_PATH = require.resolve('./fixtures/dumb-module.fixture.js'); +const DUMBER_FIXTURE_PATH = require.resolve( + './fixtures/dumber-module.fixture.js' +); - let mocha; +describe('Mocha', function() { + let stubs; + let opts; + let Mocha; let sandbox; beforeEach(function() { sandbox = createSandbox(); - mocha = new Mocha(opts); - delete require.cache[dumbFilepath]; - delete require.cache[dumberFilepath]; + opts = {reporter: sandbox.stub()}; + + stubs = {}; + stubs.utils = { + supportsEsModules: sandbox.stub().returns(false), + warn: sandbox.stub(), + isString: sandbox.stub(), + noop: sandbox.stub() + }; + stubs.suite = Object.assign(sandbox.createStubInstance(EventEmitter), { + slow: sandbox.stub(), + timeout: sandbox.stub(), + bail: sandbox.stub() + }); + stubs.Suite = sandbox.stub().returns(stubs.suite); + stubs.Suite.constants = {}; + + Mocha = rewiremock.proxy(MODULE_PATH, r => ({ + '../../lib/utils': r.with(stubs.utils).callThrough(), + '../../lib/suite': stubs.Suite + })); + delete require.cache[DUMB_FIXTURE_PATH]; + delete require.cache[DUMBER_FIXTURE_PATH]; }); afterEach(function() { - delete require.cache[dumbFilepath]; - delete require.cache[dumberFilepath]; + delete require.cache[DUMB_FIXTURE_PATH]; + delete require.cache[DUMBER_FIXTURE_PATH]; sandbox.restore(); }); describe('instance method', function() { + let mocha; + + beforeEach(function() { + mocha = new Mocha(opts); + }); + describe('addFile()', function() { it('should add the given file to the files array', function() { mocha.addFile('some-file.js'); @@ -40,9 +71,12 @@ describe('Mocha', function() { describe('loadFiles()', function() { it('should load all files from the files array', function() { this.timeout(1000); - mocha.files = [dumbFilepath, dumberFilepath]; + mocha.files = [DUMB_FIXTURE_PATH, DUMBER_FIXTURE_PATH]; mocha.loadFiles(); - expect(require.cache, 'to have keys', [dumbFilepath, dumberFilepath]); + expect(require.cache, 'to have keys', [ + DUMB_FIXTURE_PATH, + DUMBER_FIXTURE_PATH + ]); }); it('should execute the optional callback if given', function() { @@ -54,13 +88,13 @@ describe('Mocha', function() { describe('unloadFiles()', function() { it('should delegate Mocha.unloadFile() for each item in its list of files', function() { - mocha.files = [dumbFilepath, dumberFilepath]; + mocha.files = [DUMB_FIXTURE_PATH, DUMBER_FIXTURE_PATH]; sandbox.stub(Mocha, 'unloadFile'); mocha.unloadFiles(); expect(Mocha.unloadFile, 'to have a call exhaustively satisfying', [ - dumbFilepath + DUMB_FIXTURE_PATH ]) - .and('to have a call exhaustively satisfying', [dumberFilepath]) + .and('to have a call exhaustively satisfying', [DUMBER_FIXTURE_PATH]) .and('was called twice'); }); @@ -68,14 +102,97 @@ describe('Mocha', function() { expect(mocha.unloadFiles(), 'to be', mocha); }); }); + + describe('reporter()', function() { + describe('when a reporter exists relative to the cwd', function() { + beforeEach(function() { + // DANGER! + sandbox + .stub(process, 'cwd') + .returns(path.resolve(__dirname, '..', '..', 'lib', 'reporters')); + }); + + it('should load from current working directory', function() { + expect(function() { + mocha.reporter('./spec.js'); + }, 'not to throw'); + }); + + describe('when the reporter throws upon load', function() { + it('should throw "invalid reporter" exception', function() { + expect( + function() { + mocha.reporter( + '../../test/node-unit/fixtures/wonky-reporter.fixture.js' + ); + }, + 'to throw', + { + code: 'ERR_MOCHA_INVALID_REPORTER' + } + ); + }); + + it('should warn about the error before throwing', function() { + try { + mocha.reporter( + '../../test/node-unit/fixtures/wonky-reporter.fixture.js' + ); + } catch (ignored) { + } finally { + expect(stubs.utils.warn, 'to have a call satisfying', [ + expect.it('to match', /reporter blew up/) + ]); + } + }); + }); + }); + + describe('when a reporter exists relative to the "mocha" module path', function() { + it('should load from module path', function() { + expect(function() { + mocha.reporter('./reporters/spec'); + }, 'not to throw'); + }); + + describe('when the reporter throws upon load', function() { + it('should throw "invalid reporter" exception', function() { + expect( + function() { + mocha.reporter( + '../../test/node-nit/fixtures/wonky-reporter.fixture.js' + ); + }, + 'to throw', + { + code: 'ERR_MOCHA_INVALID_REPORTER' + } + ); + }); + + it('should warn about the error before throwing', function() { + try { + mocha.reporter( + require.resolve('./fixtures/wonky-reporter.fixture.js') + ); + } catch (ignored) { + } finally { + expect(stubs.utils.warn, 'to have a call satisfying', [ + expect.it('to match', /reporter blew up/) + ]); + } + }); + }); + }); + }); }); describe('static method', function() { describe('unloadFile()', function() { it('should unload a specific file from cache', function() { - require(dumbFilepath); - Mocha.unloadFile(dumbFilepath); - expect(require.cache, 'not to have key', dumbFilepath); + require(DUMB_FIXTURE_PATH); + Mocha.unloadFile(DUMB_FIXTURE_PATH); + expect(require.cache, 'not to have key', DUMB_FIXTURE_PATH); }); }); }); diff --git a/test/unit/mocha.spec.js b/test/unit/mocha.spec.js index 8839a2d0ed..63f7c54847 100644 --- a/test/unit/mocha.spec.js +++ b/test/unit/mocha.spec.js @@ -1,15 +1,86 @@ 'use strict'; -var utils = require('../../lib/utils'); -var Mocha = require('../../lib/mocha'); var sinon = require('sinon'); +var EventEmitter = require('events').EventEmitter; +var Mocha = require('../../lib/mocha'); +var utils = require('../../lib/utils'); describe('Mocha', function() { - var opts = {reporter: utils.noop}; // no output + /** + * Options for `Mocha` constructor + */ + var opts; + + /** + * Sinon sandbox + * @see https://sinonjs.org/releases/v9.0.2/sandbox/ + */ var sandbox; + /** + * Stub `Runner` constructor; returns a stubbed `EventEmitter` + */ + var Runner; + + /** + * Stub `Suite` constructor; returns a stubbed `EventEmitter` + */ + var Suite; + + /** + * Stub `Suite` instance (root suite in our case) + */ + var suite; + + /** + * Stub `Runner` (`EventEmitter`) instance + */ + var runner; + + /** + * Stub `Base` reporter constructor + */ + var Base; + + /** + * Instance of a hypothetical reporter + */ + var reporterInstance; + beforeEach(function() { sandbox = sinon.createSandbox(); + reporterInstance = {}; + opts = {reporter: sandbox.stub().returns(reporterInstance)}; + Base = sandbox.stub().returns({}); + runner = Object.assign(sandbox.createStubInstance(EventEmitter), { + run: sandbox + .stub() + .callsArgAsync(0) + .returnsThis(), + globals: sandbox.stub(), + grep: sandbox.stub() + }); + Runner = sandbox.stub().returns(runner); + // the Runner constructor is the main export, and constants is a static prop. + // we don't need the constants themselves, but the object cannot be undefined + Runner.constants = {}; + suite = Object.assign(sandbox.createStubInstance(EventEmitter), { + slow: sandbox.stub(), + timeout: sandbox.stub(), + bail: sandbox.stub() + }); + Suite = sandbox.stub().returns(suite); + Suite.constants = {}; + + sandbox.stub(utils, 'supportsEsModules').returns(false); + sandbox.stub(utils, 'warn'); + sandbox.stub(utils, 'isString'); + sandbox.stub(utils, 'noop'); + + Mocha.Runner = Runner; + Mocha.reporters.Base = Mocha.reporters.base = Base; + sandbox.stub(Mocha.reporters, 'spec'); + Mocha.Suite = Suite; }); afterEach(function() { @@ -22,7 +93,7 @@ describe('Mocha', function() { sandbox.stub(Mocha.prototype, 'global').returnsThis(); }); - describe('when "options.timeout" is `undefined`', function() { + describe('when `timeout` option is `undefined`', function() { it('should not attempt to set timeout', function() { // eslint-disable-next-line no-new new Mocha({timeout: undefined}); @@ -30,7 +101,7 @@ describe('Mocha', function() { }); }); - describe('when "options.timeout" is `false`', function() { + describe('when `timeout` is `false`', function() { it('should set a timeout of 0', function() { // eslint-disable-next-line no-new new Mocha({timeout: false}); @@ -40,8 +111,8 @@ describe('Mocha', function() { }); }); - describe('when "options.global" is provided', function() { - it('should pass "options.global" to #global()', function() { + describe('when `global` option is provided', function() { + it('should configure `global` option', function() { // eslint-disable-next-line no-new new Mocha({global: ['singular']}); expect(Mocha.prototype.global, 'to have a call satisfying', [ @@ -51,400 +122,501 @@ describe('Mocha', function() { }); }); - describe('#allowUncaught()', function() { - it('should set the allowUncaught option to true', function() { - var mocha = new Mocha(opts); - mocha.allowUncaught(); - expect(mocha.options, 'to have property', 'allowUncaught', true); - }); + describe('instance method', function() { + var mocha; - it('should set the allowUncaught option to false', function() { - var mocha = new Mocha(opts); - mocha.allowUncaught(false); - expect(mocha.options, 'to have property', 'allowUncaught', false); + beforeEach(function() { + mocha = new Mocha(opts); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.allowUncaught(), 'to be', mocha); - }); - }); + describe('allowUncaught()', function() { + it('should set the allowUncaught option to true', function() { + mocha.allowUncaught(); + expect(mocha.options, 'to have property', 'allowUncaught', true); + }); - describe('#asyncOnly()', function() { - it('should set the asyncOnly option to true', function() { - var mocha = new Mocha(opts); - mocha.asyncOnly(); - expect(mocha.options, 'to have property', 'asyncOnly', true); - }); + it('should set the allowUncaught option to false', function() { + mocha.allowUncaught(false); + expect(mocha.options, 'to have property', 'allowUncaught', false); + }); - it('should set the asyncOnly option to false', function() { - var mocha = new Mocha(opts); - mocha.asyncOnly(false); - expect(mocha.options, 'to have property', 'asyncOnly', false); + it('should be chainable', function() { + expect(mocha.allowUncaught(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.asyncOnly(), 'to be', mocha); - }); - }); + describe('asyncOnly()', function() { + it('should set the asyncOnly option to true', function() { + mocha.asyncOnly(); + expect(mocha.options, 'to have property', 'asyncOnly', true); + }); - describe('#bail()', function() { - it('should set the suite._bail to true if there is no arguments', function() { - var mocha = new Mocha(opts); - mocha.bail(); - expect(mocha.suite._bail, 'to be', true); - }); + it('should set the asyncOnly option to false', function() { + mocha.asyncOnly(false); + expect(mocha.options, 'to have property', 'asyncOnly', false); + }); - it('should set the suite._bail to false', function() { - var mocha = new Mocha(opts); - mocha.bail(false); - expect(mocha.suite._bail, 'to be', false); + it('should be chainable', function() { + expect(mocha.asyncOnly(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.bail(), 'to be', mocha); - }); - }); + describe('bail()', function() { + describe('when provided no arguments', function() { + it('should set the "bail" flag on the root suite', function() { + mocha.bail(); + expect(suite.bail, 'to have a call satisfying', [true]).and( + 'was called once' + ); + }); + }); - describe('#checkLeaks()', function() { - it('should set the checkLeaks option to true', function() { - var mocha = new Mocha(opts); - mocha.checkLeaks(); - expect(mocha.options, 'to have property', 'checkLeaks', true); - }); + describe('when provided a falsy argument', function() { + it('should unset the "bail" flag on the root suite', function() { + mocha.bail(false); + expect(suite.bail, 'to have a call satisfying', [false]).and( + 'was called once' + ); + }); + }); - it('should set the checkLeaks option to false', function() { - var mocha = new Mocha(opts); - mocha.checkLeaks(false); - expect(mocha.options, 'to have property', 'checkLeaks', false); + it('should be chainable', function() { + expect(mocha.bail(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.checkLeaks(), 'to be', mocha); - }); - }); + describe('checkLeaks()', function() { + it('should set the checkLeaks option to true', function() { + mocha.checkLeaks(); + expect(mocha.options, 'to have property', 'checkLeaks', true); + }); - describe('#color()', function() { - it('should set the color option to true', function() { - var mocha = new Mocha(opts); - mocha.color(); - expect(mocha.options, 'to have property', 'color', true); - }); + it('should set the checkLeaks option to false', function() { + mocha.checkLeaks(false); + expect(mocha.options, 'to have property', 'checkLeaks', false); + }); - it('should set the color option to false', function() { - var mocha = new Mocha(opts); - mocha.color(false); - expect(mocha.options, 'to have property', 'color', false); + it('should be chainable', function() { + expect(mocha.checkLeaks(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.color(), 'to be', mocha); - }); - }); + describe('color()', function() { + it('should set the color option to true', function() { + mocha.color(); + expect(mocha.options, 'to have property', 'color', true); + }); - describe('#delay()', function() { - it('should set the delay option to true', function() { - var mocha = new Mocha(opts); - mocha.delay(); - expect(mocha.options, 'to have property', 'delay', true); - }); + it('should set the color option to false', function() { + mocha.color(false); + expect(mocha.options, 'to have property', 'color', false); + }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.delay(), 'to be', mocha); + it('should be chainable', function() { + expect(mocha.color(), 'to be', mocha); + }); }); - }); - describe('#diff()', function() { - it('should set the diff option to true', function() { - var mocha = new Mocha(opts); - mocha.diff(); - expect(mocha.options, 'to have property', 'diff', true); - }); + describe('delay()', function() { + it('should set the delay option to true', function() { + mocha.delay(); + expect(mocha.options, 'to have property', 'delay', true); + }); - it('should set the diff option to false', function() { - var mocha = new Mocha(opts); - mocha.diff(false); - expect(mocha.options, 'to have property', 'diff', false); + it('should be chainable', function() { + expect(mocha.delay(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.diff(), 'to be', mocha); - }); - }); + describe('diff()', function() { + it('should set the diff option to true', function() { + mocha.diff(); + expect(mocha.options, 'to have property', 'diff', true); + }); - describe('#forbidOnly()', function() { - it('should set the forbidOnly option to true', function() { - var mocha = new Mocha(opts); - mocha.forbidOnly(); - expect(mocha.options, 'to have property', 'forbidOnly', true); - }); + it('should set the diff option to false', function() { + mocha.diff(false); + expect(mocha.options, 'to have property', 'diff', false); + }); - it('should set the forbidOnly option to false', function() { - var mocha = new Mocha(opts); - mocha.forbidOnly(false); - expect(mocha.options, 'to have property', 'forbidOnly', false); + it('should be chainable', function() { + expect(mocha.diff(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.forbidOnly(), 'to be', mocha); - }); - }); + describe('forbidOnly()', function() { + it('should set the forbidOnly option to true', function() { + mocha.forbidOnly(); + expect(mocha.options, 'to have property', 'forbidOnly', true); + }); - describe('#forbidPending()', function() { - it('should set the forbidPending option to true', function() { - var mocha = new Mocha(opts); - mocha.forbidPending(); - expect(mocha.options, 'to have property', 'forbidPending', true); - }); + it('should set the forbidOnly option to false', function() { + mocha.forbidOnly(false); + expect(mocha.options, 'to have property', 'forbidOnly', false); + }); - it('should set the forbidPending option to false', function() { - var mocha = new Mocha(opts); - mocha.forbidPending(false); - expect(mocha.options, 'to have property', 'forbidPending', false); + it('should be chainable', function() { + expect(mocha.forbidOnly(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.forbidPending(), 'to be', mocha); - }); - }); + describe('forbidPending()', function() { + it('should set the forbidPending option to true', function() { + mocha.forbidPending(); + expect(mocha.options, 'to have property', 'forbidPending', true); + }); - describe('#fullTrace()', function() { - it('should set the fullTrace option to true', function() { - var mocha = new Mocha(opts); - mocha.fullTrace(); - expect(mocha.options, 'to have property', 'fullTrace', true); - }); + it('should set the forbidPending option to false', function() { + mocha.forbidPending(false); + expect(mocha.options, 'to have property', 'forbidPending', false); + }); - it('should set the fullTrace option to false', function() { - var mocha = new Mocha(opts); - mocha.fullTrace(false); - expect(mocha.options, 'to have property', 'fullTrace', false); + it('should be chainable', function() { + expect(mocha.forbidPending(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.fullTrace(), 'to be', mocha); - }); - }); + describe('fullTrace()', function() { + it('should set the fullTrace option to true', function() { + mocha.fullTrace(); + expect(mocha.options, 'to have property', 'fullTrace', true); + }); - describe('#global()', function() { - it('should be an empty array initially', function() { - var mocha = new Mocha(); - expect(mocha.options.global, 'to be empty'); - }); + it('should set the fullTrace option to false', function() { + mocha.fullTrace(false); + expect(mocha.options, 'to have property', 'fullTrace', false); + }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.global(), 'to be', mocha); + it('should be chainable', function() { + expect(mocha.fullTrace(), 'to be', mocha); + }); }); - describe('when argument is invalid', function() { - it('should not modify the whitelist when given empty string', function() { - var mocha = new Mocha(opts); - mocha.global(''); + describe('global()', function() { + it('should be an empty array initially', function() { expect(mocha.options.global, 'to be empty'); }); - it('should not modify the whitelist when given empty array', function() { - var mocha = new Mocha(opts); - mocha.global([]); - expect(mocha.options.global, 'to be empty'); + it('should be chainable', function() { + expect(mocha.global(), 'to be', mocha); }); - }); - describe('when argument is valid', function() { - var elem = 'foo'; - var elem2 = 'bar'; - var elem3 = 'baz'; + describe('when argument is invalid', function() { + it('should not modify the whitelist when given empty string', function() { + mocha.global(''); + expect(mocha.options.global, 'to be empty'); + }); - it('should add string to the whitelist', function() { - var mocha = new Mocha(opts); - mocha.global(elem); - expect(mocha.options.global, 'to contain', elem); - expect(mocha.options.global, 'to have length', 1); + it('should not modify the whitelist when given empty array', function() { + mocha.global([]); + expect(mocha.options.global, 'to be empty'); + }); }); - it('should add contents of string array to the whitelist', function() { - var mocha = new Mocha(opts); - var elems = [elem, elem2]; - mocha.global(elems); - expect(mocha.options.global, 'to contain', elem, elem2); - expect(mocha.options.global, 'to have length', elems.length); + describe('when argument is valid', function() { + var elem = 'foo'; + var elem2 = 'bar'; + var elem3 = 'baz'; + + it('should add string to the whitelist', function() { + mocha.global(elem); + expect(mocha.options.global, 'to contain', elem); + expect(mocha.options.global, 'to have length', 1); + }); + + it('should add contents of string array to the whitelist', function() { + var elems = [elem, elem2]; + mocha.global(elems); + expect(mocha.options.global, 'to contain', elem, elem2); + expect(mocha.options.global, 'to have length', elems.length); + }); + + it('should not have duplicates', function() { + var mocha = new Mocha({global: [elem, elem2]}); + var elems = [elem, elem2, elem3]; + mocha.global(elems); + expect(mocha.options.global, 'to contain', elem, elem2, elem3); + expect(mocha.options.global, 'to have length', elems.length); + }); }); + }); - it('should not have duplicates', function() { - var mocha = new Mocha({global: [elem, elem2]}); - var elems = [elem, elem2, elem3]; - mocha.global(elems); - expect(mocha.options.global, 'to contain', elem, elem2, elem3); - expect(mocha.options.global, 'to have length', elems.length); + describe('growl()', function() { + describe('if capable of notifications', function() { + it('should set the growl option to true', function() { + mocha.isGrowlCapable = function forceEnable() { + return true; + }; + mocha.growl(); + expect(mocha.options, 'to have property', 'growl', true); + }); }); - }); - }); - describe('#growl()', function() { - describe('if capable of notifications', function() { - it('should set the growl option to true', function() { - var mocha = new Mocha(opts); - mocha.isGrowlCapable = function forceEnable() { - return true; - }; - mocha.growl(); - expect(mocha.options, 'to have property', 'growl', true); + describe('if not capable of notifications', function() { + it('should set the growl option to false', function() { + mocha.isGrowlCapable = function forceDisable() { + return false; + }; + mocha.growl(); + expect(mocha.options, 'to have property', 'growl', false); + }); }); - }); - describe('if not capable of notifications', function() { - it('should set the growl option to false', function() { - var mocha = new Mocha(opts); - mocha.isGrowlCapable = function forceDisable() { - return false; - }; - mocha.growl(); - expect(mocha.options, 'to have property', 'growl', false); + it('should be chainable', function() { + expect(mocha.growl(), 'to be', mocha); }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.growl(), 'to be', mocha); - }); - }); + describe('inlineDiffs()', function() { + it('should set the inlineDiffs option to true', function() { + mocha.inlineDiffs(); + expect(mocha.options, 'to have property', 'inlineDiffs', true); + }); - describe('#inlineDiffs()', function() { - it('should set the inlineDiffs option to true', function() { - var mocha = new Mocha(opts); - mocha.inlineDiffs(); - expect(mocha.options, 'to have property', 'inlineDiffs', true); - }); + it('should set the inlineDiffs option to false', function() { + mocha.inlineDiffs(false); + expect(mocha.options, 'to have property', 'inlineDiffs', false); + }); - it('should set the inlineDiffs option to false', function() { - var mocha = new Mocha(opts); - mocha.inlineDiffs(false); - expect(mocha.options, 'to have property', 'inlineDiffs', false); + it('should be chainable', function() { + expect(mocha.inlineDiffs(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.inlineDiffs(), 'to be', mocha); - }); - }); + describe('invert()', function() { + it('should set the invert option to true', function() { + mocha.invert(); + expect(mocha.options, 'to have property', 'invert', true); + }); - describe('#invert()', function() { - it('should set the invert option to true', function() { - var mocha = new Mocha(opts); - mocha.invert(); - expect(mocha.options, 'to have property', 'invert', true); + it('should be chainable', function() { + expect(mocha.invert(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.invert(), 'to be', mocha); - }); - }); + describe('noHighlighting()', function() { + // :NOTE: Browser-only option... + it('should set the noHighlighting option to true', function() { + mocha.noHighlighting(); + expect(mocha.options, 'to have property', 'noHighlighting', true); + }); - describe('#noHighlighting()', function() { - // :NOTE: Browser-only option... - it('should set the noHighlighting option to true', function() { - var mocha = new Mocha(opts); - mocha.noHighlighting(); - expect(mocha.options, 'to have property', 'noHighlighting', true); + it('should be chainable', function() { + expect(mocha.noHighlighting(), 'to be', mocha); + }); }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.noHighlighting(), 'to be', mocha); - }); - }); + describe('reporter()', function() { + it('should throw reporter error if an invalid reporter is given', function() { + expect( + function() { + mocha.reporter('invalidReporter'); + }, + 'to throw', + { + message: "invalid reporter 'invalidReporter'", + code: 'ERR_MOCHA_INVALID_REPORTER', + reporter: 'invalidReporter' + } + ); + }); - describe('#reporter()', function() { - it('should throw reporter error if an invalid reporter is given', function() { - var updatedOpts = {reporter: 'invalidReporter', reporterOptions: {}}; - var throwError = function() { - // eslint-disable-next-line no-new - new Mocha(updatedOpts); - }; - expect(throwError, 'to throw', { - message: "invalid reporter 'invalidReporter'", - code: 'ERR_MOCHA_INVALID_REPORTER', - reporter: 'invalidReporter' + it('should be chainable', function() { + expect(mocha.reporter(), 'to be', mocha); }); - }); - it('should be chainable', function() { - var mocha = new Mocha(opts); - expect(mocha.reporter(), 'to be', mocha); - }); + it('should keep reporterOption on options', function() { + var mocha = new Mocha({ + reporter: 'spec', + reporterOption: { + foo: 'bar' + } + }); + expect(mocha.options.reporterOption, 'to have property', 'foo', 'bar'); + // To support the legacy property name that can be used by reporters + expect(mocha.options.reporterOptions, 'to have property', 'foo', 'bar'); + }); - it('should keep reporterOption on options', function() { - var mocha = new Mocha({ - reporter: 'spec', - reporterOption: { - foo: 'bar' - } + it('should support legacy reporterOptions', function() { + var mocha = new Mocha({ + reporter: 'spec', + reporterOptions: { + foo: 'bar' + } + }); + expect(mocha.options.reporterOption, 'to have property', 'foo', 'bar'); + // To support the legacy property name that can be used by reporters + expect(mocha.options.reporterOptions, 'to have property', 'foo', 'bar'); }); - expect(mocha.options.reporterOption, 'to have property', 'foo', 'bar'); - // To support the legacy property name that can be used by reporters - expect(mocha.options.reporterOptions, 'to have property', 'foo', 'bar'); - }); - it('should support legacy reporterOptions', function() { - var mocha = new Mocha({ - reporter: 'spec', - reporterOptions: { - foo: 'bar' - } + describe('when a reporter does not exist', function() { + it('should throw an "invalid reporter" exception', function() { + expect( + function() { + mocha.reporter('no such thing'); + }, + 'to throw', + {code: 'ERR_MOCHA_INVALID_REPORTER'} + ); + }); }); - expect(mocha.options.reporterOption, 'to have property', 'foo', 'bar'); - // To support the legacy property name that can be used by reporters - expect(mocha.options.reporterOptions, 'to have property', 'foo', 'bar'); }); - }); - describe('#run(fn)', function() { - it('should execute the callback when complete', function(done) { - var mocha = new Mocha(opts); - sandbox.stub(Mocha.Runner.prototype, 'run').callsArg(0); - mocha.run(done); - }); + describe('run()', function() { + describe('when files have been added to the Mocha instance', function() { + beforeEach(function() { + sandbox.stub(mocha, 'loadFiles'); + mocha.addFile('some-file.js'); + }); + + describe('when Mocha is set to eagerly load files', function() { + it('should eagerly load files', function(done) { + mocha.run(function() { + expect(mocha.loadFiles, 'was called once'); + done(); + }); + }); + }); + + describe('when Mocha is set to lazily load files', function() { + beforeEach(function() { + mocha.loadAsync = true; + }); + + it('should not eagerly load files', function(done) { + mocha.run(function() { + expect(mocha.loadFiles, 'was not called'); + done(); + }); + }); + }); + }); - it('should not raise errors if callback was not provided', function() { - sandbox.stub(Mocha.Runner.prototype, 'run'); - var mocha = new Mocha(opts); - expect(function() { - mocha.run(); - }, 'not to throw'); - }); + describe('Runner initialization', function() { + it('should instantiate a Runner', function(done) { + mocha.run(function() { + expect(Runner, 'to have a call satisfying', { + calledWithNew: true, + args: [mocha.suite, mocha.options.delay] + }).and('was called once'); + done(); + }); + }); + + describe('when "grep" option is present', function() { + beforeEach(function() { + mocha.options.grep = /foo/; + mocha.options.invert = false; + }); + + it('should configure "grep"', function(done) { + mocha.run(function() { + expect(runner.grep, 'to have a call satisfying', [ + mocha.options.grep, + mocha.options.invert + ]).and('was called once'); + done(); + }); + }); + }); + + describe('when "global" option is present', function() { + beforeEach(function() { + mocha.options.global = ['foo', 'bar']; + }); + + it('should configure global vars', function(done) { + mocha.run(function() { + expect(runner.globals, 'to have a call satisfying', [ + mocha.options.global + ]).and('was called once'); + done(); + }); + }); + }); + }); - it('should catch the `start` event if no tests are provided', function(done) { - var mocha = new Mocha(opts); - mocha.run().on('start', done); - }); + describe('when "growl" options is present', function() { + beforeEach(function() { + mocha.options.growl = true; + sandbox.stub(Mocha.prototype, '_growl').returnsThis(); + }); + + it('should initialize growl support', function(done) { + mocha.run(function() { + expect(mocha._growl, 'to have a call satisfying', [runner]); + done(); + }); + }); + }); - it('should catch the `end` event if no tests are provided', function(done) { - var mocha = new Mocha(opts); - mocha.run().on('end', done); - }); + describe('Base reporter initialization', function() { + beforeEach(function() { + mocha.options.inlineDiffs = 'some value'; + mocha.options.diff = false; + }); + + describe('when "color" options is set', function() { + beforeEach(function() { + mocha.options.color = 'truthy'; + }); + + it('should configure the Base reporter', function(done) { + mocha.run(function() { + expect(Base, 'to exhaustively satisfy', { + inlineDiffs: 'some value', + hideDiff: true, + useColors: 'truthy' + }); + done(); + }); + }); + }); + + it('should configure the Base reporter', function(done) { + mocha.run(function() { + expect(Base, 'to exhaustively satisfy', { + inlineDiffs: 'some value', + hideDiff: true + }); + done(); + }); + }); + }); + + it('should instantiate a reporter', function(done) { + mocha.run(function() { + expect(opts.reporter, 'to have a call satisfying', { + calledWithNew: true, + args: [runner, mocha.options] + }).and('was called once'); + done(); + }); + }); + + it('should initialize the stats collector'); + + describe('when a reporter instance has a "done" method', function() { + beforeEach(function() { + reporterInstance.done = sandbox.stub().callsArgAsync(1); + }); + + it('should call the reporter "done" method', function(done) { + mocha.run(function() { + expect(reporterInstance.done, 'was called once'); + done(); + }); + }); + }); + + it('should execute the callback when complete', function(done) { + mocha.run(done); + }); - describe('#reporter("xunit")#run(fn)', function() { - // :TBD: Why does specifying reporter differentiate this test from preceding one it('should not raise errors if callback was not provided', function() { - var mocha = new Mocha(); + var mocha = new Mocha(opts); expect(function() { - try { - mocha.reporter('xunit').run(); - } catch (e) { - console.log(e); - expect.fail(e.message); - } + mocha.run(); }, 'not to throw'); }); });