aboutsummaryrefslogtreecommitdiff
path: root/node_modules/ava/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/ava/lib')
-rw-r--r--node_modules/ava/lib/assert.js449
-rw-r--r--node_modules/ava/lib/ava-error.js10
-rw-r--r--node_modules/ava/lib/ava-files.js287
-rw-r--r--node_modules/ava/lib/babel-config.js156
-rw-r--r--node_modules/ava/lib/beautify-stack.js72
-rw-r--r--node_modules/ava/lib/caching-precompiler.js108
-rw-r--r--node_modules/ava/lib/cli.js210
-rw-r--r--node_modules/ava/lib/code-excerpt.js57
-rw-r--r--node_modules/ava/lib/colors.js16
-rw-r--r--node_modules/ava/lib/concordance-options.js130
-rw-r--r--node_modules/ava/lib/concurrent.js64
-rw-r--r--node_modules/ava/lib/enhance-assert.js53
-rw-r--r--node_modules/ava/lib/fork.js176
-rw-r--r--node_modules/ava/lib/globals.js10
-rw-r--r--node_modules/ava/lib/logger.js92
-rw-r--r--node_modules/ava/lib/main.js105
-rw-r--r--node_modules/ava/lib/prefix-title.js21
-rw-r--r--node_modules/ava/lib/process-adapter.js103
-rw-r--r--node_modules/ava/lib/reporters/format-serialized-error.js26
-rw-r--r--node_modules/ava/lib/reporters/improper-usage-messages.js56
-rw-r--r--node_modules/ava/lib/reporters/mini.js333
-rw-r--r--node_modules/ava/lib/reporters/tap.js132
-rw-r--r--node_modules/ava/lib/reporters/verbose.js204
-rw-r--r--node_modules/ava/lib/run-status.js136
-rw-r--r--node_modules/ava/lib/runner.js232
-rw-r--r--node_modules/ava/lib/sequence.js94
-rw-r--r--node_modules/ava/lib/serialize-error.js99
-rw-r--r--node_modules/ava/lib/snapshot-manager.js418
-rw-r--r--node_modules/ava/lib/test-collection.js230
-rw-r--r--node_modules/ava/lib/test-worker.js141
-rw-r--r--node_modules/ava/lib/test.js441
-rw-r--r--node_modules/ava/lib/validate-test.js48
-rw-r--r--node_modules/ava/lib/watcher.js376
33 files changed, 0 insertions, 5085 deletions
diff --git a/node_modules/ava/lib/assert.js b/node_modules/ava/lib/assert.js
deleted file mode 100644
index 18009b97d..000000000
--- a/node_modules/ava/lib/assert.js
+++ /dev/null
@@ -1,449 +0,0 @@
-'use strict';
-const concordance = require('concordance');
-const coreAssert = require('core-assert');
-const observableToPromise = require('observable-to-promise');
-const isObservable = require('is-observable');
-const isPromise = require('is-promise');
-const concordanceOptions = require('./concordance-options').default;
-const concordanceDiffOptions = require('./concordance-options').diff;
-const enhanceAssert = require('./enhance-assert');
-const snapshotManager = require('./snapshot-manager');
-
-function formatDescriptorDiff(actualDescriptor, expectedDescriptor, options) {
- options = Object.assign({}, options, concordanceDiffOptions);
- return {
- label: 'Difference:',
- formatted: concordance.diffDescriptors(actualDescriptor, expectedDescriptor, options)
- };
-}
-
-function formatDescriptorWithLabel(label, descriptor) {
- return {
- label,
- formatted: concordance.formatDescriptor(descriptor, concordanceOptions)
- };
-}
-
-function formatWithLabel(label, value) {
- return formatDescriptorWithLabel(label, concordance.describe(value, concordanceOptions));
-}
-
-class AssertionError extends Error {
- constructor(opts) {
- super(opts.message || '');
- this.name = 'AssertionError';
-
- this.assertion = opts.assertion;
- this.fixedSource = opts.fixedSource;
- this.improperUsage = opts.improperUsage || false;
- this.operator = opts.operator;
- this.values = opts.values || [];
-
- // Raw expected and actual objects are stored for custom reporters
- // (such as wallaby.js), that manage worker processes directly and
- // use the values for custom diff views
- this.raw = opts.raw;
-
- // Reserved for power-assert statements
- this.statements = [];
-
- if (opts.stack) {
- this.stack = opts.stack;
- }
- }
-}
-exports.AssertionError = AssertionError;
-
-function getStack() {
- const obj = {};
- Error.captureStackTrace(obj, getStack);
- return obj.stack;
-}
-
-function wrapAssertions(callbacks) {
- const pass = callbacks.pass;
- const pending = callbacks.pending;
- const fail = callbacks.fail;
- const log = callbacks.log;
-
- const noop = () => {};
- const makeRethrow = reason => () => {
- throw reason;
- };
-
- const assertions = {
- pass() {
- pass(this);
- },
-
- fail(message) {
- fail(this, new AssertionError({
- assertion: 'fail',
- message: message || 'Test failed via `t.fail()`'
- }));
- },
-
- is(actual, expected, message) {
- if (Object.is(actual, expected)) {
- pass(this);
- } else {
- const result = concordance.compare(actual, expected, concordanceOptions);
- const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions);
- const expectedDescriptor = result.expected || concordance.describe(expected, concordanceOptions);
-
- if (result.pass) {
- fail(this, new AssertionError({
- assertion: 'is',
- message,
- raw: {actual, expected},
- values: [formatDescriptorWithLabel('Values are deeply equal to each other, but they are not the same:', actualDescriptor)]
- }));
- } else {
- fail(this, new AssertionError({
- assertion: 'is',
- message,
- raw: {actual, expected},
- values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)]
- }));
- }
- }
- },
-
- not(actual, expected, message) {
- if (Object.is(actual, expected)) {
- fail(this, new AssertionError({
- assertion: 'not',
- message,
- raw: {actual, expected},
- values: [formatWithLabel('Value is the same as:', actual)]
- }));
- } else {
- pass(this);
- }
- },
-
- log(text) {
- log(this, text);
- },
-
- deepEqual(actual, expected, message) {
- const result = concordance.compare(actual, expected, concordanceOptions);
- if (result.pass) {
- pass(this);
- } else {
- const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions);
- const expectedDescriptor = result.expected || concordance.describe(expected, concordanceOptions);
- fail(this, new AssertionError({
- assertion: 'deepEqual',
- message,
- raw: {actual, expected},
- values: [formatDescriptorDiff(actualDescriptor, expectedDescriptor)]
- }));
- }
- },
-
- notDeepEqual(actual, expected, message) {
- const result = concordance.compare(actual, expected, concordanceOptions);
- if (result.pass) {
- const actualDescriptor = result.actual || concordance.describe(actual, concordanceOptions);
- fail(this, new AssertionError({
- assertion: 'notDeepEqual',
- message,
- raw: {actual, expected},
- values: [formatDescriptorWithLabel('Value is deeply equal:', actualDescriptor)]
- }));
- } else {
- pass(this);
- }
- },
-
- throws(fn, err, message) {
- let promise;
- if (isPromise(fn)) {
- promise = fn;
- } else if (isObservable(fn)) {
- promise = observableToPromise(fn);
- } else if (typeof fn !== 'function') {
- fail(this, new AssertionError({
- assertion: 'throws',
- improperUsage: true,
- message: '`t.throws()` must be called with a function, Promise, or Observable',
- values: [formatWithLabel('Called with:', fn)]
- }));
- return;
- }
-
- let coreAssertThrowsErrorArg;
- if (typeof err === 'string') {
- const expectedMessage = err;
- coreAssertThrowsErrorArg = error => error.message === expectedMessage;
- } else {
- // Assume it's a constructor function or regular expression
- coreAssertThrowsErrorArg = err;
- }
-
- const test = (fn, stack) => {
- let actual;
- let threw = false;
- try {
- coreAssert.throws(() => {
- try {
- fn();
- } catch (err) {
- actual = err;
- threw = true;
- throw err;
- }
- }, coreAssertThrowsErrorArg);
- return actual;
- } catch (err) {
- throw new AssertionError({
- assertion: 'throws',
- message,
- stack,
- values: threw ?
- [formatWithLabel('Threw unexpected exception:', actual)] :
- null
- });
- }
- };
-
- if (promise) {
- // Record stack before it gets lost in the promise chain.
- const stack = getStack();
- const intermediate = promise.then(value => {
- throw new AssertionError({
- assertion: 'throws',
- message: 'Expected promise to be rejected, but it was resolved instead',
- values: [formatWithLabel('Resolved with:', value)]
- });
- }, reason => test(makeRethrow(reason), stack));
-
- pending(this, intermediate);
- // Don't reject the returned promise, even if the assertion fails.
- return intermediate.catch(noop);
- }
-
- try {
- const retval = test(fn);
- pass(this);
- return retval;
- } catch (err) {
- fail(this, err);
- }
- },
-
- notThrows(fn, message) {
- let promise;
- if (isPromise(fn)) {
- promise = fn;
- } else if (isObservable(fn)) {
- promise = observableToPromise(fn);
- } else if (typeof fn !== 'function') {
- fail(this, new AssertionError({
- assertion: 'notThrows',
- improperUsage: true,
- message: '`t.notThrows()` must be called with a function, Promise, or Observable',
- values: [formatWithLabel('Called with:', fn)]
- }));
- return;
- }
-
- const test = (fn, stack) => {
- try {
- coreAssert.doesNotThrow(fn);
- } catch (err) {
- throw new AssertionError({
- assertion: 'notThrows',
- message,
- stack,
- values: [formatWithLabel('Threw:', err.actual)]
- });
- }
- };
-
- if (promise) {
- // Record stack before it gets lost in the promise chain.
- const stack = getStack();
- const intermediate = promise.then(noop, reason => test(makeRethrow(reason), stack));
- pending(this, intermediate);
- // Don't reject the returned promise, even if the assertion fails.
- return intermediate.catch(noop);
- }
-
- try {
- test(fn);
- pass(this);
- } catch (err) {
- fail(this, err);
- }
- },
-
- ifError(actual, message) {
- if (actual) {
- fail(this, new AssertionError({
- assertion: 'ifError',
- message,
- values: [formatWithLabel('Error:', actual)]
- }));
- } else {
- pass(this);
- }
- },
-
- snapshot(expected, optionsOrMessage, message) {
- const options = {};
- if (typeof optionsOrMessage === 'string') {
- message = optionsOrMessage;
- } else if (optionsOrMessage) {
- options.id = optionsOrMessage.id;
- }
- options.expected = expected;
- options.message = message;
-
- let result;
- try {
- result = this._test.compareWithSnapshot(options);
- } catch (err) {
- if (!(err instanceof snapshotManager.SnapshotError)) {
- throw err;
- }
-
- const improperUsage = {name: err.name, snapPath: err.snapPath};
- if (err instanceof snapshotManager.VersionMismatchError) {
- improperUsage.snapVersion = err.snapVersion;
- improperUsage.expectedVersion = err.expectedVersion;
- }
-
- fail(this, new AssertionError({
- assertion: 'snapshot',
- message: message || 'Could not compare snapshot',
- improperUsage
- }));
- return;
- }
-
- if (result.pass) {
- pass(this);
- } else if (result.actual) {
- fail(this, new AssertionError({
- assertion: 'snapshot',
- message: message || 'Did not match snapshot',
- values: [formatDescriptorDiff(result.actual, result.expected, {invert: true})]
- }));
- } else {
- fail(this, new AssertionError({
- assertion: 'snapshot',
- message: message || 'No snapshot available, run with --update-snapshots'
- }));
- }
- }
- };
-
- const enhancedAssertions = enhanceAssert(pass, fail, {
- truthy(actual, message) {
- if (!actual) {
- throw new AssertionError({
- assertion: 'truthy',
- message,
- operator: '!!',
- values: [formatWithLabel('Value is not truthy:', actual)]
- });
- }
- },
-
- falsy(actual, message) {
- if (actual) {
- throw new AssertionError({
- assertion: 'falsy',
- message,
- operator: '!',
- values: [formatWithLabel('Value is not falsy:', actual)]
- });
- }
- },
-
- true(actual, message) {
- if (actual !== true) {
- throw new AssertionError({
- assertion: 'true',
- message,
- values: [formatWithLabel('Value is not `true`:', actual)]
- });
- }
- },
-
- false(actual, message) {
- if (actual !== false) {
- throw new AssertionError({
- assertion: 'false',
- message,
- values: [formatWithLabel('Value is not `false`:', actual)]
- });
- }
- },
-
- regex(string, regex, message) {
- if (typeof string !== 'string') {
- throw new AssertionError({
- assertion: 'regex',
- improperUsage: true,
- message: '`t.regex()` must be called with a string',
- values: [formatWithLabel('Called with:', string)]
- });
- }
- if (!(regex instanceof RegExp)) {
- throw new AssertionError({
- assertion: 'regex',
- improperUsage: true,
- message: '`t.regex()` must be called with a regular expression',
- values: [formatWithLabel('Called with:', regex)]
- });
- }
-
- if (!regex.test(string)) {
- throw new AssertionError({
- assertion: 'regex',
- message,
- values: [
- formatWithLabel('Value must match expression:', string),
- formatWithLabel('Regular expression:', regex)
- ]
- });
- }
- },
-
- notRegex(string, regex, message) {
- if (typeof string !== 'string') {
- throw new AssertionError({
- assertion: 'notRegex',
- improperUsage: true,
- message: '`t.notRegex()` must be called with a string',
- values: [formatWithLabel('Called with:', string)]
- });
- }
- if (!(regex instanceof RegExp)) {
- throw new AssertionError({
- assertion: 'notRegex',
- improperUsage: true,
- message: '`t.notRegex()` must be called with a regular expression',
- values: [formatWithLabel('Called with:', regex)]
- });
- }
-
- if (regex.test(string)) {
- throw new AssertionError({
- assertion: 'notRegex',
- message,
- values: [
- formatWithLabel('Value must not match expression:', string),
- formatWithLabel('Regular expression:', regex)
- ]
- });
- }
- }
- });
-
- return Object.assign(assertions, enhancedAssertions);
-}
-exports.wrapAssertions = wrapAssertions;
diff --git a/node_modules/ava/lib/ava-error.js b/node_modules/ava/lib/ava-error.js
deleted file mode 100644
index 05df6b349..000000000
--- a/node_modules/ava/lib/ava-error.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-
-class AvaError extends Error {
- constructor(message) {
- super(message);
- this.name = 'AvaError';
- }
-}
-
-module.exports = AvaError;
diff --git a/node_modules/ava/lib/ava-files.js b/node_modules/ava/lib/ava-files.js
deleted file mode 100644
index b6520da37..000000000
--- a/node_modules/ava/lib/ava-files.js
+++ /dev/null
@@ -1,287 +0,0 @@
-'use strict';
-const fs = require('fs');
-const path = require('path');
-const Promise = require('bluebird');
-const slash = require('slash');
-const globby = require('globby');
-const flatten = require('lodash.flatten');
-const autoBind = require('auto-bind');
-const defaultIgnore = require('ignore-by-default').directories();
-const multimatch = require('multimatch');
-
-function handlePaths(files, excludePatterns, globOptions) {
- // Convert Promise to Bluebird
- files = Promise.resolve(globby(files.concat(excludePatterns), globOptions));
-
- const searchedParents = new Set();
- const foundFiles = new Set();
-
- function alreadySearchingParent(dir) {
- if (searchedParents.has(dir)) {
- return true;
- }
-
- const parentDir = path.dirname(dir);
-
- if (parentDir === dir) {
- // We have reached the root path
- return false;
- }
-
- return alreadySearchingParent(parentDir);
- }
-
- return files
- .map(file => {
- file = path.resolve(globOptions.cwd, file);
-
- if (fs.statSync(file).isDirectory()) {
- if (alreadySearchingParent(file)) {
- return null;
- }
-
- searchedParents.add(file);
-
- let pattern = path.join(file, '**', '*.js');
-
- if (process.platform === 'win32') {
- // Always use `/` in patterns, harmonizing matching across platforms
- pattern = slash(pattern);
- }
-
- return handlePaths([pattern], excludePatterns, globOptions);
- }
-
- // `globby` returns slashes even on Windows. Normalize here so the file
- // paths are consistently platform-accurate as tests are run.
- return path.normalize(file);
- })
- .then(flatten)
- .filter(file => file && path.extname(file) === '.js')
- .filter(file => {
- if (path.basename(file)[0] === '_' && globOptions.includeUnderscoredFiles !== true) {
- return false;
- }
-
- return true;
- })
- .map(file => path.resolve(file))
- .filter(file => {
- const alreadyFound = foundFiles.has(file);
- foundFiles.add(file);
- return !alreadyFound;
- });
-}
-
-const defaultExcludePatterns = () => [
- '!**/node_modules/**',
- '!**/fixtures/**',
- '!**/helpers/**'
-];
-
-const defaultIncludePatterns = () => [
- 'test.js',
- 'test-*.js',
- 'test',
- '**/__tests__',
- '**/*.test.js'
-];
-
-const defaultHelperPatterns = () => [
- '**/__tests__/helpers/**/*.js',
- '**/__tests__/**/_*.js',
- '**/test/helpers/**/*.js',
- '**/test/**/_*.js'
-];
-
-const getDefaultIgnorePatterns = () => defaultIgnore.map(dir => `${dir}/**/*`);
-
-// Used on paths before they're passed to multimatch to harmonize matching
-// across platforms
-const matchable = process.platform === 'win32' ? slash : (path => path);
-
-class AvaFiles {
- constructor(options) {
- options = options || {};
-
- let files = (options.files || []).map(file => {
- // `./` should be removed from the beginning of patterns because
- // otherwise they won't match change events from Chokidar
- if (file.slice(0, 2) === './') {
- return file.slice(2);
- }
-
- return file;
- });
-
- if (files.length === 0) {
- files = defaultIncludePatterns();
- }
-
- this.excludePatterns = defaultExcludePatterns();
- this.files = files;
- this.sources = options.sources || [];
- this.cwd = options.cwd || process.cwd();
-
- autoBind(this);
- }
-
- findTestFiles() {
- return handlePaths(this.files, this.excludePatterns, {
- cwd: this.cwd,
- cache: Object.create(null),
- statCache: Object.create(null),
- realpathCache: Object.create(null),
- symlinks: Object.create(null)
- });
- }
-
- findTestHelpers() {
- return handlePaths(defaultHelperPatterns(), ['!**/node_modules/**'], {
- cwd: this.cwd,
- includeUnderscoredFiles: true,
- cache: Object.create(null),
- statCache: Object.create(null),
- realpathCache: Object.create(null),
- symlinks: Object.create(null)
- });
- }
-
- isSource(filePath) {
- let mixedPatterns = [];
- const defaultIgnorePatterns = getDefaultIgnorePatterns();
- const overrideDefaultIgnorePatterns = [];
-
- let hasPositivePattern = false;
- this.sources.forEach(pattern => {
- mixedPatterns.push(pattern);
-
- // TODO: Why not just `pattern[0] !== '!'`?
- if (!hasPositivePattern && pattern[0] !== '!') {
- hasPositivePattern = true;
- }
-
- // Extract patterns that start with an ignored directory. These need to be
- // rematched separately.
- if (defaultIgnore.indexOf(pattern.split('/')[0]) >= 0) {
- overrideDefaultIgnorePatterns.push(pattern);
- }
- });
-
- // Same defaults as used for Chokidar
- if (!hasPositivePattern) {
- mixedPatterns = ['package.json', '**/*.js'].concat(mixedPatterns);
- }
-
- filePath = matchable(filePath);
-
- // Ignore paths outside the current working directory.
- // They can't be matched to a pattern.
- if (/^\.\.\//.test(filePath)) {
- return false;
- }
-
- const isSource = multimatch(filePath, mixedPatterns).length === 1;
- if (!isSource) {
- return false;
- }
-
- const isIgnored = multimatch(filePath, defaultIgnorePatterns).length === 1;
- if (!isIgnored) {
- return true;
- }
-
- const isErroneouslyIgnored = multimatch(filePath, overrideDefaultIgnorePatterns).length === 1;
- if (isErroneouslyIgnored) {
- return true;
- }
-
- return false;
- }
-
- isTest(filePath) {
- const excludePatterns = this.excludePatterns;
- const initialPatterns = this.files.concat(excludePatterns);
-
- // Like in `api.js`, tests must be `.js` files and not start with `_`
- if (path.extname(filePath) !== '.js' || path.basename(filePath)[0] === '_') {
- return false;
- }
-
- // Check if the entire path matches a pattern
- if (multimatch(matchable(filePath), initialPatterns).length === 1) {
- return true;
- }
-
- // Check if the path contains any directory components
- const dirname = path.dirname(filePath);
- if (dirname === '.') {
- return false;
- }
-
- // Compute all possible subpaths. Note that the dirname is assumed to be
- // relative to the working directory, without a leading `./`.
- const subpaths = dirname.split(/[\\/]/).reduce((subpaths, component) => {
- const parent = subpaths[subpaths.length - 1];
-
- if (parent) {
- // Always use `/`` to makes multimatch consistent across platforms
- subpaths.push(`${parent}/${component}`);
- } else {
- subpaths.push(component);
- }
-
- return subpaths;
- }, []);
-
- // Check if any of the possible subpaths match a pattern. If so, generate a
- // new pattern with **/*.js.
- const recursivePatterns = subpaths
- .filter(subpath => multimatch(subpath, initialPatterns).length === 1)
- // Always use `/` to makes multimatch consistent across platforms
- .map(subpath => `${subpath}/**/*.js`);
-
- // See if the entire path matches any of the subpaths patterns, taking the
- // excludePatterns into account. This mimicks the behavior in api.js
- return multimatch(matchable(filePath), recursivePatterns.concat(excludePatterns)).length === 1;
- }
-
- getChokidarPatterns() {
- let paths = [];
- let ignored = [];
-
- this.sources.forEach(pattern => {
- if (pattern[0] === '!') {
- ignored.push(pattern.slice(1));
- } else {
- paths.push(pattern);
- }
- });
-
- // Allow source patterns to override the default ignore patterns. Chokidar
- // ignores paths that match the list of ignored patterns. It uses anymatch
- // under the hood, which supports negation patterns. For any source pattern
- // that starts with an ignored directory, ensure the corresponding negation
- // pattern is added to the ignored paths.
- const overrideDefaultIgnorePatterns = paths
- .filter(pattern => defaultIgnore.indexOf(pattern.split('/')[0]) >= 0)
- .map(pattern => `!${pattern}`);
-
- ignored = getDefaultIgnorePatterns().concat(ignored, overrideDefaultIgnorePatterns);
-
- if (paths.length === 0) {
- paths = ['package.json', '**/*.js', '**/*.snap'];
- }
-
- paths = paths.concat(this.files);
-
- return {
- paths,
- ignored
- };
- }
-}
-
-module.exports = AvaFiles;
-module.exports.defaultIncludePatterns = defaultIncludePatterns;
-module.exports.defaultExcludePatterns = defaultExcludePatterns;
diff --git a/node_modules/ava/lib/babel-config.js b/node_modules/ava/lib/babel-config.js
deleted file mode 100644
index d58b700b8..000000000
--- a/node_modules/ava/lib/babel-config.js
+++ /dev/null
@@ -1,156 +0,0 @@
-'use strict';
-const fs = require('fs');
-const path = require('path');
-const chalk = require('chalk');
-const figures = require('figures');
-const configManager = require('hullabaloo-config-manager');
-const md5Hex = require('md5-hex');
-const makeDir = require('make-dir');
-const semver = require('semver');
-const colors = require('./colors');
-
-function validate(conf) {
- if (conf === undefined || conf === null) {
- conf = 'default';
- }
-
- // Check for valid babel config shortcuts (can be either `default` or `inherit`)
- const isValidShortcut = conf === 'default' || conf === 'inherit';
-
- if (!conf || (typeof conf === 'string' && !isValidShortcut)) {
- let message = colors.error(figures.cross);
- message += ' Unexpected Babel configuration for AVA. ';
- message += 'See ' + chalk.underline('https://github.com/avajs/ava#es2017-support') + ' for allowed values.';
-
- throw new Error(message);
- }
-
- return conf;
-}
-
-const SOURCE = '(AVA) Base Babel config';
-const AVA_DIR = path.join(__dirname, '..');
-
-function verifyExistingOptions(verifierFile, baseConfig, cache) {
- return new Promise((resolve, reject) => {
- try {
- resolve(fs.readFileSync(verifierFile));
- } catch (err) {
- if (err && err.code === 'ENOENT') {
- resolve(null);
- } else {
- reject(err);
- }
- }
- })
- .then(buffer => {
- if (!buffer) {
- return null;
- }
-
- const verifier = configManager.restoreVerifier(buffer);
- const fixedSourceHashes = new Map();
- fixedSourceHashes.set(baseConfig.source, baseConfig.hash);
- if (baseConfig.extends) {
- fixedSourceHashes.set(baseConfig.extends.source, baseConfig.extends.hash);
- }
- return verifier.verifyCurrentEnv({sources: fixedSourceHashes}, cache)
- .then(result => {
- if (!result.cacheKeys) {
- return null;
- }
-
- if (result.dependenciesChanged) {
- fs.writeFileSync(verifierFile, result.verifier.toBuffer());
- }
-
- return result.cacheKeys;
- });
- });
-}
-
-function resolveOptions(baseConfig, cache, optionsFile, verifierFile) {
- return configManager.fromConfig(baseConfig, {cache})
- .then(result => {
- fs.writeFileSync(optionsFile, result.generateModule());
-
- return result.createVerifier()
- .then(verifier => {
- fs.writeFileSync(verifierFile, verifier.toBuffer());
- return verifier.cacheKeysForCurrentEnv();
- });
- });
-}
-
-function build(projectDir, cacheDir, userOptions, powerAssert) {
- // Compute a seed based on the Node.js version and the project directory.
- // Dependency hashes may vary based on the Node.js version, e.g. with the
- // @ava/stage-4 Babel preset. Sources and dependencies paths are absolute in
- // the generated module and verifier state. Those paths wouldn't necessarily
- // be valid if the project directory changes.
- const seed = md5Hex([process.versions.node, projectDir]);
-
- // Ensure cacheDir exists
- makeDir.sync(cacheDir);
-
- // The file names predict where valid options may be cached, and thus should
- // include the seed.
- const optionsFile = path.join(cacheDir, `${seed}.babel-options.js`);
- const verifierFile = path.join(cacheDir, `${seed}.verifier.bin`);
-
- const baseOptions = {
- babelrc: false,
- plugins: [],
- presets: [
- ['@ava/transform-test-files', {powerAssert}]
- ]
- };
- if (userOptions === 'default') {
- baseOptions.presets.unshift('@ava/stage-4');
- }
-
- // Include object rest spread support for node versions that support it
- // natively.
- if (userOptions === 'default' && semver.satisfies(process.versions.node, '>= 8.3.0')) {
- baseOptions.plugins.push('babel-plugin-syntax-object-rest-spread');
- }
-
- const baseConfig = configManager.createConfig({
- dir: AVA_DIR, // Presets are resolved relative to this directory
- hash: md5Hex(JSON.stringify(baseOptions)),
- json5: false,
- options: baseOptions,
- source: SOURCE
- });
-
- if (userOptions !== 'default') {
- baseConfig.extend(configManager.createConfig({
- dir: projectDir,
- options: userOptions === 'inherit' ?
- {babelrc: true} :
- userOptions,
- source: path.join(projectDir, 'package.json') + '#ava.babel',
- hash: md5Hex(JSON.stringify(userOptions))
- }));
- }
-
- const cache = configManager.prepareCache();
- return verifyExistingOptions(verifierFile, baseConfig, cache)
- .then(cacheKeys => {
- if (cacheKeys) {
- return cacheKeys;
- }
-
- return resolveOptions(baseConfig, cache, optionsFile, verifierFile);
- })
- .then(cacheKeys => ({
- getOptions: require(optionsFile).getOptions,
- // Include the seed in the cache keys used to store compilation results.
- cacheKeys: Object.assign({seed}, cacheKeys)
- }));
-}
-
-module.exports = {
- validate,
- build
-};
diff --git a/node_modules/ava/lib/beautify-stack.js b/node_modules/ava/lib/beautify-stack.js
deleted file mode 100644
index 4ae8c04be..000000000
--- a/node_modules/ava/lib/beautify-stack.js
+++ /dev/null
@@ -1,72 +0,0 @@
-'use strict';
-const StackUtils = require('stack-utils');
-const cleanStack = require('clean-stack');
-const debug = require('debug')('ava');
-
-// Ignore unimportant stack trace lines
-let ignoreStackLines = [];
-
-const avaInternals = /\/ava\/(?:lib\/)?[\w-]+\.js:\d+:\d+\)?$/;
-const avaDependencies = /\/node_modules\/(?:bluebird|empower-core|(?:ava\/node_modules\/)?(?:babel-runtime|core-js))\//;
-const stackFrameLine = /^.+( \(.+:\d+:\d+\)|:\d+:\d+)$/;
-
-if (!debug.enabled) {
- ignoreStackLines = StackUtils.nodeInternals();
- ignoreStackLines.push(avaInternals);
- ignoreStackLines.push(avaDependencies);
-}
-
-const stackUtils = new StackUtils({internals: ignoreStackLines});
-
-function extractFrames(stack) {
- return stack
- .split('\n')
- .map(line => line.trim())
- .filter(line => stackFrameLine.test(line))
- .join('\n');
-}
-
-/**
- * Given a string value of the format generated for the `stack` property of a
- * V8 error object, return a string that contains only stack frame information
- * for frames that have relevance to the consumer.
- *
- * For example, given the following string value:
- *
- * ```
- * Error
- * at inner (/home/ava/ex.js:7:12)
- * at /home/ava/ex.js:12:5
- * at outer (/home/ava/ex.js:13:4)
- * at Object.<anonymous> (/home/ava/ex.js:14:3)
- * at Module._compile (module.js:570:32)
- * at Object.Module._extensions..js (module.js:579:10)
- * at Module.load (module.js:487:32)
- * at tryModuleLoad (module.js:446:12)
- * at Function.Module._load (module.js:438:3)
- * at Module.runMain (module.js:604:10)
- * ```
- *
- * ...this function returns the following string value:
- *
- * ```
- * inner (/home/ava/ex.js:7:12)
- * /home/ava/ex.js:12:5
- * outer (/home/ava/ex.js:13:4)
- * Object.<anonymous> (/home/ava/ex.js:14:3)
- * ```
- */
-module.exports = stack => {
- if (!stack) {
- return '';
- }
-
- stack = extractFrames(stack);
- // Workaround for https://github.com/tapjs/stack-utils/issues/14
- // TODO: fix it in `stack-utils`
- stack = cleanStack(stack);
-
- return stackUtils.clean(stack)
- // Remove the trailing newline inserted by the `stack-utils` module
- .trim();
-};
diff --git a/node_modules/ava/lib/caching-precompiler.js b/node_modules/ava/lib/caching-precompiler.js
deleted file mode 100644
index f6e5e47c3..000000000
--- a/node_modules/ava/lib/caching-precompiler.js
+++ /dev/null
@@ -1,108 +0,0 @@
-'use strict';
-const path = require('path');
-const fs = require('fs');
-const convertSourceMap = require('convert-source-map');
-const cachingTransform = require('caching-transform');
-const packageHash = require('package-hash');
-const stripBomBuf = require('strip-bom-buf');
-const autoBind = require('auto-bind');
-const md5Hex = require('md5-hex');
-
-function getSourceMap(filePath, code) {
- let sourceMap = convertSourceMap.fromSource(code);
-
- if (!sourceMap) {
- const dirPath = path.dirname(filePath);
- sourceMap = convertSourceMap.fromMapFileSource(code, dirPath);
- }
-
- if (sourceMap) {
- sourceMap = sourceMap.toObject();
- }
-
- return sourceMap;
-}
-
-class CachingPrecompiler {
- constructor(options) {
- autoBind(this);
-
- this.getBabelOptions = options.getBabelOptions;
- this.babelCacheKeys = options.babelCacheKeys;
- this.cacheDirPath = options.path;
- this.fileHashes = {};
- this.transform = this._createTransform();
- }
-
- precompileFile(filePath) {
- if (!this.fileHashes[filePath]) {
- const source = stripBomBuf(fs.readFileSync(filePath));
- this.transform(source, filePath);
- }
-
- return this.fileHashes[filePath];
- }
-
- // Conditionally called by caching-transform when precompiling is required
- _init() {
- this.babel = require('babel-core');
- return this._transform;
- }
-
- _transform(code, filePath, hash) {
- code = code.toString();
-
- let result;
- const originalBabelDisableCache = process.env.BABEL_DISABLE_CACHE;
- try {
- // Disable Babel's cache. AVA has good cache management already.
- process.env.BABEL_DISABLE_CACHE = '1';
-
- result = this.babel.transform(code, Object.assign(this.getBabelOptions(), {
- inputSourceMap: getSourceMap(filePath, code),
- filename: filePath,
- sourceMaps: true,
- ast: false
- }));
- } finally {
- // Restore the original value. It is passed to workers, where users may
- // not want Babel's cache to be disabled.
- process.env.BABEL_DISABLE_CACHE = originalBabelDisableCache;
- }
-
- // Save source map
- const mapPath = path.join(this.cacheDirPath, `${hash}.js.map`);
- fs.writeFileSync(mapPath, JSON.stringify(result.map));
-
- // Append source map comment to transformed code
- // So that other libraries (like nyc) can find the source map
- const dirPath = path.dirname(filePath);
- const relativeMapPath = path.relative(dirPath, mapPath);
- const comment = convertSourceMap.generateMapFileComment(relativeMapPath);
-
- return `${result.code}\n${comment}`;
- }
-
- _createTransform() {
- const salt = packageHash.sync([
- require.resolve('../package.json'),
- require.resolve('babel-core/package.json')
- ], this.babelCacheKeys);
-
- return cachingTransform({
- factory: this._init,
- cacheDir: this.cacheDirPath,
- hash: this._generateHash,
- salt,
- ext: '.js'
- });
- }
-
- _generateHash(code, filePath, salt) {
- const hash = md5Hex([code, filePath, salt]);
- this.fileHashes[filePath] = hash;
- return hash;
- }
-}
-
-module.exports = CachingPrecompiler;
diff --git a/node_modules/ava/lib/cli.js b/node_modules/ava/lib/cli.js
deleted file mode 100644
index 0c2c2f82f..000000000
--- a/node_modules/ava/lib/cli.js
+++ /dev/null
@@ -1,210 +0,0 @@
-'use strict';
-const path = require('path');
-const updateNotifier = require('update-notifier');
-const figures = require('figures');
-const arrify = require('arrify');
-const meow = require('meow');
-const Promise = require('bluebird');
-const pkgConf = require('pkg-conf');
-const isCi = require('is-ci');
-const hasFlag = require('has-flag');
-const Api = require('../api');
-const colors = require('./colors');
-const VerboseReporter = require('./reporters/verbose');
-const MiniReporter = require('./reporters/mini');
-const TapReporter = require('./reporters/tap');
-const Logger = require('./logger');
-const Watcher = require('./watcher');
-const babelConfigHelper = require('./babel-config');
-
-// Bluebird specific
-Promise.longStackTraces();
-
-exports.run = () => {
- const conf = pkgConf.sync('ava');
-
- const filepath = pkgConf.filepath(conf);
- const projectDir = filepath === null ? process.cwd() : path.dirname(filepath);
-
- const cli = meow(`
- Usage
- ava [<file|directory|glob> ...]
-
- Options
- --init Add AVA to your project
- --fail-fast Stop after first test failure
- --serial, -s Run tests serially
- --tap, -t Generate TAP output
- --verbose, -v Enable verbose output
- --no-cache Disable the transpiler cache
- --no-power-assert Disable Power Assert
- --color Force color output
- --no-color Disable color output
- --match, -m Only run tests with matching title (Can be repeated)
- --watch, -w Re-run tests when tests and source files change
- --timeout, -T Set global timeout
- --concurrency, -c Max number of test files running at the same time (Default: CPU cores)
- --update-snapshots, -u Update snapshots
-
- Examples
- ava
- ava test.js test2.js
- ava test-*.js
- ava test
- ava --init
- ava --init foo.js
-
- Default patterns when no arguments:
- test.js test-*.js test/**/*.js **/__tests__/**/*.js **/*.test.js
- `, {
- string: [
- '_',
- 'match',
- 'timeout',
- 'concurrency'
- ],
- boolean: [
- 'init',
- 'fail-fast',
- 'serial',
- 'tap',
- 'verbose',
- 'watch',
- 'update-snapshots',
- 'color'
- ],
- default: {
- cache: conf.cache,
- color: 'color' in conf ? conf.color : require('supports-color').stdout !== false,
- concurrency: conf.concurrency,
- failFast: conf.failFast,
- init: conf.init,
- match: conf.match,
- powerAssert: conf.powerAssert,
- serial: conf.serial,
- tap: conf.tap,
- timeout: conf.timeout,
- updateSnapshots: conf.updateSnapshots,
- verbose: conf.verbose,
- watch: conf.watch
- },
- alias: {
- t: 'tap',
- v: 'verbose',
- s: 'serial',
- m: 'match',
- w: 'watch',
- T: 'timeout',
- c: 'concurrency',
- u: 'update-snapshots'
- }
- });
-
- updateNotifier({pkg: cli.pkg}).notify();
-
- if (cli.flags.init) {
- require('ava-init')();
- return;
- }
-
- if (
- ((hasFlag('--watch') || hasFlag('-w')) && (hasFlag('--tap') || hasFlag('-t'))) ||
- (conf.watch && conf.tap)
- ) {
- throw new Error(colors.error(figures.cross) + ' The TAP reporter is not available when using watch mode.');
- }
-
- if ((hasFlag('--watch') || hasFlag('-w')) && isCi) {
- throw new Error(colors.error(figures.cross) + ' Watch mode is not available in CI, as it prevents AVA from terminating.');
- }
-
- if (cli.flags.concurrency === '') {
- throw new Error(colors.error(figures.cross) + ' The --concurrency and -c flags must be provided.');
- }
-
- if (cli.flags.concurrency &&
- (!Number.isInteger(Number.parseFloat(cli.flags.concurrency)) || parseInt(cli.flags.concurrency, 10) < 0)) {
- throw new Error(colors.error(figures.cross) + ' The --concurrency and -c flags must be a nonnegative integer.');
- }
-
- if (hasFlag('--require') || hasFlag('-r')) {
- throw new Error(colors.error(figures.cross) + ' The --require and -r flags are deprecated. Requirements should be configured in package.json - see documentation.');
- }
-
- // Copy resultant cli.flags into conf for use with Api and elsewhere
- Object.assign(conf, cli.flags);
-
- const api = new Api({
- failFast: conf.failFast,
- failWithoutAssertions: conf.failWithoutAssertions !== false,
- serial: conf.serial,
- require: arrify(conf.require),
- cacheEnabled: conf.cache !== false,
- powerAssert: conf.powerAssert !== false,
- explicitTitles: conf.watch,
- match: arrify(conf.match),
- babelConfig: babelConfigHelper.validate(conf.babel),
- resolveTestsFrom: cli.input.length === 0 ? projectDir : process.cwd(),
- projectDir,
- timeout: conf.timeout,
- concurrency: conf.concurrency ? parseInt(conf.concurrency, 10) : 0,
- updateSnapshots: conf.updateSnapshots,
- snapshotDir: conf.snapshotDir ? path.resolve(projectDir, conf.snapshotDir) : null,
- color: conf.color
- });
-
- let reporter;
-
- if (conf.tap && !conf.watch) {
- reporter = new TapReporter();
- } else if (conf.verbose || isCi) {
- reporter = new VerboseReporter({color: conf.color, watching: conf.watch});
- } else {
- reporter = new MiniReporter({color: conf.color, watching: conf.watch});
- }
-
- reporter.api = api;
- const logger = new Logger(reporter);
-
- logger.start();
-
- api.on('test-run', runStatus => {
- reporter.api = runStatus;
- runStatus.on('test', logger.test);
- runStatus.on('error', logger.unhandledError);
-
- runStatus.on('stdout', logger.stdout);
- runStatus.on('stderr', logger.stderr);
- });
-
- const files = cli.input.length ? cli.input : arrify(conf.files);
-
- if (conf.watch) {
- try {
- const watcher = new Watcher(logger, api, files, arrify(conf.source));
- watcher.observeStdin(process.stdin);
- } catch (err) {
- if (err.name === 'AvaError') {
- // An AvaError may be thrown if `chokidar` is not installed. Log it nicely.
- console.error(` ${colors.error(figures.cross)} ${err.message}`);
- logger.exit(1);
- } else {
- // Rethrow so it becomes an uncaught exception
- throw err;
- }
- }
- } else {
- api.run(files)
- .then(runStatus => {
- logger.finish(runStatus);
- logger.exit(runStatus.failCount > 0 || runStatus.rejectionCount > 0 || runStatus.exceptionCount > 0 ? 1 : 0);
- })
- .catch(err => {
- // Don't swallow exceptions. Note that any expected error should already
- // have been logged.
- setImmediate(() => {
- throw err;
- });
- });
- }
-};
diff --git a/node_modules/ava/lib/code-excerpt.js b/node_modules/ava/lib/code-excerpt.js
deleted file mode 100644
index aa619a0b2..000000000
--- a/node_modules/ava/lib/code-excerpt.js
+++ /dev/null
@@ -1,57 +0,0 @@
-'use strict';
-const fs = require('fs');
-const equalLength = require('equal-length');
-const codeExcerpt = require('code-excerpt');
-const truncate = require('cli-truncate');
-const chalk = require('chalk');
-
-const formatLineNumber = (lineNumber, maxLineNumber) =>
- ' '.repeat(Math.max(0, String(maxLineNumber).length - String(lineNumber).length)) + lineNumber;
-
-module.exports = (source, options) => {
- if (!source.isWithinProject || source.isDependency) {
- return null;
- }
-
- const file = source.file;
- const line = source.line;
-
- options = options || {};
- const maxWidth = options.maxWidth || 80;
-
- let contents;
- try {
- contents = fs.readFileSync(file, 'utf8');
- } catch (err) {
- return null;
- }
-
- const excerpt = codeExcerpt(contents, line, {around: 1});
- if (!excerpt) {
- return null;
- }
-
- const lines = excerpt.map(item => ({
- line: item.line,
- value: truncate(item.value, maxWidth - String(line).length - 5)
- }));
-
- const joinedLines = lines.map(line => line.value).join('\n');
- const extendedLines = equalLength(joinedLines).split('\n');
-
- return lines
- .map((item, index) => ({
- line: item.line,
- value: extendedLines[index]
- }))
- .map(item => {
- const isErrorSource = item.line === line;
-
- const lineNumber = formatLineNumber(item.line, line) + ':';
- const coloredLineNumber = isErrorSource ? lineNumber : chalk.grey(lineNumber);
- const result = ` ${coloredLineNumber} ${item.value}`;
-
- return isErrorSource ? chalk.bgRed(result) : result;
- })
- .join('\n');
-};
diff --git a/node_modules/ava/lib/colors.js b/node_modules/ava/lib/colors.js
deleted file mode 100644
index 75fb4d8aa..000000000
--- a/node_modules/ava/lib/colors.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict';
-const chalk = require('chalk');
-
-module.exports = {
- log: chalk.gray,
- title: chalk.bold.white,
- error: chalk.red,
- skip: chalk.yellow,
- todo: chalk.blue,
- pass: chalk.green,
- duration: chalk.gray.dim,
- errorSource: chalk.gray,
- errorStack: chalk.gray,
- stack: chalk.red,
- information: chalk.magenta
-};
diff --git a/node_modules/ava/lib/concordance-options.js b/node_modules/ava/lib/concordance-options.js
deleted file mode 100644
index 18b4b0c77..000000000
--- a/node_modules/ava/lib/concordance-options.js
+++ /dev/null
@@ -1,130 +0,0 @@
-'use strict';
-const ansiStyles = require('ansi-styles');
-const chalk = require('chalk');
-const stripAnsi = require('strip-ansi');
-const cloneDeepWith = require('lodash.clonedeepwith');
-const reactPlugin = require('@concordance/react');
-const options = require('./globals').options;
-
-// Wrap Concordance's React plugin. Change the name to avoid collisions if in
-// the future users can register plugins themselves.
-const avaReactPlugin = Object.assign({}, reactPlugin, {name: 'ava-plugin-react'});
-const plugins = [avaReactPlugin];
-
-const forceColor = new chalk.constructor({enabled: true});
-
-const colorTheme = {
- boolean: ansiStyles.yellow,
- circular: forceColor.grey('[Circular]'),
- date: {
- invalid: forceColor.red('invalid'),
- value: ansiStyles.blue
- },
- diffGutters: {
- actual: forceColor.red('-') + ' ',
- expected: forceColor.green('+') + ' ',
- padding: ' '
- },
- error: {
- ctor: {open: ansiStyles.grey.open + '(', close: ')' + ansiStyles.grey.close},
- name: ansiStyles.magenta
- },
- function: {
- name: ansiStyles.blue,
- stringTag: ansiStyles.magenta
- },
- global: ansiStyles.magenta,
- item: {after: forceColor.grey(',')},
- list: {openBracket: forceColor.grey('['), closeBracket: forceColor.grey(']')},
- mapEntry: {after: forceColor.grey(',')},
- maxDepth: forceColor.grey('…'),
- null: ansiStyles.yellow,
- number: ansiStyles.yellow,
- object: {
- openBracket: forceColor.grey('{'),
- closeBracket: forceColor.grey('}'),
- ctor: ansiStyles.magenta,
- stringTag: {open: ansiStyles.magenta.open + '@', close: ansiStyles.magenta.close},
- secondaryStringTag: {open: ansiStyles.grey.open + '@', close: ansiStyles.grey.close}
- },
- property: {
- after: forceColor.grey(','),
- keyBracket: {open: forceColor.grey('['), close: forceColor.grey(']')},
- valueFallback: forceColor.grey('…')
- },
- react: {
- functionType: forceColor.grey('\u235F'),
- openTag: {
- start: forceColor.grey('<'),
- end: forceColor.grey('>'),
- selfClose: forceColor.grey('/'),
- selfCloseVoid: ' ' + forceColor.grey('/')
- },
- closeTag: {
- open: forceColor.grey('</'),
- close: forceColor.grey('>')
- },
- tagName: ansiStyles.magenta,
- attribute: {
- separator: '=',
- value: {
- openBracket: forceColor.grey('{'),
- closeBracket: forceColor.grey('}'),
- string: {
- line: {open: forceColor.blue('"'), close: forceColor.blue('"'), escapeQuote: '"'}
- }
- }
- },
- child: {
- openBracket: forceColor.grey('{'),
- closeBracket: forceColor.grey('}')
- }
- },
- regexp: {
- source: {open: ansiStyles.blue.open + '/', close: '/' + ansiStyles.blue.close},
- flags: ansiStyles.yellow
- },
- stats: {separator: forceColor.grey('---')},
- string: {
- open: ansiStyles.blue.open,
- close: ansiStyles.blue.close,
- line: {open: forceColor.blue('\''), close: forceColor.blue('\'')},
- multiline: {start: forceColor.blue('`'), end: forceColor.blue('`')},
- controlPicture: ansiStyles.grey,
- diff: {
- insert: {
- open: ansiStyles.bgGreen.open + ansiStyles.black.open,
- close: ansiStyles.black.close + ansiStyles.bgGreen.close
- },
- delete: {
- open: ansiStyles.bgRed.open + ansiStyles.black.open,
- close: ansiStyles.black.close + ansiStyles.bgRed.close
- },
- equal: ansiStyles.blue,
- insertLine: {
- open: ansiStyles.green.open,
- close: ansiStyles.green.close
- },
- deleteLine: {
- open: ansiStyles.red.open,
- close: ansiStyles.red.close
- }
- }
- },
- symbol: ansiStyles.yellow,
- typedArray: {
- bytes: ansiStyles.yellow
- },
- undefined: ansiStyles.yellow
-};
-
-const plainTheme = cloneDeepWith(colorTheme, value => {
- if (typeof value === 'string') {
- return stripAnsi(value);
- }
-});
-
-const theme = options.color === false ? plainTheme : colorTheme;
-exports.default = {maxDepth: 3, plugins, theme};
-exports.diff = {maxDepth: 1, plugins, theme};
-exports.snapshotManager = {plugins, theme: plainTheme};
diff --git a/node_modules/ava/lib/concurrent.js b/node_modules/ava/lib/concurrent.js
deleted file mode 100644
index 3cdbb41c3..000000000
--- a/node_modules/ava/lib/concurrent.js
+++ /dev/null
@@ -1,64 +0,0 @@
-'use strict';
-
-class Concurrent {
- constructor(runnables, bail) {
- if (!Array.isArray(runnables)) {
- throw new TypeError('Expected an array of runnables');
- }
-
- this.runnables = runnables;
- this.bail = bail || false;
- }
-
- run() {
- let allPassed = true;
-
- let pending;
- let rejectPending;
- let resolvePending;
- const allPromises = [];
- const handlePromise = promise => {
- if (!pending) {
- pending = new Promise((resolve, reject) => {
- rejectPending = reject;
- resolvePending = resolve;
- });
- }
-
- allPromises.push(promise.then(passed => {
- if (!passed) {
- allPassed = false;
-
- if (this.bail) {
- // Stop if the test failed and bail mode is on.
- resolvePending();
- }
- }
- }, rejectPending));
- };
-
- for (const runnable of this.runnables) {
- const passedOrPromise = runnable.run();
-
- if (!passedOrPromise) {
- if (this.bail) {
- // Stop if the test failed and bail mode is on.
- return false;
- }
-
- allPassed = false;
- } else if (passedOrPromise !== true) {
- handlePromise(passedOrPromise);
- }
- }
-
- if (pending) {
- Promise.all(allPromises).then(resolvePending);
- return pending.then(() => allPassed);
- }
-
- return allPassed;
- }
-}
-
-module.exports = Concurrent;
diff --git a/node_modules/ava/lib/enhance-assert.js b/node_modules/ava/lib/enhance-assert.js
deleted file mode 100644
index 6991caf40..000000000
--- a/node_modules/ava/lib/enhance-assert.js
+++ /dev/null
@@ -1,53 +0,0 @@
-'use strict';
-const concordance = require('concordance');
-const dotProp = require('dot-prop');
-const generate = require('babel-generator').default;
-const concordanceOptions = require('./concordance-options').default;
-
-// When adding patterns, don't forget to add to
-// https://github.com/avajs/babel-preset-transform-test-files/blob/master/espower-patterns.json
-// Then release a new version of that preset and bump the SemVer range here.
-const PATTERNS = [
- 't.truthy(value, [message])',
- 't.falsy(value, [message])',
- 't.true(value, [message])',
- 't.false(value, [message])',
- 't.regex(contents, regex, [message])',
- 't.notRegex(contents, regex, [message])'
-];
-
-const computeStatement = node => generate(node, {quotes: 'single'}).code;
-const getNode = (ast, path) => dotProp.get(ast, path.replace(/\//g, '.'));
-
-const formatter = context => {
- const ast = JSON.parse(context.source.ast);
- const args = context.args[0].events;
- return args
- .map(arg => {
- const node = getNode(ast, arg.espath);
- const statement = computeStatement(node);
- const formatted = concordance.format(arg.value, concordanceOptions);
- return [statement, formatted];
- })
- .reverse();
-};
-
-const enhanceAssert = (pass, fail, assertions) => {
- const empower = require('empower-core');
- return empower(assertions, {
- destructive: true,
- onError(event) {
- const error = event.error;
- if (event.powerAssertContext) { // Context may be missing in internal tests.
- error.statements = formatter(event.powerAssertContext);
- }
- fail(this, error);
- },
- onSuccess() {
- pass(this);
- },
- patterns: PATTERNS,
- bindReceiver: false
- });
-};
-module.exports = enhanceAssert;
diff --git a/node_modules/ava/lib/fork.js b/node_modules/ava/lib/fork.js
deleted file mode 100644
index 0ca0f45a4..000000000
--- a/node_modules/ava/lib/fork.js
+++ /dev/null
@@ -1,176 +0,0 @@
-'use strict';
-const childProcess = require('child_process');
-const path = require('path');
-const fs = require('fs');
-const Promise = require('bluebird');
-const debug = require('debug')('ava');
-const AvaError = require('./ava-error');
-
-if (fs.realpathSync(__filename) !== __filename) {
- console.warn('WARNING: `npm link ava` and the `--preserve-symlink` flag are incompatible. We have detected that AVA is linked via `npm link`, and that you are using either an early version of Node 6, or the `--preserve-symlink` flag. This breaks AVA. You should upgrade to Node 6.2.0+, avoid the `--preserve-symlink` flag, or avoid using `npm link ava`.');
-}
-
-const env = Object.assign({NODE_ENV: 'test'}, process.env);
-
-// Ensure NODE_PATH paths are absolute
-if (env.NODE_PATH) {
- env.NODE_PATH = env.NODE_PATH
- .split(path.delimiter)
- .map(x => path.resolve(x))
- .join(path.delimiter);
-}
-
-// In case the test file imports a different AVA install,
-// the presence of this variable allows it to require this one instead
-env.AVA_PATH = path.resolve(__dirname, '..');
-
-module.exports = (file, opts, execArgv) => {
- opts = Object.assign({
- file,
- baseDir: process.cwd(),
- tty: process.stdout.isTTY ? {
- columns: process.stdout.columns,
- rows: process.stdout.rows
- } : false
- }, opts);
-
- const args = [JSON.stringify(opts), opts.color ? '--color' : '--no-color'];
-
- const ps = childProcess.fork(path.join(__dirname, 'test-worker.js'), args, {
- cwd: opts.projectDir,
- silent: true,
- env,
- execArgv: execArgv || process.execArgv
- });
-
- const relFile = path.relative('.', file);
-
- let exiting = false;
- const send = (name, data) => {
- if (!exiting) {
- // This seems to trigger a Node bug which kills the AVA master process, at
- // least while running AVA's tests. See
- // <https://github.com/novemberborn/_ava-tap-crash> for more details.
- ps.send({
- name: `ava-${name}`,
- data,
- ava: true
- });
- }
- };
-
- const testResults = [];
- let results;
-
- const promise = new Promise((resolve, reject) => {
- ps.on('error', reject);
-
- // Emit `test` and `stats` events
- ps.on('message', event => {
- if (!event.ava) {
- return;
- }
-
- event.name = event.name.replace(/^ava-/, '');
- event.data.file = relFile;
-
- debug('ipc %s:\n%o', event.name, event.data);
-
- ps.emit(event.name, event.data);
- });
-
- ps.on('test', props => {
- testResults.push(props);
- });
-
- ps.on('results', data => {
- results = data;
- data.tests = testResults;
- send('teardown');
- });
-
- ps.on('exit', (code, signal) => {
- if (code > 0) {
- return reject(new AvaError(`${relFile} exited with a non-zero exit code: ${code}`));
- }
-
- if (code === null && signal) {
- return reject(new AvaError(`${relFile} exited due to ${signal}`));
- }
-
- if (results) {
- resolve(results);
- } else {
- reject(new AvaError(`Test results were not received from ${relFile}`));
- }
- });
-
- ps.on('no-tests', data => {
- send('teardown');
-
- let message = `No tests found in ${relFile}`;
-
- if (!data.avaRequired) {
- message += ', make sure to import "ava" at the top of your test file';
- }
-
- reject(new AvaError(message));
- });
- });
-
- // Teardown finished, now exit
- ps.on('teardown', () => {
- send('exit');
- exiting = true;
- });
-
- // Uncaught exception in fork, need to exit
- ps.on('uncaughtException', () => {
- send('teardown');
- });
-
- ps.stdout.on('data', data => {
- ps.emit('stdout', data);
- });
-
- ps.stderr.on('data', data => {
- ps.emit('stderr', data);
- });
-
- promise.on = function () {
- ps.on.apply(ps, arguments);
- return promise;
- };
-
- promise.send = (name, data) => {
- send(name, data);
- return promise;
- };
-
- promise.exit = () => {
- send('init-exit');
- return promise;
- };
-
- // Send 'run' event only when fork is listening for it
- let isReady = false;
-
- ps.on('stats', () => {
- isReady = true;
- });
-
- promise.run = options => {
- if (isReady) {
- send('run', options);
- return promise;
- }
-
- ps.on('stats', () => {
- send('run', options);
- });
-
- return promise;
- };
-
- return promise;
-};
diff --git a/node_modules/ava/lib/globals.js b/node_modules/ava/lib/globals.js
deleted file mode 100644
index 51176c113..000000000
--- a/node_modules/ava/lib/globals.js
+++ /dev/null
@@ -1,10 +0,0 @@
-'use strict';
-
-// Global objects / functions to be bound before requiring test file, so tests do not interfere
-
-const x = module.exports;
-x.now = Date.now;
-x.setTimeout = setTimeout;
-x.clearTimeout = clearTimeout;
-x.setImmediate = setImmediate;
-x.options = {};
diff --git a/node_modules/ava/lib/logger.js b/node_modules/ava/lib/logger.js
deleted file mode 100644
index e8edb120f..000000000
--- a/node_modules/ava/lib/logger.js
+++ /dev/null
@@ -1,92 +0,0 @@
-'use strict';
-const autoBind = require('auto-bind');
-
-class Logger {
- constructor(reporter) {
- this.reporter = reporter;
- autoBind(this);
- }
-
- start(runStatus) {
- if (!this.reporter.start) {
- return;
- }
-
- this.write(this.reporter.start(runStatus), runStatus);
- }
-
- reset(runStatus) {
- if (!this.reporter.reset) {
- return;
- }
-
- this.write(this.reporter.reset(runStatus), runStatus);
- }
-
- test(test, runStatus) {
- this.write(this.reporter.test(test, runStatus), runStatus);
- }
-
- unhandledError(err, runStatus) {
- if (!this.reporter.unhandledError) {
- return;
- }
-
- this.write(this.reporter.unhandledError(err, runStatus), runStatus);
- }
-
- finish(runStatus) {
- if (!this.reporter.finish) {
- return;
- }
-
- this.write(this.reporter.finish(runStatus), runStatus);
- }
-
- section() {
- if (!this.reporter.section) {
- return;
- }
-
- this.write(this.reporter.section());
- }
-
- clear() {
- if (!this.reporter.clear) {
- return false;
- }
-
- this.write(this.reporter.clear());
- return true;
- }
-
- write(str, runStatus) {
- if (typeof str === 'undefined') {
- return;
- }
-
- this.reporter.write(str, runStatus);
- }
-
- stdout(data, runStatus) {
- if (!this.reporter.stdout) {
- return;
- }
-
- this.reporter.stdout(data, runStatus);
- }
-
- stderr(data, runStatus) {
- if (!this.reporter.stderr) {
- return;
- }
-
- this.reporter.stderr(data, runStatus);
- }
-
- exit(code) {
- process.exit(code); // eslint-disable-line unicorn/no-process-exit
- }
-}
-
-module.exports = Logger;
diff --git a/node_modules/ava/lib/main.js b/node_modules/ava/lib/main.js
deleted file mode 100644
index 4c5fdc373..000000000
--- a/node_modules/ava/lib/main.js
+++ /dev/null
@@ -1,105 +0,0 @@
-'use strict';
-const worker = require('./test-worker');
-const adapter = require('./process-adapter');
-const serializeError = require('./serialize-error');
-const globals = require('./globals');
-const Runner = require('./runner');
-
-const opts = globals.options;
-const runner = new Runner({
- bail: opts.failFast,
- failWithoutAssertions: opts.failWithoutAssertions,
- file: opts.file,
- match: opts.match,
- projectDir: opts.projectDir,
- serial: opts.serial,
- updateSnapshots: opts.updateSnapshots,
- snapshotDir: opts.snapshotDir
-});
-
-worker.setRunner(runner);
-
-// If fail-fast is enabled, use this variable to detect
-// that no more tests should be logged
-let isFailed = false;
-
-Error.stackTraceLimit = Infinity;
-
-function test(props) {
- if (isFailed) {
- return;
- }
-
- const hasError = typeof props.error !== 'undefined';
-
- // Don't display anything if it's a passed hook
- if (!hasError && props.type !== 'test') {
- return;
- }
-
- if (hasError) {
- props.error = serializeError(props.error);
- } else {
- props.error = null;
- }
-
- adapter.send('test', props);
-
- if (hasError && opts.failFast) {
- isFailed = true;
- exit();
- }
-}
-
-function exit() {
- // Reference the IPC channel now that tests have finished running.
- adapter.ipcChannel.ref();
-
- const stats = runner.buildStats();
- adapter.send('results', {stats});
-}
-
-globals.setImmediate(() => {
- const hasExclusive = runner.tests.hasExclusive;
- const numberOfTests = runner.tests.testCount;
-
- if (numberOfTests === 0) {
- adapter.send('no-tests', {avaRequired: true});
- return;
- }
-
- adapter.send('stats', {
- testCount: numberOfTests,
- hasExclusive
- });
-
- runner.on('test', test);
-
- process.on('ava-run', options => {
- // Unreference the IPC channel. This stops it from keeping the event loop
- // busy, which means the `beforeExit` event can be used to detect when tests
- // stall.
- adapter.ipcChannel.unref();
-
- runner.run(options)
- .then(() => {
- runner.saveSnapshotState();
-
- return exit();
- })
- .catch(err => {
- process.emit('uncaughtException', err);
- });
- });
-
- process.on('ava-init-exit', () => {
- exit();
- });
-});
-
-module.exports = runner.chain;
-
-// TypeScript imports the `default` property for
-// an ES2015 default import (`import test from 'ava'`)
-// See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181
-module.exports.default = runner.chain;
diff --git a/node_modules/ava/lib/prefix-title.js b/node_modules/ava/lib/prefix-title.js
deleted file mode 100644
index a1c7b4f3b..000000000
--- a/node_modules/ava/lib/prefix-title.js
+++ /dev/null
@@ -1,21 +0,0 @@
-'use strict';
-const path = require('path');
-
-module.exports = (file, base, separator) => {
- let prefix = file
- // Only replace this.base if it is found at the start of the path
- .replace(base, (match, offset) => offset === 0 ? '' : match)
- .replace(/\.spec/, '')
- .replace(/\.test/, '')
- .replace(/test-/g, '')
- .replace(/\.js$/, '')
- .split(path.sep)
- .filter(p => p !== '__tests__')
- .join(separator);
-
- if (prefix.length > 0) {
- prefix += separator;
- }
-
- return prefix;
-};
diff --git a/node_modules/ava/lib/process-adapter.js b/node_modules/ava/lib/process-adapter.js
deleted file mode 100644
index 5f9c0d79d..000000000
--- a/node_modules/ava/lib/process-adapter.js
+++ /dev/null
@@ -1,103 +0,0 @@
-'use strict';
-const fs = require('fs');
-const path = require('path');
-const debug = require('debug')('ava');
-const sourceMapSupport = require('source-map-support');
-const installPrecompiler = require('require-precompiled');
-
-// Parse and re-emit AVA messages
-process.on('message', message => {
- if (!message.ava) {
- return;
- }
-
- process.emit(message.name, message.data);
-});
-
-exports.send = (name, data) => {
- process.send({
- name: `ava-${name}`,
- data,
- ava: true
- });
-};
-
-// `process.channel` was added in Node.js 7.1.0, but the channel was available
-// through an undocumented API as `process._channel`.
-exports.ipcChannel = process.channel || process._channel;
-
-const opts = JSON.parse(process.argv[2]);
-exports.opts = opts;
-
-// Fake TTY support
-if (opts.tty) {
- process.stdout.isTTY = true;
- process.stdout.columns = opts.tty.columns || 80;
- process.stdout.rows = opts.tty.rows;
-
- const tty = require('tty');
- const isatty = tty.isatty;
-
- tty.isatty = function (fd) {
- if (fd === 1 || fd === process.stdout) {
- return true;
- }
-
- return isatty(fd);
- };
-}
-
-if (debug.enabled) {
- // Forward the `time-require` `--sorted` flag.
- // Intended for internal optimization tests only.
- if (opts._sorted) {
- process.argv.push('--sorted');
- }
-
- require('time-require'); // eslint-disable-line import/no-unassigned-import
-}
-
-const sourceMapCache = new Map();
-const cacheDir = opts.cacheDir;
-
-exports.installSourceMapSupport = () => {
- sourceMapSupport.install({
- environment: 'node',
- handleUncaughtExceptions: false,
- retrieveSourceMap(source) {
- if (sourceMapCache.has(source)) {
- return {
- url: source,
- map: fs.readFileSync(sourceMapCache.get(source), 'utf8')
- };
- }
- }
- });
-};
-
-exports.installPrecompilerHook = () => {
- installPrecompiler(filename => {
- const precompiled = opts.precompiled[filename];
-
- if (precompiled) {
- sourceMapCache.set(filename, path.join(cacheDir, `${precompiled}.js.map`));
- return fs.readFileSync(path.join(cacheDir, `${precompiled}.js`), 'utf8');
- }
-
- return null;
- });
-};
-
-exports.installDependencyTracking = (dependencies, testPath) => {
- Object.keys(require.extensions).forEach(ext => {
- const wrappedHandler = require.extensions[ext];
-
- require.extensions[ext] = (module, filename) => {
- if (filename !== testPath) {
- dependencies.add(filename);
- }
-
- wrappedHandler(module, filename);
- };
- });
-};
diff --git a/node_modules/ava/lib/reporters/format-serialized-error.js b/node_modules/ava/lib/reporters/format-serialized-error.js
deleted file mode 100644
index 6ab59e47c..000000000
--- a/node_modules/ava/lib/reporters/format-serialized-error.js
+++ /dev/null
@@ -1,26 +0,0 @@
-'use strict';
-const chalk = require('chalk');
-const trimOffNewlines = require('trim-off-newlines');
-
-function formatSerializedError(error) {
- const printMessage = error.values.length === 0 ?
- Boolean(error.message) :
- !error.values[0].label.startsWith(error.message);
-
- if (error.statements.length === 0 && error.values.length === 0) {
- return {formatted: null, printMessage};
- }
-
- let formatted = '';
- for (const value of error.values) {
- formatted += `${value.label}\n\n${trimOffNewlines(value.formatted)}\n\n`;
- }
-
- for (const statement of error.statements) {
- formatted += `${statement[0]}\n${chalk.grey('=>')} ${trimOffNewlines(statement[1])}\n\n`;
- }
-
- formatted = trimOffNewlines(formatted);
- return {formatted, printMessage};
-}
-module.exports = formatSerializedError;
diff --git a/node_modules/ava/lib/reporters/improper-usage-messages.js b/node_modules/ava/lib/reporters/improper-usage-messages.js
deleted file mode 100644
index 014a4bf0d..000000000
--- a/node_modules/ava/lib/reporters/improper-usage-messages.js
+++ /dev/null
@@ -1,56 +0,0 @@
-'use strict';
-const chalk = require('chalk');
-
-exports.forError = error => {
- if (!error.improperUsage) {
- return null;
- }
-
- const assertion = error.assertion;
- if (assertion === 'throws' || assertion === 'notThrows') {
- return `Try wrapping the first argument to \`t.${assertion}()\` in a function:
-
- ${chalk.cyan(`t.${assertion}(() => { `)}${chalk.grey('/* your code here */')}${chalk.cyan(' })')}
-
-Visit the following URL for more details:
-
- ${chalk.blue.underline('https://github.com/avajs/ava#throwsfunctionpromise-error-message')}`;
- }
-
- if (assertion === 'snapshot') {
- const name = error.improperUsage.name;
- const snapPath = error.improperUsage.snapPath;
-
- if (name === 'ChecksumError') {
- return `The snapshot file is corrupted.
-
-File path: ${chalk.yellow(snapPath)}
-
-Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to recreate it.`;
- }
-
- if (name === 'LegacyError') {
- return `The snapshot file was created with AVA 0.19. It's not supported by this AVA version.
-
-File path: ${chalk.yellow(snapPath)}
-
-Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrade.`;
- }
-
- if (name === 'VersionMismatchError') {
- const snapVersion = error.improperUsage.snapVersion;
- const expectedVersion = error.improperUsage.expectedVersion;
- const upgradeMessage = snapVersion < expectedVersion ?
- `Please run AVA again with the ${chalk.cyan('--update-snapshots')} flag to upgrade.` :
- 'You should upgrade AVA.';
-
- return `The snapshot file is v${snapVersion}, but only v${expectedVersion} is supported.
-
-File path: ${chalk.yellow(snapPath)}
-
-${upgradeMessage}`;
- }
- }
-
- return null;
-};
diff --git a/node_modules/ava/lib/reporters/mini.js b/node_modules/ava/lib/reporters/mini.js
deleted file mode 100644
index a21d02a6b..000000000
--- a/node_modules/ava/lib/reporters/mini.js
+++ /dev/null
@@ -1,333 +0,0 @@
-'use strict';
-const StringDecoder = require('string_decoder').StringDecoder;
-const cliCursor = require('cli-cursor');
-const lastLineTracker = require('last-line-stream/tracker');
-const plur = require('plur');
-const spinners = require('cli-spinners');
-const chalk = require('chalk');
-const figures = require('figures');
-const cliTruncate = require('cli-truncate');
-const cross = require('figures').cross;
-const indentString = require('indent-string');
-const ansiEscapes = require('ansi-escapes');
-const trimOffNewlines = require('trim-off-newlines');
-const codeExcerpt = require('../code-excerpt');
-const colors = require('../colors');
-const formatSerializedError = require('./format-serialized-error');
-const improperUsageMessages = require('./improper-usage-messages');
-
-class MiniReporter {
- constructor(options) {
- this.options = Object.assign({}, options);
-
- chalk.enabled = this.options.color;
- for (const key of Object.keys(colors)) {
- colors[key].enabled = this.options.color;
- }
-
- const spinnerDef = spinners[process.platform === 'win32' ? 'line' : 'dots'];
- this.spinnerFrames = spinnerDef.frames.map(c => chalk.gray.dim(c));
- this.spinnerInterval = spinnerDef.interval;
-
- this.reset();
- this.stream = process.stderr;
- this.stringDecoder = new StringDecoder();
- }
-
- start() {
- this.interval = setInterval(() => {
- this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
- this.write(this.prefix());
- }, this.spinnerInterval);
-
- return this.prefix('');
- }
-
- reset() {
- this.clearInterval();
- this.passCount = 0;
- this.knownFailureCount = 0;
- this.failCount = 0;
- this.skipCount = 0;
- this.todoCount = 0;
- this.rejectionCount = 0;
- this.exceptionCount = 0;
- this.currentStatus = '';
- this.currentTest = '';
- this.statusLineCount = 0;
- this.spinnerIndex = 0;
- this.lastLineTracker = lastLineTracker();
- }
-
- spinnerChar() {
- return this.spinnerFrames[this.spinnerIndex];
- }
-
- clearInterval() {
- clearInterval(this.interval);
- this.interval = null;
- }
-
- test(test) {
- if (test.todo) {
- this.todoCount++;
- } else if (test.skip) {
- this.skipCount++;
- } else if (test.error) {
- this.failCount++;
- } else {
- this.passCount++;
- if (test.failing) {
- this.knownFailureCount++;
- }
- }
-
- if (test.todo || test.skip) {
- return;
- }
-
- return this.prefix(this._test(test));
- }
-
- prefix(str) {
- str = str || this.currentTest;
- this.currentTest = str;
-
- // The space before the newline is required for proper formatting
- // TODO(jamestalmage): Figure out why it's needed and document it here
- return ` \n ${this.spinnerChar()} ${str}`;
- }
-
- _test(test) {
- const SPINNER_WIDTH = 3;
- const PADDING = 1;
- let title = cliTruncate(test.title, process.stdout.columns - SPINNER_WIDTH - PADDING);
-
- if (test.error || test.failing) {
- title = colors.error(test.title);
- }
-
- return title + '\n' + this.reportCounts();
- }
-
- unhandledError(err) {
- if (err.type === 'exception') {
- this.exceptionCount++;
- } else {
- this.rejectionCount++;
- }
- }
-
- reportCounts(time) {
- const lines = [
- this.passCount > 0 ? '\n ' + colors.pass(this.passCount, 'passed') : '',
- this.knownFailureCount > 0 ? '\n ' + colors.error(this.knownFailureCount, plur('known failure', this.knownFailureCount)) : '',
- this.failCount > 0 ? '\n ' + colors.error(this.failCount, 'failed') : '',
- this.skipCount > 0 ? '\n ' + colors.skip(this.skipCount, 'skipped') : '',
- this.todoCount > 0 ? '\n ' + colors.todo(this.todoCount, 'todo') : ''
- ].filter(Boolean);
-
- if (time && lines.length > 0) {
- lines[0] += ' ' + time;
- }
-
- return lines.join('');
- }
-
- finish(runStatus) {
- this.clearInterval();
- let time;
-
- if (this.options.watching) {
- time = chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']');
- }
-
- let status = this.reportCounts(time) + '\n';
-
- if (this.rejectionCount > 0) {
- status += ' ' + colors.error(this.rejectionCount, plur('rejection', this.rejectionCount)) + '\n';
- }
-
- if (this.exceptionCount > 0) {
- status += ' ' + colors.error(this.exceptionCount, plur('exception', this.exceptionCount)) + '\n';
- }
-
- if (runStatus.previousFailCount > 0) {
- status += ' ' + colors.error(runStatus.previousFailCount, 'previous', plur('failure', runStatus.previousFailCount), 'in test files that were not rerun') + '\n';
- }
-
- if (this.knownFailureCount > 0) {
- for (const test of runStatus.knownFailures) {
- const title = test.title;
- status += '\n ' + colors.title(title) + '\n';
- // TODO: Output description with link
- // status += colors.stack(description);
- }
- }
-
- status += '\n';
- if (this.failCount > 0) {
- runStatus.errors.forEach(test => {
- if (!test.error) {
- return;
- }
-
- status += ' ' + colors.title(test.title) + '\n';
-
- if (test.logs) {
- test.logs.forEach(log => {
- const logLines = indentString(colors.log(log), 6);
- const logLinesWithLeadingFigure = logLines.replace(
- /^ {6}/,
- ` ${colors.information(figures.info)} `
- );
-
- status += logLinesWithLeadingFigure + '\n';
- });
-
- status += '\n';
- }
-
- if (test.error.source) {
- status += ' ' + colors.errorSource(test.error.source.file + ':' + test.error.source.line) + '\n';
-
- const excerpt = codeExcerpt(test.error.source, {maxWidth: process.stdout.columns});
- if (excerpt) {
- status += '\n' + indentString(excerpt, 2) + '\n';
- }
- }
-
- if (test.error.avaAssertionError) {
- const result = formatSerializedError(test.error);
- if (result.printMessage) {
- status += '\n' + indentString(test.error.message, 2) + '\n';
- }
-
- if (result.formatted) {
- status += '\n' + indentString(result.formatted, 2) + '\n';
- }
-
- const message = improperUsageMessages.forError(test.error);
- if (message) {
- status += '\n' + indentString(message, 2) + '\n';
- }
- } else if (test.error.message) {
- status += '\n' + indentString(test.error.message, 2) + '\n';
- }
-
- if (test.error.stack) {
- const stack = test.error.stack;
- if (stack.includes('\n')) {
- status += '\n' + indentString(colors.errorStack(stack), 2) + '\n';
- }
- }
-
- status += '\n\n\n';
- });
- }
-
- if (this.rejectionCount > 0 || this.exceptionCount > 0) {
- // TODO(sindresorhus): Figure out why this causes a test failure when switched to a for-of loop
- runStatus.errors.forEach(err => {
- if (err.title) {
- return;
- }
-
- if (err.type === 'exception' && err.name === 'AvaError') {
- status += ' ' + colors.error(cross + ' ' + err.message) + '\n\n';
- } else {
- const title = err.type === 'rejection' ? 'Unhandled Rejection' : 'Uncaught Exception';
- status += ' ' + colors.title(title) + '\n';
-
- if (err.name) {
- status += ' ' + colors.stack(err.summary) + '\n';
- status += colors.errorStack(err.stack) + '\n\n';
- } else {
- status += ' Threw non-error: ' + err.summary + '\n';
- }
- }
- });
- }
-
- if (runStatus.failFastEnabled === true && runStatus.remainingCount > 0 && runStatus.failCount > 0) {
- const remaining = 'At least ' + runStatus.remainingCount + ' ' + plur('test was', 'tests were', runStatus.remainingCount) + ' skipped.';
- status += ' ' + colors.information('`--fail-fast` is on. ' + remaining) + '\n\n';
- }
-
- if (runStatus.hasExclusive === true && runStatus.remainingCount > 0) {
- status += ' ' + colors.information('The .only() modifier is used in some tests.', runStatus.remainingCount, plur('test', runStatus.remainingCount), plur('was', 'were', runStatus.remainingCount), 'not run');
- }
-
- return '\n' + trimOffNewlines(status) + '\n';
- }
-
- section() {
- return '\n' + chalk.gray.dim('\u2500'.repeat(process.stdout.columns || 80));
- }
-
- clear() {
- return '';
- }
-
- write(str) {
- cliCursor.hide();
- this.currentStatus = str;
- this._update();
- this.statusLineCount = this.currentStatus.split('\n').length;
- }
-
- stdout(data) {
- this._update(data);
- }
-
- stderr(data) {
- this._update(data);
- }
-
- _update(data) {
- let str = '';
- let ct = this.statusLineCount;
- const columns = process.stdout.columns;
- let lastLine = this.lastLineTracker.lastLine();
-
- // Terminals automatically wrap text. We only need the last log line as seen on the screen.
- lastLine = lastLine.substring(lastLine.length - (lastLine.length % columns));
-
- // Don't delete the last log line if it's completely empty.
- if (lastLine.length > 0) {
- ct++;
- }
-
- // Erase the existing status message, plus the last log line.
- str += ansiEscapes.eraseLines(ct);
-
- // Rewrite the last log line.
- str += lastLine;
-
- if (str.length > 0) {
- this.stream.write(str);
- }
-
- if (data) {
- // Send new log data to the terminal, and update the last line status.
- this.lastLineTracker.update(this.stringDecoder.write(data));
- this.stream.write(data);
- }
-
- let currentStatus = this.currentStatus;
-
- if (currentStatus.length > 0) {
- lastLine = this.lastLineTracker.lastLine();
- // We need a newline at the end of the last log line, before the status message.
- // However, if the last log line is the exact width of the terminal a newline is implied,
- // and adding a second will cause problems.
- if (lastLine.length % columns) {
- currentStatus = '\n' + currentStatus;
- }
- // Rewrite the status message.
- this.stream.write(currentStatus);
- }
- }
-}
-
-module.exports = MiniReporter;
diff --git a/node_modules/ava/lib/reporters/tap.js b/node_modules/ava/lib/reporters/tap.js
deleted file mode 100644
index 5ef8a23e3..000000000
--- a/node_modules/ava/lib/reporters/tap.js
+++ /dev/null
@@ -1,132 +0,0 @@
-'use strict';
-const format = require('util').format;
-const indentString = require('indent-string');
-const stripAnsi = require('strip-ansi');
-const yaml = require('js-yaml');
-
-function dumpError(error, includeMessage) {
- const obj = Object.assign({}, error.object);
- if (error.name) {
- obj.name = error.name;
- }
- if (includeMessage && error.message) {
- obj.message = error.message;
- }
-
- if (error.avaAssertionError) {
- if (error.assertion) {
- obj.assertion = error.assertion;
- }
- if (error.operator) {
- obj.operator = error.operator;
- }
- if (error.values.length > 0) {
- obj.values = error.values.reduce((acc, value) => {
- acc[value.label] = stripAnsi(value.formatted);
- return acc;
- }, {});
- }
- }
-
- if (error.stack) {
- obj.at = error.stack.split('\n')[0];
- }
-
- return ` ---\n${indentString(yaml.safeDump(obj).trim(), 4)}\n ...`;
-}
-
-class TapReporter {
- constructor() {
- this.i = 0;
- }
-
- start() {
- return 'TAP version 13';
- }
-
- test(test) {
- const output = [];
-
- let directive = '';
- const passed = test.todo ? 'not ok' : 'ok';
-
- if (test.todo) {
- directive = '# TODO';
- } else if (test.skip) {
- directive = '# SKIP';
- }
-
- const title = stripAnsi(test.title);
-
- const appendLogs = () => {
- if (test.logs) {
- test.logs.forEach(log => {
- const logLines = indentString(log, 4);
- const logLinesWithLeadingFigure = logLines.replace(
- /^ {4}/,
- ' * '
- );
-
- output.push(logLinesWithLeadingFigure);
- });
- }
- };
-
- output.push(`# ${title}`);
-
- if (test.error) {
- output.push(format('not ok %d - %s', ++this.i, title));
- appendLogs();
- output.push(dumpError(test.error, true));
- } else {
- output.push(format('%s %d - %s %s', passed, ++this.i, title, directive).trim());
- appendLogs();
- }
-
- return output.join('\n');
- }
-
- unhandledError(err) {
- const output = [
- `# ${err.message}`,
- format('not ok %d - %s', ++this.i, err.message)
- ];
- // AvaErrors don't have stack traces
- if (err.type !== 'exception' || err.name !== 'AvaError') {
- output.push(dumpError(err, false));
- }
-
- return output.join('\n');
- }
-
- finish(runStatus) {
- const output = [
- '',
- '1..' + (runStatus.passCount + runStatus.failCount + runStatus.skipCount),
- '# tests ' + (runStatus.passCount + runStatus.failCount + runStatus.skipCount),
- '# pass ' + runStatus.passCount
- ];
-
- if (runStatus.skipCount > 0) {
- output.push(`# skip ${runStatus.skipCount}`);
- }
-
- output.push('# fail ' + (runStatus.failCount + runStatus.rejectionCount + runStatus.exceptionCount), '');
-
- return output.join('\n');
- }
-
- write(str) {
- console.log(str);
- }
-
- stdout(data) {
- process.stderr.write(data);
- }
-
- stderr(data) {
- this.stdout(data);
- }
-}
-
-module.exports = TapReporter;
diff --git a/node_modules/ava/lib/reporters/verbose.js b/node_modules/ava/lib/reporters/verbose.js
deleted file mode 100644
index c58d8db3b..000000000
--- a/node_modules/ava/lib/reporters/verbose.js
+++ /dev/null
@@ -1,204 +0,0 @@
-'use strict';
-const indentString = require('indent-string');
-const prettyMs = require('pretty-ms');
-const figures = require('figures');
-const chalk = require('chalk');
-const plur = require('plur');
-const trimOffNewlines = require('trim-off-newlines');
-const codeExcerpt = require('../code-excerpt');
-const colors = require('../colors');
-const formatSerializedError = require('./format-serialized-error');
-const improperUsageMessages = require('./improper-usage-messages');
-
-class VerboseReporter {
- constructor(options) {
- this.options = Object.assign({}, options);
-
- chalk.enabled = this.options.color;
- for (const key of Object.keys(colors)) {
- colors[key].enabled = this.options.color;
- }
- }
-
- start() {
- return '';
- }
-
- test(test, runStatus) {
- const lines = [];
- if (test.error) {
- lines.push(' ' + colors.error(figures.cross) + ' ' + test.title + ' ' + colors.error(test.error.message));
- } else if (test.todo) {
- lines.push(' ' + colors.todo('- ' + test.title));
- } else if (test.skip) {
- lines.push(' ' + colors.skip('- ' + test.title));
- } else if (test.failing) {
- lines.push(' ' + colors.error(figures.tick) + ' ' + colors.error(test.title));
- } else if (runStatus.fileCount === 1 && runStatus.testCount === 1 && test.title === '[anonymous]') {
- // No output
- } else {
- // Display duration only over a threshold
- const threshold = 100;
- const duration = test.duration > threshold ? colors.duration(' (' + prettyMs(test.duration) + ')') : '';
-
- lines.push(' ' + colors.pass(figures.tick) + ' ' + test.title + duration);
- }
-
- if (test.logs) {
- test.logs.forEach(log => {
- const logLines = indentString(colors.log(log), 6);
- const logLinesWithLeadingFigure = logLines.replace(
- /^ {6}/,
- ` ${colors.information(figures.info)} `
- );
-
- lines.push(logLinesWithLeadingFigure);
- });
- }
-
- return lines.length > 0 ? lines.join('\n') : undefined;
- }
-
- unhandledError(err) {
- if (err.type === 'exception' && err.name === 'AvaError') {
- return colors.error(' ' + figures.cross + ' ' + err.message);
- }
-
- const types = {
- rejection: 'Unhandled Rejection',
- exception: 'Uncaught Exception'
- };
-
- let output = colors.error(types[err.type] + ':', err.file) + '\n';
-
- if (err.stack) {
- output += ' ' + colors.stack(err.title || err.summary) + '\n';
- output += ' ' + colors.stack(err.stack) + '\n';
- } else {
- output += ' ' + colors.stack(JSON.stringify(err)) + '\n';
- }
-
- output += '\n';
-
- return output;
- }
-
- finish(runStatus) {
- let output = '';
-
- const lines = [
- runStatus.failCount > 0 ?
- ' ' + colors.error(runStatus.failCount, plur('test', runStatus.failCount), 'failed') :
- ' ' + colors.pass(runStatus.passCount, plur('test', runStatus.passCount), 'passed'),
- runStatus.knownFailureCount > 0 ? ' ' + colors.error(runStatus.knownFailureCount, plur('known failure', runStatus.knownFailureCount)) : '',
- runStatus.skipCount > 0 ? ' ' + colors.skip(runStatus.skipCount, plur('test', runStatus.skipCount), 'skipped') : '',
- runStatus.todoCount > 0 ? ' ' + colors.todo(runStatus.todoCount, plur('test', runStatus.todoCount), 'todo') : '',
- runStatus.rejectionCount > 0 ? ' ' + colors.error(runStatus.rejectionCount, 'unhandled', plur('rejection', runStatus.rejectionCount)) : '',
- runStatus.exceptionCount > 0 ? ' ' + colors.error(runStatus.exceptionCount, 'uncaught', plur('exception', runStatus.exceptionCount)) : '',
- runStatus.previousFailCount > 0 ? ' ' + colors.error(runStatus.previousFailCount, 'previous', plur('failure', runStatus.previousFailCount), 'in test files that were not rerun') : ''
- ].filter(Boolean);
-
- if (lines.length > 0) {
- if (this.options.watching) {
- lines[0] += ' ' + chalk.gray.dim('[' + new Date().toLocaleTimeString('en-US', {hour12: false}) + ']');
- }
- output += lines.join('\n') + '\n';
- }
-
- if (runStatus.knownFailureCount > 0) {
- runStatus.knownFailures.forEach(test => {
- output += '\n\n ' + colors.error(test.title) + '\n';
- });
- }
-
- output += '\n';
- if (runStatus.failCount > 0) {
- runStatus.tests.forEach(test => {
- if (!test.error) {
- return;
- }
-
- output += ' ' + colors.title(test.title) + '\n';
-
- if (test.logs) {
- test.logs.forEach(log => {
- const logLines = indentString(colors.log(log), 6);
- const logLinesWithLeadingFigure = logLines.replace(
- /^ {6}/,
- ` ${colors.information(figures.info)} `
- );
-
- output += logLinesWithLeadingFigure + '\n';
- });
-
- output += '\n';
- }
-
- if (test.error.source) {
- output += ' ' + colors.errorSource(test.error.source.file + ':' + test.error.source.line) + '\n';
-
- const excerpt = codeExcerpt(test.error.source, {maxWidth: process.stdout.columns});
- if (excerpt) {
- output += '\n' + indentString(excerpt, 2) + '\n';
- }
- }
-
- if (test.error.avaAssertionError) {
- const result = formatSerializedError(test.error);
- if (result.printMessage) {
- output += '\n' + indentString(test.error.message, 2) + '\n';
- }
-
- if (result.formatted) {
- output += '\n' + indentString(result.formatted, 2) + '\n';
- }
-
- const message = improperUsageMessages.forError(test.error);
- if (message) {
- output += '\n' + indentString(message, 2) + '\n';
- }
- } else if (test.error.message) {
- output += '\n' + indentString(test.error.message, 2) + '\n';
- }
-
- if (test.error.stack) {
- const stack = test.error.stack;
- if (stack.includes('\n')) {
- output += '\n' + indentString(colors.errorStack(stack), 2) + '\n';
- }
- }
-
- output += '\n\n\n';
- });
- }
-
- if (runStatus.failFastEnabled === true && runStatus.remainingCount > 0 && runStatus.failCount > 0) {
- const remaining = 'At least ' + runStatus.remainingCount + ' ' + plur('test was', 'tests were', runStatus.remainingCount) + ' skipped.';
- output += ' ' + colors.information('`--fail-fast` is on. ' + remaining) + '\n\n';
- }
-
- if (runStatus.hasExclusive === true && runStatus.remainingCount > 0) {
- output += ' ' + colors.information('The .only() modifier is used in some tests.', runStatus.remainingCount, plur('test', runStatus.remainingCount), plur('was', 'were', runStatus.remainingCount), 'not run');
- }
-
- return '\n' + trimOffNewlines(output) + '\n';
- }
-
- section() {
- return chalk.gray.dim('\u2500'.repeat(process.stdout.columns || 80));
- }
-
- write(str) {
- console.error(str);
- }
-
- stdout(data) {
- process.stderr.write(data);
- }
-
- stderr(data) {
- process.stderr.write(data);
- }
-}
-
-module.exports = VerboseReporter;
diff --git a/node_modules/ava/lib/run-status.js b/node_modules/ava/lib/run-status.js
deleted file mode 100644
index 461ab8f90..000000000
--- a/node_modules/ava/lib/run-status.js
+++ /dev/null
@@ -1,136 +0,0 @@
-'use strict';
-const EventEmitter = require('events');
-const chalk = require('chalk');
-const flatten = require('arr-flatten');
-const figures = require('figures');
-const autoBind = require('auto-bind');
-const prefixTitle = require('./prefix-title');
-
-function sum(arr, key) {
- let result = 0;
-
- arr.forEach(item => {
- result += item[key];
- });
-
- return result;
-}
-
-class RunStatus extends EventEmitter {
- constructor(opts) {
- super();
-
- opts = opts || {};
- this.prefixTitles = opts.prefixTitles !== false;
- this.hasExclusive = Boolean(opts.runOnlyExclusive);
- this.base = opts.base || '';
- this.rejectionCount = 0;
- this.exceptionCount = 0;
- this.passCount = 0;
- this.knownFailureCount = 0;
- this.skipCount = 0;
- this.todoCount = 0;
- this.failCount = 0;
- this.fileCount = 0;
- this.testCount = 0;
- this.remainingCount = 0;
- this.previousFailCount = 0;
- this.knownFailures = [];
- this.errors = [];
- this.stats = [];
- this.tests = [];
- this.failFastEnabled = opts.failFast || false;
- this.updateSnapshots = opts.updateSnapshots || false;
-
- autoBind(this);
- }
-
- observeFork(emitter) {
- emitter
- .on('teardown', this.handleTeardown)
- .on('stats', this.handleStats)
- .on('test', this.handleTest)
- .on('unhandledRejections', this.handleRejections)
- .on('uncaughtException', this.handleExceptions)
- .on('stdout', this.handleOutput.bind(this, 'stdout'))
- .on('stderr', this.handleOutput.bind(this, 'stderr'));
- }
-
- handleRejections(data) {
- this.rejectionCount += data.rejections.length;
-
- data.rejections.forEach(err => {
- err.type = 'rejection';
- err.file = data.file;
- this.emit('error', err, this);
- this.errors.push(err);
- });
- }
-
- handleExceptions(data) {
- this.exceptionCount++;
- const err = data.exception;
- err.type = 'exception';
- err.file = data.file;
- this.emit('error', err, this);
- this.errors.push(err);
- }
-
- handleTeardown(data) {
- this.emit('dependencies', data.file, data.dependencies, this);
- this.emit('touchedFiles', data.touchedFiles);
- }
-
- handleStats(stats) {
- this.emit('stats', stats, this);
-
- if (stats.hasExclusive) {
- this.hasExclusive = true;
- }
-
- this.testCount += stats.testCount;
- }
-
- handleTest(test) {
- test.title = this.prefixTitle(test.file) + test.title;
-
- if (test.error) {
- this.errors.push(test);
- }
-
- if (test.failing && !test.error) {
- this.knownFailures.push(test);
- }
-
- this.emit('test', test, this);
- }
-
- prefixTitle(file) {
- if (!this.prefixTitles) {
- return '';
- }
-
- const separator = ' ' + chalk.gray.dim(figures.pointerSmall) + ' ';
-
- return prefixTitle(file, this.base, separator);
- }
-
- handleOutput(channel, data) {
- this.emit(channel, data, this);
- }
-
- processResults(results) {
- // Assemble stats from all tests
- this.stats = results.map(result => result.stats);
- this.tests = results.map(result => result.tests);
- this.tests = flatten(this.tests);
- this.passCount = sum(this.stats, 'passCount');
- this.knownFailureCount = sum(this.stats, 'knownFailureCount');
- this.skipCount = sum(this.stats, 'skipCount');
- this.todoCount = sum(this.stats, 'todoCount');
- this.failCount = sum(this.stats, 'failCount');
- this.remainingCount = this.testCount - this.passCount - this.failCount - this.skipCount - this.todoCount - this.knownFailureCount;
- }
-}
-
-module.exports = RunStatus;
diff --git a/node_modules/ava/lib/runner.js b/node_modules/ava/lib/runner.js
deleted file mode 100644
index eb02dde45..000000000
--- a/node_modules/ava/lib/runner.js
+++ /dev/null
@@ -1,232 +0,0 @@
-'use strict';
-const EventEmitter = require('events');
-const path = require('path');
-const Bluebird = require('bluebird');
-const optionChain = require('option-chain');
-const matcher = require('matcher');
-const snapshotManager = require('./snapshot-manager');
-const TestCollection = require('./test-collection');
-const validateTest = require('./validate-test');
-
-const chainableMethods = {
- defaults: {
- type: 'test',
- serial: false,
- exclusive: false,
- skipped: false,
- todo: false,
- failing: false,
- callback: false,
- always: false
- },
- chainableMethods: {
- test: {},
- serial: {serial: true},
- before: {type: 'before'},
- after: {type: 'after'},
- skip: {skipped: true},
- todo: {todo: true},
- failing: {failing: true},
- only: {exclusive: true},
- beforeEach: {type: 'beforeEach'},
- afterEach: {type: 'afterEach'},
- cb: {callback: true},
- always: {always: true}
- }
-};
-
-function wrapFunction(fn, args) {
- return function (t) {
- return fn.apply(this, [t].concat(args));
- };
-}
-
-class Runner extends EventEmitter {
- constructor(options) {
- super();
-
- options = options || {};
-
- this.file = options.file;
- this.match = options.match || [];
- this.projectDir = options.projectDir;
- this.serial = options.serial;
- this.updateSnapshots = options.updateSnapshots;
- this.snapshotDir = options.snapshotDir;
-
- this.hasStarted = false;
- this.results = [];
- this.snapshots = null;
- this.tests = new TestCollection({
- bail: options.bail,
- failWithoutAssertions: options.failWithoutAssertions,
- compareTestSnapshot: this.compareTestSnapshot.bind(this)
- });
-
- this.chain = optionChain(chainableMethods, (opts, args) => {
- let title;
- let fn;
- let macroArgIndex;
-
- if (this.hasStarted) {
- throw new Error('All tests and hooks must be declared synchronously in your ' +
- 'test file, and cannot be nested within other tests or hooks.');
- }
-
- if (typeof args[0] === 'string') {
- title = args[0];
- fn = args[1];
- macroArgIndex = 2;
- } else {
- fn = args[0];
- title = null;
- macroArgIndex = 1;
- }
-
- if (this.serial) {
- opts.serial = true;
- }
-
- if (args.length > macroArgIndex) {
- args = args.slice(macroArgIndex);
- } else {
- args = null;
- }
-
- if (Array.isArray(fn)) {
- fn.forEach(fn => {
- this.addTest(title, opts, fn, args);
- });
- } else {
- this.addTest(title, opts, fn, args);
- }
- });
- }
-
- addTest(title, metadata, fn, args) {
- if (args) {
- if (fn.title) {
- title = fn.title.apply(fn, [title || ''].concat(args));
- }
-
- fn = wrapFunction(fn, args);
- }
-
- if (metadata.type === 'test' && this.match.length > 0) {
- metadata.exclusive = matcher([title || ''], this.match).length === 1;
- }
-
- const validationError = validateTest(title, fn, metadata);
- if (validationError !== null) {
- throw new TypeError(validationError);
- }
-
- this.tests.add({
- metadata,
- fn,
- title
- });
- }
-
- addTestResult(result) {
- const test = result.result;
- const props = {
- logs: test.logs,
- duration: test.duration,
- title: test.title,
- error: result.reason,
- type: test.metadata.type,
- skip: test.metadata.skipped,
- todo: test.metadata.todo,
- failing: test.metadata.failing
- };
-
- this.results.push(result);
- this.emit('test', props);
- }
-
- buildStats() {
- const stats = {
- failCount: 0,
- knownFailureCount: 0,
- passCount: 0,
- skipCount: 0,
- testCount: 0,
- todoCount: 0
- };
-
- for (const result of this.results) {
- if (!result.passed) {
- // Includes hooks
- stats.failCount++;
- }
-
- const metadata = result.result.metadata;
- if (metadata.type === 'test') {
- stats.testCount++;
-
- if (metadata.skipped) {
- stats.skipCount++;
- } else if (metadata.todo) {
- stats.todoCount++;
- } else if (result.passed) {
- if (metadata.failing) {
- stats.knownFailureCount++;
- } else {
- stats.passCount++;
- }
- }
- }
- }
-
- return stats;
- }
-
- compareTestSnapshot(options) {
- if (!this.snapshots) {
- this.snapshots = snapshotManager.load({
- file: this.file,
- fixedLocation: this.snapshotDir,
- name: path.basename(this.file),
- projectDir: this.projectDir,
- relFile: path.relative(this.projectDir, this.file),
- testDir: path.dirname(this.file),
- updating: this.updateSnapshots
- });
- this.emit('dependency', this.snapshots.snapPath);
- }
-
- return this.snapshots.compare(options);
- }
-
- saveSnapshotState() {
- if (this.snapshots) {
- const files = this.snapshots.save();
- if (files) {
- this.emit('touched', files);
- }
- } else if (this.updateSnapshots) {
- // TODO: There may be unused snapshot files if no test caused the
- // snapshots to be loaded. Prune them. But not if tests (including hooks!)
- // were skipped. Perhaps emit a warning if this occurs?
- }
- }
-
- run(options) {
- if (options.runOnlyExclusive && !this.tests.hasExclusive) {
- return Promise.resolve(null);
- }
-
- this.hasStarted = true;
- this.tests.on('test', result => {
- this.addTestResult(result);
- });
- return Bluebird.try(() => this.tests.build().run());
- }
-
- attributeLeakedError(err) {
- return this.tests.attributeLeakedError(err);
- }
-}
-
-module.exports = Runner;
diff --git a/node_modules/ava/lib/sequence.js b/node_modules/ava/lib/sequence.js
deleted file mode 100644
index 1e5960a98..000000000
--- a/node_modules/ava/lib/sequence.js
+++ /dev/null
@@ -1,94 +0,0 @@
-'use strict';
-
-const beforeExitSubscribers = new Set();
-const beforeExitHandler = () => {
- for (const subscriber of beforeExitSubscribers) {
- subscriber();
- }
-};
-const onBeforeExit = subscriber => {
- if (beforeExitSubscribers.size === 0) {
- // Only listen for the event once, no matter how many Sequences are run
- // concurrently.
- process.on('beforeExit', beforeExitHandler);
- }
-
- beforeExitSubscribers.add(subscriber);
- return {
- dispose() {
- beforeExitSubscribers.delete(subscriber);
- if (beforeExitSubscribers.size === 0) {
- process.removeListener('beforeExit', beforeExitHandler);
- }
- }
- };
-};
-
-class Sequence {
- constructor(runnables, bail) {
- if (!Array.isArray(runnables)) {
- throw new TypeError('Expected an array of runnables');
- }
-
- this.runnables = runnables;
- this.bail = bail || false;
- }
-
- run() {
- const iterator = this.runnables[Symbol.iterator]();
-
- let activeRunnable;
- const beforeExit = onBeforeExit(() => {
- if (activeRunnable.finishDueToInactivity) {
- activeRunnable.finishDueToInactivity();
- }
- });
-
- let allPassed = true;
- const finish = () => {
- beforeExit.dispose();
- return allPassed;
- };
-
- const runNext = () => {
- let promise;
-
- for (let next = iterator.next(); !next.done; next = iterator.next()) {
- activeRunnable = next.value;
- const passedOrPromise = activeRunnable.run();
- if (!passedOrPromise) {
- allPassed = false;
-
- if (this.bail) {
- // Stop if the test failed and bail mode is on.
- break;
- }
- } else if (passedOrPromise !== true) {
- promise = passedOrPromise;
- break;
- }
- }
-
- if (!promise) {
- return finish();
- }
-
- return promise.then(passed => {
- if (!passed) {
- allPassed = false;
-
- if (this.bail) {
- // Stop if the test failed and bail mode is on.
- return finish();
- }
- }
-
- return runNext();
- });
- };
-
- return runNext();
- }
-}
-
-module.exports = Sequence;
diff --git a/node_modules/ava/lib/serialize-error.js b/node_modules/ava/lib/serialize-error.js
deleted file mode 100644
index 13146ff42..000000000
--- a/node_modules/ava/lib/serialize-error.js
+++ /dev/null
@@ -1,99 +0,0 @@
-'use strict';
-const path = require('path');
-const cleanYamlObject = require('clean-yaml-object');
-const StackUtils = require('stack-utils');
-const assert = require('./assert');
-const beautifyStack = require('./beautify-stack');
-
-function isAvaAssertionError(source) {
- return source instanceof assert.AssertionError;
-}
-
-function filter(propertyName, isRoot) {
- return !isRoot || (propertyName !== 'message' && propertyName !== 'name' && propertyName !== 'stack');
-}
-
-const stackUtils = new StackUtils();
-function extractSource(stack) {
- if (!stack) {
- return null;
- }
-
- const firstStackLine = stack.split('\n')[0];
- return stackUtils.parseLine(firstStackLine);
-}
-function buildSource(source) {
- if (!source) {
- return null;
- }
-
- // Assume the CWD is the project directory. This holds since this function
- // is only called in test workers, which are created with their working
- // directory set to the project directory.
- const projectDir = process.cwd();
-
- const file = path.resolve(projectDir, source.file.trim());
- const rel = path.relative(projectDir, file);
-
- const isWithinProject = rel.split(path.sep)[0] !== '..';
- const isDependency = isWithinProject && path.dirname(rel).split(path.sep).indexOf('node_modules') > -1;
-
- return {
- isDependency,
- isWithinProject,
- file,
- line: source.line
- };
-}
-
-module.exports = error => {
- const stack = typeof error.stack === 'string' ?
- beautifyStack(error.stack) :
- null;
-
- const retval = {
- avaAssertionError: isAvaAssertionError(error),
- source: buildSource(extractSource(stack))
- };
- if (stack) {
- retval.stack = stack;
- }
-
- if (retval.avaAssertionError) {
- retval.improperUsage = error.improperUsage;
- retval.message = error.message;
- retval.name = error.name;
- retval.statements = error.statements;
- retval.values = error.values;
-
- if (error.fixedSource) {
- const source = buildSource(error.fixedSource);
- if (source) {
- retval.source = source;
- }
- }
-
- if (error.assertion) {
- retval.assertion = error.assertion;
- }
- if (error.operator) {
- retval.operator = error.operator;
- }
- } else {
- retval.object = cleanYamlObject(error, filter); // Cleanly copy non-standard properties
- if (typeof error.message === 'string') {
- retval.message = error.message;
- }
- if (typeof error.name === 'string') {
- retval.name = error.name;
- }
- }
-
- if (typeof error.stack === 'string') {
- retval.summary = error.stack.split('\n')[0];
- } else {
- retval.summary = JSON.stringify(error);
- }
-
- return retval;
-};
diff --git a/node_modules/ava/lib/snapshot-manager.js b/node_modules/ava/lib/snapshot-manager.js
deleted file mode 100644
index fcc24922e..000000000
--- a/node_modules/ava/lib/snapshot-manager.js
+++ /dev/null
@@ -1,418 +0,0 @@
-'use strict';
-
-const crypto = require('crypto');
-const fs = require('fs');
-const path = require('path');
-const zlib = require('zlib');
-
-const writeFileAtomic = require('@ava/write-file-atomic');
-const concordance = require('concordance');
-const indentString = require('indent-string');
-const makeDir = require('make-dir');
-const md5Hex = require('md5-hex');
-const Buffer = require('safe-buffer').Buffer;
-const convertSourceMap = require('convert-source-map');
-
-const concordanceOptions = require('./concordance-options').snapshotManager;
-
-// Increment if encoding layout or Concordance serialization versions change. Previous AVA versions will not be able to
-// decode buffers generated by a newer version, so changing this value will require a major version bump of AVA itself.
-// The version is encoded as an unsigned 16 bit integer.
-const VERSION = 1;
-
-const VERSION_HEADER = Buffer.alloc(2);
-VERSION_HEADER.writeUInt16LE(VERSION);
-
-// The decoder matches on the trailing newline byte (0x0A).
-const READABLE_PREFIX = Buffer.from(`AVA Snapshot v${VERSION}\n`, 'ascii');
-const REPORT_SEPARATOR = Buffer.from('\n\n', 'ascii');
-const REPORT_TRAILING_NEWLINE = Buffer.from('\n', 'ascii');
-
-const MD5_HASH_LENGTH = 16;
-
-class SnapshotError extends Error {
- constructor(message, snapPath) {
- super(message);
- this.name = 'SnapshotError';
- this.snapPath = snapPath;
- }
-}
-exports.SnapshotError = SnapshotError;
-
-class ChecksumError extends SnapshotError {
- constructor(snapPath) {
- super('Checksum mismatch', snapPath);
- this.name = 'ChecksumError';
- }
-}
-exports.ChecksumError = ChecksumError;
-
-class VersionMismatchError extends SnapshotError {
- constructor(snapPath, version) {
- super('Unexpected snapshot version', snapPath);
- this.name = 'VersionMismatchError';
- this.snapVersion = version;
- this.expectedVersion = VERSION;
- }
-}
-exports.VersionMismatchError = VersionMismatchError;
-
-const LEGACY_SNAPSHOT_HEADER = Buffer.from('// Jest Snapshot v1');
-function isLegacySnapshot(buffer) {
- return LEGACY_SNAPSHOT_HEADER.equals(buffer.slice(0, LEGACY_SNAPSHOT_HEADER.byteLength));
-}
-
-class LegacyError extends SnapshotError {
- constructor(snapPath) {
- super('Legacy snapshot file', snapPath);
- this.name = 'LegacyError';
- }
-}
-exports.LegacyError = LegacyError;
-
-function tryRead(file) {
- try {
- return fs.readFileSync(file);
- } catch (err) {
- if (err.code === 'ENOENT') {
- return null;
- }
-
- throw err;
- }
-}
-
-function withoutLineEndings(buffer) {
- let newLength = buffer.byteLength - 1;
- while (buffer[newLength] === 0x0A || buffer[newLength] === 0x0D) {
- newLength--;
- }
- return buffer.slice(0, newLength);
-}
-
-function formatEntry(label, descriptor) {
- if (label) {
- label = `> ${label}\n\n`;
- }
- const codeBlock = indentString(concordance.formatDescriptor(descriptor, concordanceOptions), 4);
- return Buffer.from(label + codeBlock, 'utf8');
-}
-
-function combineEntries(entries) {
- const buffers = [];
- let byteLength = 0;
-
- const sortedKeys = Array.from(entries.keys()).sort();
- for (const key of sortedKeys) {
- const keyBuffer = Buffer.from(`\n\n## ${key}\n\n`, 'utf8');
- buffers.push(keyBuffer);
- byteLength += keyBuffer.byteLength;
-
- const formattedEntries = entries.get(key);
- const last = formattedEntries[formattedEntries.length - 1];
- for (const entry of formattedEntries) {
- buffers.push(entry);
- byteLength += entry.byteLength;
-
- if (entry !== last) {
- buffers.push(REPORT_SEPARATOR);
- byteLength += REPORT_SEPARATOR.byteLength;
- }
- }
- }
-
- return {buffers, byteLength};
-}
-
-function generateReport(relFile, snapFile, entries) {
- const combined = combineEntries(entries);
- const buffers = combined.buffers;
- let byteLength = combined.byteLength;
-
- const header = Buffer.from(`# Snapshot report for \`${relFile}\`
-
-The actual snapshot is saved in \`${snapFile}\`.
-
-Generated by [AVA](https://ava.li).`, 'utf8');
- buffers.unshift(header);
- byteLength += header.byteLength;
-
- buffers.push(REPORT_TRAILING_NEWLINE);
- byteLength += REPORT_TRAILING_NEWLINE.byteLength;
- return Buffer.concat(buffers, byteLength);
-}
-
-function appendReportEntries(existingReport, entries) {
- const combined = combineEntries(entries);
- const buffers = combined.buffers;
- let byteLength = combined.byteLength;
-
- const prepend = withoutLineEndings(existingReport);
- buffers.unshift(prepend);
- byteLength += prepend.byteLength;
-
- return Buffer.concat(buffers, byteLength);
-}
-
-function encodeSnapshots(buffersByHash) {
- const buffers = [];
- let byteOffset = 0;
-
- // Entry start and end pointers are relative to the header length. This means
- // it's possible to append new entries to an existing snapshot file, without
- // having to rewrite pointers for existing entries.
- const headerLength = Buffer.alloc(4);
- buffers.push(headerLength);
- byteOffset += 4;
-
- // Allows 65535 hashes (tests or identified snapshots) per file.
- const numHashes = Buffer.alloc(2);
- numHashes.writeUInt16LE(buffersByHash.size);
- buffers.push(numHashes);
- byteOffset += 2;
-
- const entries = [];
- for (const pair of buffersByHash) {
- const hash = pair[0];
- const snapshotBuffers = pair[1];
-
- buffers.push(Buffer.from(hash, 'hex'));
- byteOffset += MD5_HASH_LENGTH;
-
- // Allows 65535 snapshots per hash.
- const numSnapshots = Buffer.alloc(2);
- numSnapshots.writeUInt16LE(snapshotBuffers.length, 0);
- buffers.push(numSnapshots);
- byteOffset += 2;
-
- for (const value of snapshotBuffers) {
- // Each pointer is 32 bits, restricting the total, uncompressed buffer to
- // 4 GiB.
- const start = Buffer.alloc(4);
- const end = Buffer.alloc(4);
- entries.push({start, end, value});
-
- buffers.push(start, end);
- byteOffset += 8;
- }
- }
-
- headerLength.writeUInt32LE(byteOffset, 0);
-
- let bodyOffset = 0;
- for (const entry of entries) {
- const start = bodyOffset;
- const end = bodyOffset + entry.value.byteLength;
- entry.start.writeUInt32LE(start, 0);
- entry.end.writeUInt32LE(end, 0);
- buffers.push(entry.value);
- bodyOffset = end;
- }
- byteOffset += bodyOffset;
-
- const compressed = zlib.gzipSync(Buffer.concat(buffers, byteOffset));
- const md5sum = crypto.createHash('md5').update(compressed).digest();
- return Buffer.concat([
- READABLE_PREFIX,
- VERSION_HEADER,
- md5sum,
- compressed
- ], READABLE_PREFIX.byteLength + VERSION_HEADER.byteLength + MD5_HASH_LENGTH + compressed.byteLength);
-}
-
-function decodeSnapshots(buffer, snapPath) {
- if (isLegacySnapshot(buffer)) {
- throw new LegacyError(snapPath);
- }
-
- // The version starts after the readable prefix, which is ended by a newline
- // byte (0x0A).
- const versionOffset = buffer.indexOf(0x0A) + 1;
- const version = buffer.readUInt16LE(versionOffset);
- if (version !== VERSION) {
- throw new VersionMismatchError(snapPath, version);
- }
-
- const md5sumOffset = versionOffset + 2;
- const compressedOffset = md5sumOffset + MD5_HASH_LENGTH;
- const compressed = buffer.slice(compressedOffset);
-
- const md5sum = crypto.createHash('md5').update(compressed).digest();
- const expectedSum = buffer.slice(md5sumOffset, compressedOffset);
- if (!md5sum.equals(expectedSum)) {
- throw new ChecksumError(snapPath);
- }
-
- const decompressed = zlib.gunzipSync(compressed);
- let byteOffset = 0;
-
- const headerLength = decompressed.readUInt32LE(byteOffset);
- byteOffset += 4;
-
- const snapshotsByHash = new Map();
- const numHashes = decompressed.readUInt16LE(byteOffset);
- byteOffset += 2;
-
- for (let count = 0; count < numHashes; count++) {
- const hash = decompressed.toString('hex', byteOffset, byteOffset + MD5_HASH_LENGTH);
- byteOffset += MD5_HASH_LENGTH;
-
- const numSnapshots = decompressed.readUInt16LE(byteOffset);
- byteOffset += 2;
-
- const snapshotsBuffers = new Array(numSnapshots);
- for (let index = 0; index < numSnapshots; index++) {
- const start = decompressed.readUInt32LE(byteOffset) + headerLength;
- byteOffset += 4;
- const end = decompressed.readUInt32LE(byteOffset) + headerLength;
- byteOffset += 4;
- snapshotsBuffers[index] = decompressed.slice(start, end);
- }
-
- // Allow for new entries to be appended to an existing header, which could
- // lead to the same hash being present multiple times.
- if (snapshotsByHash.has(hash)) {
- snapshotsByHash.set(hash, snapshotsByHash.get(hash).concat(snapshotsBuffers));
- } else {
- snapshotsByHash.set(hash, snapshotsBuffers);
- }
- }
-
- return snapshotsByHash;
-}
-
-class Manager {
- constructor(options) {
- this.appendOnly = options.appendOnly;
- this.dir = options.dir;
- this.relFile = options.relFile;
- this.reportFile = options.reportFile;
- this.snapFile = options.snapFile;
- this.snapPath = options.snapPath;
- this.snapshotsByHash = options.snapshotsByHash;
-
- this.hasChanges = false;
- this.reportEntries = new Map();
- }
-
- compare(options) {
- const hash = md5Hex(options.belongsTo);
- const entries = this.snapshotsByHash.get(hash) || [];
- if (options.index > entries.length) {
- throw new RangeError(`Cannot record snapshot ${options.index} for ${JSON.stringify(options.belongsTo)}, exceeds expected index of ${entries.length}`);
- }
- if (options.index === entries.length) {
- this.record(hash, options);
- return {pass: true};
- }
-
- const snapshotBuffer = entries[options.index];
- const actual = concordance.deserialize(snapshotBuffer, concordanceOptions);
-
- const expected = concordance.describe(options.expected, concordanceOptions);
- const pass = concordance.compareDescriptors(actual, expected);
-
- return {actual, expected, pass};
- }
-
- record(hash, options) {
- const descriptor = concordance.describe(options.expected, concordanceOptions);
-
- this.hasChanges = true;
- const snapshot = concordance.serialize(descriptor);
- if (this.snapshotsByHash.has(hash)) {
- this.snapshotsByHash.get(hash).push(snapshot);
- } else {
- this.snapshotsByHash.set(hash, [snapshot]);
- }
-
- const entry = formatEntry(options.label, descriptor);
- if (this.reportEntries.has(options.belongsTo)) {
- this.reportEntries.get(options.belongsTo).push(entry);
- } else {
- this.reportEntries.set(options.belongsTo, [entry]);
- }
- }
-
- save() {
- if (!this.hasChanges) {
- return null;
- }
-
- const snapPath = this.snapPath;
- const buffer = encodeSnapshots(this.snapshotsByHash);
-
- const reportPath = path.join(this.dir, this.reportFile);
- const existingReport = this.appendOnly ? tryRead(reportPath) : null;
- const reportBuffer = existingReport ?
- appendReportEntries(existingReport, this.reportEntries) :
- generateReport(this.relFile, this.snapFile, this.reportEntries);
-
- makeDir.sync(this.dir);
- const tmpSnapPath = writeFileAtomic.sync(snapPath, buffer);
- const tmpReportPath = writeFileAtomic.sync(reportPath, reportBuffer);
-
- return [tmpSnapPath, tmpReportPath, snapPath, reportPath];
- }
-}
-
-function determineSnapshotDir(options) {
- const testDir = determineSourceMappedDir(options);
- if (options.fixedLocation) {
- const relativeTestLocation = path.relative(options.projectDir, testDir);
- return path.join(options.fixedLocation, relativeTestLocation);
- }
-
- const parts = new Set(path.relative(options.projectDir, testDir).split(path.sep));
- if (parts.has('__tests__')) {
- return path.join(testDir, '__snapshots__');
- }
- if (parts.has('test') || parts.has('tests')) { // Accept tests, even though it's not in the default test patterns
- return path.join(testDir, 'snapshots');
- }
-
- return testDir;
-}
-
-function determineSourceMappedDir(options) {
- const source = tryRead(options.file).toString();
- const converter = convertSourceMap.fromSource(source) || convertSourceMap.fromMapFileSource(source, options.testDir);
- if (converter) {
- const map = converter.toObject();
- const firstSource = `${map.sourceRoot || ''}${map.sources[0]}`;
- const sourceFile = path.resolve(options.testDir, firstSource);
- return path.dirname(sourceFile);
- }
-
- return options.testDir;
-}
-
-function load(options) {
- const dir = determineSnapshotDir(options);
- const reportFile = `${options.name}.md`;
- const snapFile = `${options.name}.snap`;
- const snapPath = path.join(dir, snapFile);
-
- let appendOnly = !options.updating;
- let snapshotsByHash;
-
- if (!options.updating) {
- const buffer = tryRead(snapPath);
- if (buffer) {
- snapshotsByHash = decodeSnapshots(buffer, snapPath);
- } else {
- appendOnly = false;
- }
- }
-
- return new Manager({
- appendOnly,
- dir,
- relFile: options.relFile,
- reportFile,
- snapFile,
- snapPath,
- snapshotsByHash: snapshotsByHash || new Map()
- });
-}
-exports.load = load;
diff --git a/node_modules/ava/lib/test-collection.js b/node_modules/ava/lib/test-collection.js
deleted file mode 100644
index fd34bc489..000000000
--- a/node_modules/ava/lib/test-collection.js
+++ /dev/null
@@ -1,230 +0,0 @@
-'use strict';
-const EventEmitter = require('events');
-const fnName = require('fn-name');
-const Concurrent = require('./concurrent');
-const Sequence = require('./sequence');
-const Test = require('./test');
-
-class TestCollection extends EventEmitter {
- constructor(options) {
- super();
-
- this.bail = options.bail;
- this.failWithoutAssertions = options.failWithoutAssertions;
- this.compareTestSnapshot = options.compareTestSnapshot;
- this.hasExclusive = false;
- this.testCount = 0;
-
- this.tests = {
- concurrent: [],
- serial: []
- };
-
- this.hooks = {
- before: [],
- beforeEach: [],
- after: [],
- afterAlways: [],
- afterEach: [],
- afterEachAlways: []
- };
-
- this.pendingTestInstances = new Set();
-
- this._emitTestResult = this._emitTestResult.bind(this);
- }
-
- add(test) {
- const metadata = test.metadata;
- const type = metadata.type;
-
- if (!type) {
- throw new Error('Test type must be specified');
- }
-
- if (!test.title && test.fn) {
- test.title = fnName(test.fn);
- }
-
- // Workaround for Babel giving anonymous functions a name
- if (test.title === 'callee$0$0') {
- test.title = null;
- }
-
- if (!test.title) {
- if (type === 'test') {
- test.title = '[anonymous]';
- } else {
- test.title = type;
- }
- }
-
- if (metadata.always && type !== 'after' && type !== 'afterEach') {
- throw new Error('"always" can only be used with after and afterEach hooks');
- }
-
- // Add a hook
- if (type !== 'test') {
- if (metadata.exclusive) {
- throw new Error(`"only" cannot be used with a ${type} hook`);
- }
-
- this.hooks[type + (metadata.always ? 'Always' : '')].push(test);
- return;
- }
-
- this.testCount++;
-
- // Add `.only()` tests if `.only()` was used previously
- if (this.hasExclusive && !metadata.exclusive) {
- return;
- }
-
- if (metadata.exclusive && !this.hasExclusive) {
- this.tests.concurrent = [];
- this.tests.serial = [];
- this.hasExclusive = true;
- }
-
- if (metadata.serial) {
- this.tests.serial.push(test);
- } else {
- this.tests.concurrent.push(test);
- }
- }
-
- _skippedTest(test) {
- return {
- run: () => {
- this._emitTestResult({
- passed: true,
- result: test
- });
-
- return true;
- }
- };
- }
-
- _emitTestResult(result) {
- this.pendingTestInstances.delete(result.result);
- this.emit('test', result);
- }
-
- _buildHooks(hooks, testTitle, context) {
- return hooks.map(hook => {
- const test = this._buildHook(hook, testTitle, context);
-
- if (hook.metadata.skipped || hook.metadata.todo) {
- return this._skippedTest(test);
- }
-
- return test;
- });
- }
-
- _buildHook(hook, testTitle, contextRef) {
- let title = hook.title;
-
- if (testTitle) {
- title += ` for ${testTitle}`;
- }
-
- if (!contextRef) {
- contextRef = null;
- }
-
- const test = new Test({
- contextRef,
- failWithoutAssertions: false,
- fn: hook.fn,
- compareTestSnapshot: this.compareTestSnapshot,
- metadata: hook.metadata,
- onResult: this._emitTestResult,
- title
- });
- this.pendingTestInstances.add(test);
- return test;
- }
-
- _buildTest(test, contextRef) {
- if (!contextRef) {
- contextRef = null;
- }
-
- test = new Test({
- contextRef,
- failWithoutAssertions: this.failWithoutAssertions,
- fn: test.fn,
- compareTestSnapshot: this.compareTestSnapshot,
- metadata: test.metadata,
- onResult: this._emitTestResult,
- title: test.title
- });
- this.pendingTestInstances.add(test);
- return test;
- }
-
- _buildTestWithHooks(test) {
- if (test.metadata.skipped || test.metadata.todo) {
- return new Sequence([this._skippedTest(this._buildTest(test))], true);
- }
-
- const context = {context: {}};
-
- const beforeHooks = this._buildHooks(this.hooks.beforeEach, test.title, context);
- const afterHooks = this._buildHooks(this.hooks.afterEach, test.title, context);
-
- let sequence = new Sequence([].concat(beforeHooks, this._buildTest(test, context), afterHooks), true);
- if (this.hooks.afterEachAlways.length > 0) {
- const afterAlwaysHooks = new Sequence(this._buildHooks(this.hooks.afterEachAlways, test.title, context));
- sequence = new Sequence([sequence, afterAlwaysHooks], false);
- }
- return sequence;
- }
-
- _buildTests(tests) {
- return tests.map(test => this._buildTestWithHooks(test));
- }
-
- _hasUnskippedTests() {
- return this.tests.serial.concat(this.tests.concurrent)
- .some(test => {
- return !(test.metadata && test.metadata.skipped === true);
- });
- }
-
- build() {
- const serialTests = new Sequence(this._buildTests(this.tests.serial), this.bail);
- const concurrentTests = new Concurrent(this._buildTests(this.tests.concurrent), this.bail);
- const allTests = new Sequence([serialTests, concurrentTests]);
-
- let finalTests;
- // Only run before and after hooks when there are unskipped tests
- if (this._hasUnskippedTests()) {
- const beforeHooks = new Sequence(this._buildHooks(this.hooks.before));
- const afterHooks = new Sequence(this._buildHooks(this.hooks.after));
- finalTests = new Sequence([beforeHooks, allTests, afterHooks], true);
- } else {
- finalTests = new Sequence([allTests], true);
- }
-
- if (this.hooks.afterAlways.length > 0) {
- const afterAlwaysHooks = new Sequence(this._buildHooks(this.hooks.afterAlways));
- finalTests = new Sequence([finalTests, afterAlwaysHooks], false);
- }
-
- return finalTests;
- }
-
- attributeLeakedError(err) {
- for (const test of this.pendingTestInstances) {
- if (test.attributeLeakedError(err)) {
- return true;
- }
- }
- return false;
- }
-}
-
-module.exports = TestCollection;
diff --git a/node_modules/ava/lib/test-worker.js b/node_modules/ava/lib/test-worker.js
deleted file mode 100644
index 84fba364e..000000000
--- a/node_modules/ava/lib/test-worker.js
+++ /dev/null
@@ -1,141 +0,0 @@
-'use strict';
-
-// Check if the test is being run without AVA cli
-{
- const path = require('path');
- const chalk = require('chalk');
-
- const isForked = typeof process.send === 'function';
- if (!isForked) {
- const fp = path.relative('.', process.argv[1]);
-
- console.log();
- console.error('Test files must be run with the AVA CLI:\n\n ' + chalk.grey.dim('$') + ' ' + chalk.cyan('ava ' + fp) + '\n');
-
- process.exit(1); // eslint-disable-line unicorn/no-process-exit
- }
-}
-
-const currentlyUnhandled = require('currently-unhandled')();
-const isObj = require('is-obj');
-
-const adapter = require('./process-adapter');
-const globals = require('./globals');
-
-const opts = adapter.opts;
-globals.options = opts;
-
-const serializeError = require('./serialize-error');
-
-(opts.require || []).forEach(x => require(x));
-
-adapter.installSourceMapSupport();
-adapter.installPrecompilerHook();
-
-const testPath = opts.file;
-
-const dependencies = new Set();
-adapter.installDependencyTracking(dependencies, testPath);
-
-const touchedFiles = new Set();
-
-// Set when main.js is required (since test files should have `require('ava')`).
-let runner = null;
-exports.setRunner = newRunner => {
- runner = newRunner;
- runner.on('dependency', file => {
- dependencies.add(file);
- });
- runner.on('touched', files => {
- for (const file of files) {
- touchedFiles.add(file);
- }
- });
-};
-
-require(testPath);
-
-// If AVA was not required, show an error
-if (!runner) {
- adapter.send('no-tests', {avaRequired: false});
-}
-
-function attributeLeakedError(err) {
- if (!runner) {
- return false;
- }
-
- return runner.attributeLeakedError(err);
-}
-
-const attributedRejections = new Set();
-process.on('unhandledRejection', (reason, promise) => {
- if (attributeLeakedError(reason)) {
- attributedRejections.add(promise);
- }
-});
-
-process.on('uncaughtException', exception => {
- if (attributeLeakedError(exception)) {
- return;
- }
-
- let serialized;
- try {
- serialized = serializeError(exception);
- } catch (ignore) { // eslint-disable-line unicorn/catch-error-name
- // Avoid using serializeError
- const err = new Error('Failed to serialize uncaught exception');
- serialized = {
- avaAssertionError: false,
- name: err.name,
- message: err.message,
- stack: err.stack
- };
- }
-
- // Ensure the IPC channel is refereced. The uncaught exception will kick off
- // the teardown sequence, for which the messages must be received.
- adapter.ipcChannel.ref();
-
- adapter.send('uncaughtException', {exception: serialized});
-});
-
-let tearingDown = false;
-process.on('ava-teardown', () => {
- // AVA-teardown can be sent more than once
- if (tearingDown) {
- return;
- }
- tearingDown = true;
-
- let rejections = currentlyUnhandled()
- .filter(rejection => !attributedRejections.has(rejection.promise));
-
- if (rejections.length > 0) {
- rejections = rejections.map(rejection => {
- let reason = rejection.reason;
- if (!isObj(reason) || typeof reason.message !== 'string') {
- reason = {
- message: String(reason)
- };
- }
- return serializeError(reason);
- });
-
- adapter.send('unhandledRejections', {rejections});
- }
-
- // Include dependencies in the final teardown message. This ensures the full
- // set of dependencies is included no matter how the process exits, unless
- // it flat out crashes. Also include any files that AVA touched during the
- // test run. This allows the watcher to ignore modifications to those files.
- adapter.send('teardown', {
- dependencies: Array.from(dependencies),
- touchedFiles: Array.from(touchedFiles)
- });
-});
-
-process.on('ava-exit', () => {
- process.exit(0); // eslint-disable-line xo/no-process-exit
-});
diff --git a/node_modules/ava/lib/test.js b/node_modules/ava/lib/test.js
deleted file mode 100644
index 839101b40..000000000
--- a/node_modules/ava/lib/test.js
+++ /dev/null
@@ -1,441 +0,0 @@
-'use strict';
-const isGeneratorFn = require('is-generator-fn');
-const co = require('co-with-promise');
-const concordance = require('concordance');
-const observableToPromise = require('observable-to-promise');
-const isPromise = require('is-promise');
-const isObservable = require('is-observable');
-const plur = require('plur');
-const assert = require('./assert');
-const globals = require('./globals');
-const concordanceOptions = require('./concordance-options').default;
-
-function formatErrorValue(label, error) {
- const formatted = concordance.format(error, concordanceOptions);
- return {label, formatted};
-}
-
-class SkipApi {
- constructor(test) {
- this._test = test;
- }
-}
-
-const captureStack = start => {
- const limitBefore = Error.stackTraceLimit;
- Error.stackTraceLimit = 1;
- const obj = {};
- Error.captureStackTrace(obj, start);
- Error.stackTraceLimit = limitBefore;
- return obj.stack;
-};
-
-class ExecutionContext {
- constructor(test) {
- Object.defineProperties(this, {
- _test: {value: test},
- skip: {value: new SkipApi(test)}
- });
- }
-
- plan(ct) {
- this._test.plan(ct, captureStack(this.plan));
- }
-
- get end() {
- const end = this._test.bindEndCallback();
- const endFn = err => end(err, captureStack(endFn));
- return endFn;
- }
-
- get title() {
- return this._test.title;
- }
-
- get context() {
- const contextRef = this._test.contextRef;
- return contextRef && contextRef.context;
- }
-
- set context(context) {
- const contextRef = this._test.contextRef;
-
- if (!contextRef) {
- this._test.saveFirstError(new Error(`\`t.context\` is not available in ${this._test.metadata.type} tests`));
- return;
- }
-
- contextRef.context = context;
- }
-
- _throwsArgStart(assertion, file, line) {
- this._test.trackThrows({assertion, file, line});
- }
-
- _throwsArgEnd() {
- this._test.trackThrows(null);
- }
-}
-
-{
- const assertions = assert.wrapAssertions({
- log(executionContext, text) {
- executionContext._test.addLog(text);
- },
-
- pass(executionContext) {
- executionContext._test.countPassedAssertion();
- },
-
- pending(executionContext, promise) {
- executionContext._test.addPendingAssertion(promise);
- },
-
- fail(executionContext, error) {
- executionContext._test.addFailedAssertion(error);
- }
- });
- Object.assign(ExecutionContext.prototype, assertions);
-
- function skipFn() {
- this._test.countPassedAssertion();
- }
- Object.keys(assertions).forEach(el => {
- SkipApi.prototype[el] = skipFn;
- });
-}
-
-class Test {
- constructor(options) {
- this.contextRef = options.contextRef;
- this.failWithoutAssertions = options.failWithoutAssertions;
- this.fn = isGeneratorFn(options.fn) ? co.wrap(options.fn) : options.fn;
- this.metadata = options.metadata;
- this.onResult = options.onResult;
- this.title = options.title;
- this.logs = [];
-
- this.snapshotInvocationCount = 0;
- this.compareWithSnapshot = assertionOptions => {
- const belongsTo = assertionOptions.id || this.title;
- const expected = assertionOptions.expected;
- const index = assertionOptions.id ? 0 : this.snapshotInvocationCount++;
- const label = assertionOptions.id ? '' : assertionOptions.message || `Snapshot ${this.snapshotInvocationCount}`;
- return options.compareTestSnapshot({belongsTo, expected, index, label});
- };
-
- this.assertCount = 0;
- this.assertError = undefined;
- this.calledEnd = false;
- this.duration = null;
- this.endCallbackFinisher = null;
- this.finishDueToAttributedError = null;
- this.finishDueToInactivity = null;
- this.finishing = false;
- this.pendingAssertionCount = 0;
- this.pendingThrowsAssertion = null;
- this.planCount = null;
- this.startedAt = 0;
- }
-
- bindEndCallback() {
- if (this.metadata.callback) {
- return (err, stack) => {
- this.endCallback(err, stack);
- };
- }
-
- throw new Error('`t.end()`` is not supported in this context. To use `t.end()` as a callback, you must use "callback mode" via `test.cb(testName, fn)`');
- }
-
- endCallback(err, stack) {
- if (this.calledEnd) {
- this.saveFirstError(new Error('`t.end()` called more than once'));
- return;
- }
- this.calledEnd = true;
-
- if (err) {
- this.saveFirstError(new assert.AssertionError({
- actual: err,
- message: 'Callback called with an error',
- stack,
- values: [formatErrorValue('Callback called with an error:', err)]
- }));
- }
-
- if (this.endCallbackFinisher) {
- this.endCallbackFinisher();
- }
- }
-
- createExecutionContext() {
- return new ExecutionContext(this);
- }
-
- countPassedAssertion() {
- if (this.finishing) {
- this.saveFirstError(new Error('Assertion passed, but test has already finished'));
- }
-
- this.assertCount++;
- }
-
- addLog(text) {
- this.logs.push(text);
- }
-
- addPendingAssertion(promise) {
- if (this.finishing) {
- this.saveFirstError(new Error('Assertion passed, but test has already finished'));
- }
-
- this.assertCount++;
- this.pendingAssertionCount++;
- promise
- .catch(err => this.saveFirstError(err))
- .then(() => this.pendingAssertionCount--);
- }
-
- addFailedAssertion(error) {
- if (this.finishing) {
- this.saveFirstError(new Error('Assertion failed, but test has already finished'));
- }
-
- this.assertCount++;
- this.saveFirstError(error);
- }
-
- saveFirstError(err) {
- if (!this.assertError) {
- this.assertError = err;
- }
- }
-
- plan(count, planStack) {
- if (typeof count !== 'number') {
- throw new TypeError('Expected a number');
- }
-
- this.planCount = count;
-
- // In case the `planCount` doesn't match `assertCount, we need the stack of
- // this function to throw with a useful stack.
- this.planStack = planStack;
- }
-
- verifyPlan() {
- if (!this.assertError && this.planCount !== null && this.planCount !== this.assertCount) {
- this.saveFirstError(new assert.AssertionError({
- assertion: 'plan',
- message: `Planned for ${this.planCount} ${plur('assertion', this.planCount)}, but got ${this.assertCount}.`,
- operator: '===',
- stack: this.planStack
- }));
- }
- }
-
- verifyAssertions() {
- if (!this.assertError) {
- if (this.failWithoutAssertions && !this.calledEnd && this.planCount === null && this.assertCount === 0) {
- this.saveFirstError(new Error('Test finished without running any assertions'));
- } else if (this.pendingAssertionCount > 0) {
- this.saveFirstError(new Error('Test finished, but an assertion is still pending'));
- }
- }
- }
-
- trackThrows(pending) {
- this.pendingThrowsAssertion = pending;
- }
-
- detectImproperThrows(err) {
- if (!this.pendingThrowsAssertion) {
- return false;
- }
-
- const pending = this.pendingThrowsAssertion;
- this.pendingThrowsAssertion = null;
-
- const values = [];
- if (err) {
- values.push(formatErrorValue(`The following error was thrown, possibly before \`t.${pending.assertion}()\` could be called:`, err));
- }
-
- this.saveFirstError(new assert.AssertionError({
- assertion: pending.assertion,
- fixedSource: {file: pending.file, line: pending.line},
- improperUsage: true,
- message: `Improper usage of \`t.${pending.assertion}()\` detected`,
- stack: err instanceof Error && err.stack,
- values
- }));
- return true;
- }
-
- waitForPendingThrowsAssertion() {
- return new Promise(resolve => {
- this.finishDueToAttributedError = () => {
- resolve(this.finishPromised());
- };
-
- this.finishDueToInactivity = () => {
- this.detectImproperThrows();
- resolve(this.finishPromised());
- };
-
- // Wait up to a second to see if an error can be attributed to the
- // pending assertion.
- globals.setTimeout(() => this.finishDueToInactivity(), 1000).unref();
- });
- }
-
- attributeLeakedError(err) {
- if (!this.detectImproperThrows(err)) {
- return false;
- }
-
- this.finishDueToAttributedError();
- return true;
- }
-
- callFn() {
- try {
- return {
- ok: true,
- retval: this.fn(this.createExecutionContext())
- };
- } catch (err) {
- return {
- ok: false,
- error: err
- };
- }
- }
-
- run() {
- this.startedAt = globals.now();
-
- const result = this.callFn();
- if (!result.ok) {
- if (!this.detectImproperThrows(result.error)) {
- this.saveFirstError(new assert.AssertionError({
- message: 'Error thrown in test',
- stack: result.error instanceof Error && result.error.stack,
- values: [formatErrorValue('Error thrown in test:', result.error)]
- }));
- }
- return this.finish();
- }
-
- const returnedObservable = isObservable(result.retval);
- const returnedPromise = isPromise(result.retval);
-
- let promise;
- if (returnedObservable) {
- promise = observableToPromise(result.retval);
- } else if (returnedPromise) {
- // `retval` can be any thenable, so convert to a proper promise.
- promise = Promise.resolve(result.retval);
- }
-
- if (this.metadata.callback) {
- if (returnedObservable || returnedPromise) {
- const asyncType = returnedObservable ? 'observables' : 'promises';
- this.saveFirstError(new Error(`Do not return ${asyncType} from tests declared via \`test.cb(...)\`, if you want to return a promise simply declare the test via \`test(...)\``));
- return this.finish();
- }
-
- if (this.calledEnd) {
- return this.finish();
- }
-
- return new Promise(resolve => {
- this.endCallbackFinisher = () => {
- resolve(this.finishPromised());
- };
-
- this.finishDueToAttributedError = () => {
- resolve(this.finishPromised());
- };
-
- this.finishDueToInactivity = () => {
- this.saveFirstError(new Error('`t.end()` was never called'));
- resolve(this.finishPromised());
- };
- });
- }
-
- if (promise) {
- return new Promise(resolve => {
- this.finishDueToAttributedError = () => {
- resolve(this.finishPromised());
- };
-
- this.finishDueToInactivity = () => {
- const err = returnedObservable ?
- new Error('Observable returned by test never completed') :
- new Error('Promise returned by test never resolved');
- this.saveFirstError(err);
- resolve(this.finishPromised());
- };
-
- promise
- .catch(err => {
- if (!this.detectImproperThrows(err)) {
- this.saveFirstError(new assert.AssertionError({
- message: 'Rejected promise returned by test',
- stack: err instanceof Error && err.stack,
- values: [formatErrorValue('Rejected promise returned by test. Reason:', err)]
- }));
- }
- })
- .then(() => resolve(this.finishPromised()));
- });
- }
-
- return this.finish();
- }
-
- finish() {
- this.finishing = true;
-
- if (!this.assertError && this.pendingThrowsAssertion) {
- return this.waitForPendingThrowsAssertion();
- }
-
- this.verifyPlan();
- this.verifyAssertions();
-
- this.duration = globals.now() - this.startedAt;
-
- let reason = this.assertError;
- let passed = !reason;
-
- if (this.metadata.failing) {
- passed = !passed;
-
- if (passed) {
- reason = undefined;
- } else {
- reason = new Error('Test was expected to fail, but succeeded, you should stop marking the test as failing');
- }
- }
-
- this.onResult({
- passed,
- result: this,
- reason
- });
-
- return passed;
- }
-
- finishPromised() {
- return new Promise(resolve => {
- resolve(this.finish());
- });
- }
-}
-
-module.exports = Test;
diff --git a/node_modules/ava/lib/validate-test.js b/node_modules/ava/lib/validate-test.js
deleted file mode 100644
index 8258a5990..000000000
--- a/node_modules/ava/lib/validate-test.js
+++ /dev/null
@@ -1,48 +0,0 @@
-'use strict';
-
-function validate(title, fn, metadata) {
- if (metadata.type !== 'test') {
- if (metadata.exclusive) {
- return '`only` is only for tests and cannot be used with hooks';
- }
-
- if (metadata.failing) {
- return '`failing` is only for tests and cannot be used with hooks';
- }
-
- if (metadata.todo) {
- return '`todo` is only for documentation of future tests and cannot be used with hooks';
- }
- }
-
- if (metadata.todo) {
- if (typeof fn === 'function') {
- return '`todo` tests are not allowed to have an implementation. Use ' +
- '`test.skip()` for tests with an implementation.';
- }
-
- if (typeof title !== 'string') {
- return '`todo` tests require a title';
- }
-
- if (metadata.skipped || metadata.failing || metadata.exclusive) {
- return '`todo` tests are just for documentation and cannot be used with `skip`, `only`, or `failing`';
- }
- } else if (typeof fn !== 'function') {
- return 'Expected an implementation. Use `test.todo()` for tests without an implementation.';
- }
-
- if (metadata.always) {
- if (!(metadata.type === 'after' || metadata.type === 'afterEach')) {
- return '`always` can only be used with `after` and `afterEach`';
- }
- }
-
- if (metadata.skipped && metadata.exclusive) {
- return '`only` tests cannot be skipped';
- }
-
- return null;
-}
-
-module.exports = validate;
diff --git a/node_modules/ava/lib/watcher.js b/node_modules/ava/lib/watcher.js
deleted file mode 100644
index 3f5ed3ee7..000000000
--- a/node_modules/ava/lib/watcher.js
+++ /dev/null
@@ -1,376 +0,0 @@
-'use strict';
-const nodePath = require('path');
-const debug = require('debug')('ava:watcher');
-const diff = require('lodash.difference');
-const chokidar = require('chokidar');
-const flatten = require('arr-flatten');
-const union = require('array-union');
-const uniq = require('array-uniq');
-const AvaFiles = require('./ava-files');
-
-function rethrowAsync(err) {
- // Don't swallow exceptions. Note that any
- // expected error should already have been logged
- setImmediate(() => {
- throw err;
- });
-}
-
-const MIN_DEBOUNCE_DELAY = 10;
-const INITIAL_DEBOUNCE_DELAY = 100;
-
-class Debouncer {
- constructor(watcher) {
- this.watcher = watcher;
- this.timer = null;
- this.repeat = false;
- }
-
- debounce(delay) {
- if (this.timer) {
- this.again = true;
- return;
- }
-
- delay = delay ? Math.max(delay, MIN_DEBOUNCE_DELAY) : INITIAL_DEBOUNCE_DELAY;
-
- const timer = setTimeout(() => {
- this.watcher.busy.then(() => {
- // Do nothing if debouncing was canceled while waiting for the busy
- // promise to fulfil
- if (this.timer !== timer) {
- return;
- }
-
- if (this.again) {
- this.timer = null;
- this.again = false;
- this.debounce(delay / 2);
- } else {
- this.watcher.runAfterChanges();
- this.timer = null;
- this.again = false;
- }
- });
- }, delay);
-
- this.timer = timer;
- }
-
- cancel() {
- if (this.timer) {
- clearTimeout(this.timer);
- this.timer = null;
- this.again = false;
- }
- }
-}
-
-class TestDependency {
- constructor(file, sources) {
- this.file = file;
- this.sources = sources;
- }
-
- contains(source) {
- return this.sources.indexOf(source) !== -1;
- }
-}
-
-class Watcher {
- constructor(logger, api, files, sources) {
- this.debouncer = new Debouncer(this);
- this.avaFiles = new AvaFiles({
- files,
- sources
- });
-
- this.clearLogOnNextRun = true;
- this.runVector = 0;
- this.previousFiles = files;
- this.run = (specificFiles, updateSnapshots) => {
- if (this.runVector > 0) {
- const cleared = this.clearLogOnNextRun && logger.clear();
- if (!cleared) {
- logger.reset();
- logger.section();
- }
- this.clearLogOnNextRun = true;
-
- logger.reset();
- logger.start();
- }
-
- this.runVector += 1;
-
- const currentVector = this.runVector;
-
- let runOnlyExclusive = false;
-
- if (specificFiles) {
- const exclusiveFiles = specificFiles.filter(file => this.filesWithExclusiveTests.indexOf(file) !== -1);
-
- runOnlyExclusive = exclusiveFiles.length !== this.filesWithExclusiveTests.length;
-
- if (runOnlyExclusive) {
- // The test files that previously contained exclusive tests are always
- // run, together with the remaining specific files.
- const remainingFiles = diff(specificFiles, exclusiveFiles);
- specificFiles = this.filesWithExclusiveTests.concat(remainingFiles);
- }
- }
-
- this.touchedFiles.clear();
- this.previousFiles = specificFiles || files;
- this.busy = api.run(this.previousFiles, {runOnlyExclusive, updateSnapshots: updateSnapshots === true})
- .then(runStatus => {
- runStatus.previousFailCount = this.sumPreviousFailures(currentVector);
- logger.finish(runStatus);
-
- const badCounts = runStatus.failCount + runStatus.rejectionCount + runStatus.exceptionCount;
- this.clearLogOnNextRun = this.clearLogOnNextRun && badCounts === 0;
- })
- .catch(rethrowAsync);
- };
-
- this.testDependencies = [];
- this.trackTestDependencies(api, sources);
-
- this.touchedFiles = new Set();
- this.trackTouchedFiles(api);
-
- this.filesWithExclusiveTests = [];
- this.trackExclusivity(api);
-
- this.filesWithFailures = [];
- this.trackFailures(api);
-
- this.dirtyStates = {};
- this.watchFiles();
- this.rerunAll();
- }
-
- watchFiles() {
- const patterns = this.avaFiles.getChokidarPatterns();
-
- chokidar.watch(patterns.paths, {
- ignored: patterns.ignored,
- ignoreInitial: true
- }).on('all', (event, path) => {
- if (event === 'add' || event === 'change' || event === 'unlink') {
- debug('Detected %s of %s', event, path);
- this.dirtyStates[path] = event;
- this.debouncer.debounce();
- }
- });
- }
-
- trackTestDependencies(api) {
- const relative = absPath => nodePath.relative(process.cwd(), absPath);
-
- api.on('test-run', runStatus => {
- runStatus.on('dependencies', (file, dependencies) => {
- const sourceDeps = dependencies.map(x => relative(x)).filter(this.avaFiles.isSource);
- this.updateTestDependencies(file, sourceDeps);
- });
- });
- }
-
- updateTestDependencies(file, sources) {
- if (sources.length === 0) {
- this.testDependencies = this.testDependencies.filter(dep => dep.file !== file);
- return;
- }
-
- const isUpdate = this.testDependencies.some(dep => {
- if (dep.file !== file) {
- return false;
- }
-
- dep.sources = sources;
-
- return true;
- });
-
- if (!isUpdate) {
- this.testDependencies.push(new TestDependency(file, sources));
- }
- }
-
- trackTouchedFiles(api) {
- api.on('test-run', runStatus => {
- runStatus.on('touchedFiles', files => {
- for (const file of files) {
- this.touchedFiles.add(nodePath.relative(process.cwd(), file));
- }
- });
- });
- }
-
- trackExclusivity(api) {
- api.on('stats', stats => {
- this.updateExclusivity(stats.file, stats.hasExclusive);
- });
- }
-
- updateExclusivity(file, hasExclusiveTests) {
- const index = this.filesWithExclusiveTests.indexOf(file);
-
- if (hasExclusiveTests && index === -1) {
- this.filesWithExclusiveTests.push(file);
- } else if (!hasExclusiveTests && index !== -1) {
- this.filesWithExclusiveTests.splice(index, 1);
- }
- }
-
- trackFailures(api) {
- api.on('test-run', (runStatus, files) => {
- files.forEach(file => {
- this.pruneFailures(nodePath.relative(process.cwd(), file));
- });
-
- const currentVector = this.runVector;
- runStatus.on('error', err => {
- this.countFailure(err.file, currentVector);
- });
- runStatus.on('test', result => {
- if (result.error) {
- this.countFailure(result.file, currentVector);
- }
- });
- });
- }
-
- pruneFailures(file) {
- this.filesWithFailures = this.filesWithFailures.filter(state => state.file !== file);
- }
-
- countFailure(file, vector) {
- const isUpdate = this.filesWithFailures.some(state => {
- if (state.file !== file) {
- return false;
- }
-
- state.count++;
- return true;
- });
-
- if (!isUpdate) {
- this.filesWithFailures.push({
- file,
- vector,
- count: 1
- });
- }
- }
-
- sumPreviousFailures(beforeVector) {
- let total = 0;
-
- this.filesWithFailures.forEach(state => {
- if (state.vector < beforeVector) {
- total += state.count;
- }
- });
-
- return total;
- }
-
- cleanUnlinkedTests(unlinkedTests) {
- unlinkedTests.forEach(testFile => {
- this.updateTestDependencies(testFile, []);
- this.updateExclusivity(testFile, false);
- this.pruneFailures(testFile);
- });
- }
-
- observeStdin(stdin) {
- stdin.resume();
- stdin.setEncoding('utf8');
-
- stdin.on('data', data => {
- data = data.trim().toLowerCase();
- if (data !== 'r' && data !== 'rs' && data !== 'u') {
- return;
- }
-
- // Cancel the debouncer, it might rerun specific tests whereas *all* tests
- // need to be rerun
- this.debouncer.cancel();
- this.busy.then(() => {
- // Cancel the debouncer again, it might have restarted while waiting for
- // the busy promise to fulfil
- this.debouncer.cancel();
- this.clearLogOnNextRun = false;
- if (data === 'u') {
- this.updatePreviousSnapshots();
- } else {
- this.rerunAll();
- }
- });
- });
- }
-
- rerunAll() {
- this.dirtyStates = {};
- this.run();
- }
-
- updatePreviousSnapshots() {
- this.dirtyStates = {};
- this.run(this.previousFiles, true);
- }
-
- runAfterChanges() {
- const dirtyStates = this.dirtyStates;
- this.dirtyStates = {};
-
- const dirtyPaths = Object.keys(dirtyStates).filter(path => {
- if (this.touchedFiles.has(path)) {
- debug('Ignoring known touched file %s', path);
- this.touchedFiles.delete(path);
- return false;
- }
- return true;
- });
- const dirtyTests = dirtyPaths.filter(this.avaFiles.isTest);
- const dirtySources = diff(dirtyPaths, dirtyTests);
- const addedOrChangedTests = dirtyTests.filter(path => dirtyStates[path] !== 'unlink');
- const unlinkedTests = diff(dirtyTests, addedOrChangedTests);
-
- this.cleanUnlinkedTests(unlinkedTests);
-
- // No need to rerun tests if the only change is that tests were deleted
- if (unlinkedTests.length === dirtyPaths.length) {
- return;
- }
-
- if (dirtySources.length === 0) {
- // Run any new or changed tests
- this.run(addedOrChangedTests);
- return;
- }
-
- // Try to find tests that depend on the changed source files
- const testsBySource = dirtySources.map(path => {
- return this.testDependencies.filter(dep => dep.contains(path)).map(dep => {
- debug('%s is a dependency of %s', path, dep.file);
- return dep.file;
- });
- }, this).filter(tests => tests.length > 0);
-
- // Rerun all tests if source files were changed that could not be traced to
- // specific tests
- if (testsBySource.length !== dirtySources.length) {
- debug('Sources remain that cannot be traced to specific tests: %O', dirtySources);
- debug('Rerunning all tests');
- this.run();
- return;
- }
-
- // Run all affected tests
- this.run(union(addedOrChangedTests, uniq(flatten(testsBySource))));
- }
-}
-
-module.exports = Watcher;