Added logging, changed some directory structure

This commit is contained in:
2018-01-13 21:33:40 -05:00
parent f079a5f067
commit 8e72ffb917
73656 changed files with 35284 additions and 53718 deletions

View File

@@ -0,0 +1,4 @@
**/__mocks__/**
**/__tests__/**
src
yarn.lock

View File

@@ -0,0 +1,11 @@
# Jest
🃏 Delightful JavaScript Testing
- **👩🏻‍💻 Easy Setup**: Jest is a complete and easy to set up JavaScript testing solution. In fact, Jest works out of the box for any React project.
- **🏃🏽 Instant Feedback**: Failed tests run first. Fast interactive mode can switch between running all tests or only test files related to changed files.
- **📸 Snapshot Testing**: Jest can [capture snapshots](http://facebook.github.io/jest/docs/snapshot-testing.html) of React trees or other serializable values to simplify UI testing.
Read More: http://facebook.github.io/jest/

View File

@@ -0,0 +1,10 @@
#!/usr/bin/env node
/**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
require('jest-cli/bin/jest');

View File

@@ -0,0 +1,11 @@
'use strict'; /**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
module.exports = require('jest-cli');

View File

@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../jest-cli/bin/jest.js" "$@"
ret=$?
else
node "$basedir/../jest-cli/bin/jest.js" "$@"
ret=$?
fi
exit $ret

View File

@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\jest-cli\bin\jest.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\jest-cli\bin\jest.js" %*
)

View File

@@ -0,0 +1,106 @@
'use strict';
var ESC = '\u001b[';
var x = module.exports;
x.cursorTo = function (x, y) {
if (arguments.length === 0) {
return ESC + 'H';
}
if (arguments.length === 1) {
return ESC + (x + 1) + 'G';
}
return ESC + (y + 1) + ';' + (x + 1) + 'H';
};
x.cursorMove = function (x, y) {
var ret = '';
if (x < 0) {
ret += ESC + (-x) + 'D';
} else if (x > 0) {
ret += ESC + x + 'C';
}
if (y < 0) {
ret += ESC + (-y) + 'A';
} else if (y > 0) {
ret += ESC + y + 'B';
}
return ret;
};
x.cursorUp = function (count) {
return ESC + (typeof count === 'number' ? count : 1) + 'A';
};
x.cursorDown = function (count) {
return ESC + (typeof count === 'number' ? count : 1) + 'B';
};
x.cursorForward = function (count) {
return ESC + (typeof count === 'number' ? count : 1) + 'C';
};
x.cursorBackward = function (count) {
return ESC + (typeof count === 'number' ? count : 1) + 'D';
};
x.cursorLeft = ESC + '1000D';
x.cursorSavePosition = ESC + 's';
x.cursorRestorePosition = ESC + 'u';
x.cursorGetPosition = ESC + '6n';
x.cursorNextLine = ESC + 'E';
x.cursorPrevLine = ESC + 'F';
x.cursorHide = ESC + '?25l';
x.cursorShow = ESC + '?25h';
x.eraseLines = function (count) {
var clear = '';
for (var i = 0; i < count; i++) {
clear += x.cursorLeft + x.eraseEndLine + (i < count - 1 ? x.cursorUp() : '');
}
return clear;
};
x.eraseEndLine = ESC + 'K';
x.eraseStartLine = ESC + '1K';
x.eraseLine = ESC + '2K';
x.eraseDown = ESC + 'J';
x.eraseUp = ESC + '1J';
x.eraseScreen = ESC + '2J';
x.scrollUp = ESC + 'S';
x.scrollDown = ESC + 'T';
x.clearScreen = '\u001bc';
x.beep = '\u0007';
x.image = function (buf, opts) {
opts = opts || {};
var ret = '\u001b]1337;File=inline=1';
if (opts.width) {
ret += ';width=' + opts.width;
}
if (opts.height) {
ret += ';height=' + opts.height;
}
if (opts.preserveAspectRatio === false) {
ret += ';preserveAspectRatio=0';
}
return ret + ':' + buf.toString('base64') + '\u0007';
};
x.iTerm = {};
x.iTerm.setCwd = function (cwd) {
return '\u001b]50;CurrentDir=' + (cwd || process.cwd()) + '\u0007';
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,85 @@
{
"_args": [
[
"ansi-escapes@1.4.0",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project"
]
],
"_from": "ansi-escapes@1.4.0",
"_id": "ansi-escapes@1.4.0",
"_inBundle": false,
"_integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"_location": "/react-scripts/jest/ansi-escapes",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ansi-escapes@1.4.0",
"name": "ansi-escapes",
"escapedName": "ansi-escapes",
"rawSpec": "1.4.0",
"saveSpec": null,
"fetchSpec": "1.4.0"
},
"_requiredBy": [
"/react-scripts/jest/jest-cli"
],
"_resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"_spec": "1.4.0",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/ansi-escapes/issues"
},
"description": "ANSI escape codes for manipulating the terminal",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=0.10.0"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/ansi-escapes#readme",
"keywords": [
"ansi",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"escapes",
"formatting",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text",
"vt100",
"sequence",
"control",
"code",
"codes",
"cursor",
"iterm",
"iterm2"
],
"license": "MIT",
"name": "ansi-escapes",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/ansi-escapes.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "1.4.0"
}

View File

@@ -0,0 +1,176 @@
# ansi-escapes [![Build Status](https://travis-ci.org/sindresorhus/ansi-escapes.svg?branch=master)](https://travis-ci.org/sindresorhus/ansi-escapes)
> [ANSI escape codes](http://www.termsys.demon.co.uk/vtansi.htm) for manipulating the terminal
## Install
```
$ npm install --save ansi-escapes
```
## Usage
```js
const ansiEscapes = require('ansi-escapes');
// moves the cursor two rows up and to the left
process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001b[2A\u001b[1000D'
```
## API
### cursorTo([x, [y]])
Set the absolute position of the cursor. `x0` `y0` is the top left of the screen.
Specify either both `x` & `y`, only `x`, or nothing.
### cursorMove(x, [y])
Set the position of the cursor relative to its current position.
### cursorUp(count)
Move cursor up a specific amount of rows. Default is `1`.
### cursorDown(count)
Move cursor down a specific amount of rows. Default is `1`.
### cursorForward(count)
Move cursor forward a specific amount of rows. Default is `1`.
### cursorBackward(count)
Move cursor backward a specific amount of rows. Default is `1`.
### cursorLeft
Move cursor to the left side.
### cursorSavePosition
Save cursor position.
### cursorRestorePosition
Restore saved cursor position.
### cursorGetPosition
Get cursor position.
### cursorNextLine
Move cursor to the next line.
### cursorPrevLine
Move cursor to the previous line.
### cursorHide
Hide cursor.
### cursorShow
Show cursor.
### eraseLines(count)
Erase from the current cursor position up the specified amount of rows.
### eraseEndLine
Erase from the current cursor position to the end of the current line.
### eraseStartLine
Erase from the current cursor position to the start of the current line.
### eraseLine
Erase the entire current line.
### eraseDown
Erase the screen from the current line down to the bottom of the screen.
### eraseUp
Erase the screen from the current line up to the top of the screen.
### eraseScreen
Erase the screen and move the cursor the top left position.
### scrollUp
Scroll display up one line.
### scrollDown
Scroll display down one line.
### clearScreen
Clear the terminal screen.
### beep
Output a beeping sound.
### image(input, [options])
Display an image.
*Currently only supported on iTerm >=2.9.*
See [term-img](https://github.com/sindresorhus/term-img) for a higher-level module.
#### input
Type: `buffer`
Buffer of an image. Usually read in with `fs.readFile()`.
#### options
##### width
##### height
Type: `string` `number`
The width and height are given as a number followed by a unit, or the word "auto".
- `N`: N character cells.
- `Npx`: N pixels.
- `N%`: N percent of the session's width or height.
- `auto`: The image's inherent size will be used to determine an appropriate dimension.
##### preserveAspectRatio
Type: `boolean`<br>
Default: `true`
### iTerm.setCwd([path])
Type: `string`<br>
Default: `process.cwd()`
[Inform iTerm](https://www.iterm2.com/documentation-escape-codes.html) of the current directory to help semantic history and enable [Cmd-clicking relative paths](https://coderwall.com/p/b7e82q/quickly-open-files-in-iterm-with-cmd-click).
## Related
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,8 @@
'use strict';
module.exports = () => {
const _ = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const stack = new Error().stack.slice(1);
Error.prepareStackTrace = _;
return stack;
};

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,75 @@
{
"_args": [
[
"callsites@2.0.0",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project"
]
],
"_from": "callsites@2.0.0",
"_id": "callsites@2.0.0",
"_inBundle": false,
"_integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"_location": "/react-scripts/jest/callsites",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "callsites@2.0.0",
"name": "callsites",
"escapedName": "callsites",
"rawSpec": "2.0.0",
"saveSpec": null,
"fetchSpec": "2.0.0"
},
"_requiredBy": [
"/react-scripts/jest/jest-cli"
],
"_resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
"_spec": "2.0.0",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/callsites/issues"
},
"description": "Get callsites from the V8 stack trace API",
"devDependencies": {
"ava": "*",
"xo": "*"
},
"engines": {
"node": ">=4"
},
"files": [
"index.js"
],
"homepage": "https://github.com/sindresorhus/callsites#readme",
"keywords": [
"stacktrace",
"v8",
"callsite",
"callsites",
"stack",
"trace",
"function",
"file",
"line",
"debug"
],
"license": "MIT",
"name": "callsites",
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/callsites.git"
},
"scripts": {
"test": "xo && ava"
},
"version": "2.0.0",
"xo": {
"esnext": true
}
}

View File

@@ -0,0 +1,46 @@
# callsites [![Build Status](https://travis-ci.org/sindresorhus/callsites.svg?branch=master)](https://travis-ci.org/sindresorhus/callsites)
> Get callsites from the [V8 stack trace API](https://github.com/v8/v8/wiki/Stack-Trace-API)
## Install
```
$ npm install --save callsites
```
## Usage
```js
const callsites = require('callsites');
function unicorn() {
console.log(callsites()[0].getFileName());
//=> '/Users/sindresorhus/dev/callsites/test.js'
}
unicorn();
```
## API
Returns an array of callsite objects with the following methods:
- `getTypeName`: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.
- `getFunctionName`: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.
- `getMethodName`: returns the name of the property of this or one of its prototypes that holds the current function
- `getFileName`: if this function was defined in a script returns the name of the script
- `getLineNumber`: if this function was defined in a script returns the current line number
- `getColumnNumber`: if this function was defined in a script returns the current column number
- `getEvalOrigin`: if this function was created using a call to eval returns a CallSite object representing the location where eval was called
- `isToplevel`: is this a top-level invocation, that is, is this the global object?
- `isEval`: does this call take place in code defined by a call to eval?
- `isNative`: is this call in native V8 code?
- `isConstructor`: is this a constructor call?
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)

View File

@@ -0,0 +1,4 @@
**/__mocks__/**
**/__tests__/**
src
yarn.lock

View File

@@ -0,0 +1,11 @@
# Jest
🃏 Delightful JavaScript Testing
- **👩🏻‍💻 Easy Setup**: Jest is a complete and easy to set up JavaScript testing solution. In fact, Jest works out of the box for any React project.
- **🏃🏽 Instant Feedback**: Failed tests run first. Fast interactive mode can switch between running all tests or only test files related to changed files.
- **📸 Snapshot Testing**: Jest can [capture snapshots](http://facebook.github.io/jest/docs/snapshot-testing.html) of React trees or other serializable values to simplify UI testing.
Read More: http://facebook.github.io/jest/

View File

@@ -0,0 +1,14 @@
#!/usr/bin/env node
/**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
if (process.env.NODE_ENV == null) {
process.env.NODE_ENV = 'test';
}
require('../build/cli').run();

View File

@@ -0,0 +1,60 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
'use strict';
const chalk = require('chalk');
const ansiEscapes = require('ansi-escapes');
const Prompt = require('./lib/Prompt');
const usage = entity =>
`\n${chalk.bold('Pattern Mode Usage')}\n` +
` ${chalk.dim('\u203A Press')} Esc ${chalk.dim('to exit pattern mode.')}\n` +
` ${chalk.dim('\u203A Press')} Enter ` +
`${chalk.dim(`to apply pattern to all ${entity}.`)}\n` +
`\n`;
const usageRows = usage('').split('\n').length;
module.exports = class PatternPrompt {
constructor(pipe, prompt) {
this._pipe = pipe;
this._prompt = prompt;
this._currentUsageRows = usageRows;
}
run(onSuccess, onCancel, options) {
this._pipe.write(ansiEscapes.cursorHide);
this._pipe.write(ansiEscapes.clearScreen);
if (options && options.header) {
this._pipe.write(options.header + '\n');
this._currentUsageRows = usageRows + options.header.split('\n').length;
} else {
this._currentUsageRows = usageRows;
}
this._pipe.write(usage(this._entityName));
this._pipe.write(ansiEscapes.cursorShow);
this._prompt.enter(this._onChange.bind(this), onSuccess, onCancel);
}
_onChange(pattern, options) {
this._pipe.write(ansiEscapes.eraseLine);
this._pipe.write(ansiEscapes.cursorLeft);
}};

View File

@@ -0,0 +1,84 @@
'use strict';function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}
class ReporterDispatcher {
constructor() {
this._reporters = [];
}
register(reporter) {
this._reporters.push(reporter);
}
unregister(ReporterClass) {
this._reporters = this._reporters.filter(
reporter => !(reporter instanceof ReporterClass));
}
onTestResult(test, testResult, results) {
this._reporters.forEach(
reporter =>
reporter.onTestResult &&
reporter.onTestResult(test, testResult, results));
}
onTestStart(test) {
this._reporters.forEach(
reporter => reporter.onTestStart && reporter.onTestStart(test));
}
onRunStart(results, options) {
this._reporters.forEach(
reporter => reporter.onRunStart && reporter.onRunStart(results, options));
}
onRunComplete(contexts, results) {var _this = this;return _asyncToGenerator(function* () {
for (const reporter of _this._reporters) {
reporter.onRunComplete && (
yield reporter.onRunComplete(contexts, results));
}})();
}
// Return a list of last errors for every reporter
getErrors() {
return this._reporters.reduce((list, reporter) => {
const error = reporter.getLastError && reporter.getLastError();
return error ? list.concat(error) : list;
}, []);
}
hasErrors() {
return this.getErrors().length !== 0;
}} /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/module.exports = ReporterDispatcher;

View File

@@ -0,0 +1,234 @@
'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}(); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const path = require('path');
const micromatch = require('micromatch');
const DependencyResolver = require('jest-resolve-dependencies');
const changedFiles = require('jest-changed-files');var _require =
require('jest-regex-util');const escapePathForRegex = _require.escapePathForRegex,replacePathSepForRegex = _require.replacePathSepForRegex;
const git = changedFiles.git;
const hg = changedFiles.hg;
const determineSCM = path =>
Promise.all([git.isGitRepository(path), hg.isHGRepository(path)]);
const pathToRegex = p => replacePathSepForRegex(p);
const globsToMatcher = globs => {
if (globs == null || globs.length === 0) {
return () => true;
}
const matchers = globs.map(each => micromatch.matcher(each, { dot: true }));
return path => matchers.some(each => each(path));
};
const regexToMatcher = testRegex => {
if (!testRegex) {
return () => true;
}
const regex = new RegExp(pathToRegex(testRegex));
return path => regex.test(path);
};
const toTests = (context, tests) =>
tests.map(path => ({
context,
duration: undefined,
path }));
class SearchSource {
constructor(context, options) {const
config = context.config;
this._context = context;
this._options = options || {
skipNodeResolution: false };
this._rootPattern = new RegExp(
config.roots.map(dir => escapePathForRegex(dir)).join('|'));
const ignorePattern = config.testPathIgnorePatterns;
this._testIgnorePattern = ignorePattern.length ?
new RegExp(ignorePattern.join('|')) :
null;
this._testPathCases = {
roots: path => this._rootPattern.test(path),
testMatch: globsToMatcher(config.testMatch),
testPathIgnorePatterns: path =>
!this._testIgnorePattern || !this._testIgnorePattern.test(path),
testRegex: regexToMatcher(config.testRegex) };
}
_filterTestPathsWithStats(
allPaths,
testPathPattern)
{
const data = {
stats: {},
tests: [],
total: allPaths.length };
const testCases = Object.assign({}, this._testPathCases);
if (testPathPattern) {
const regex = new RegExp(testPathPattern, 'i');
testCases.testPathPattern = path => regex.test(path);
}
const testCasesKeys = Object.keys(testCases);
data.tests = allPaths.filter(test => {
return testCasesKeys.reduce((flag, key) => {
if (testCases[key](test.path)) {
data.stats[key] = ++data.stats[key] || 1;
return flag && true;
}
data.stats[key] = data.stats[key] || 0;
return false;
}, true);
});
return data;
}
_getAllTestPaths(testPathPattern) {
return this._filterTestPathsWithStats(
toTests(this._context, this._context.hasteFS.getAllFiles()),
testPathPattern);
}
isTestFilePath(path) {
return Object.keys(this._testPathCases).every(key =>
this._testPathCases[key](path));
}
findMatchingTests(testPathPattern) {
return this._getAllTestPaths(testPathPattern);
}
findRelatedTests(allPaths) {
const dependencyResolver = new DependencyResolver(
this._context.resolver,
this._context.hasteFS);
return {
tests: toTests(
this._context,
dependencyResolver.resolveInverse(
allPaths,
this.isTestFilePath.bind(this),
{
skipNodeResolution: this._options.skipNodeResolution })) };
}
findRelatedTestsFromPattern(paths) {
if (Array.isArray(paths) && paths.length) {
const resolvedPaths = paths.map(p => path.resolve(process.cwd(), p));
return this.findRelatedTests(new Set(resolvedPaths));
}
return { tests: [] };
}
findChangedTests(options) {
return Promise.all(
this._context.config.roots.map(determineSCM)).
then(repos => {
if (!repos.every((_ref) => {var _ref2 = _slicedToArray(_ref, 2);let gitRepo = _ref2[0],hgRepo = _ref2[1];return gitRepo || hgRepo;})) {
return {
noSCM: true,
tests: [] };
}
return Promise.all(
repos.map((_ref3) => {var _ref4 = _slicedToArray(_ref3, 2);let gitRepo = _ref4[0],hgRepo = _ref4[1];
if (gitRepo) {
return git.findChangedFiles(gitRepo, options);
}
if (hgRepo) {
return hg.findChangedFiles(hgRepo, options);
}
return [];
})).
then(changedPathSets =>
this.findRelatedTests(
new Set(Array.prototype.concat.apply([], changedPathSets))));
});
}
getTestPaths(pattern) {
if (pattern.onlyChanged) {
return this.findChangedTests({ lastCommit: pattern.lastCommit });
} else if (pattern.findRelatedTests && pattern.paths) {
return Promise.resolve(this.findRelatedTestsFromPattern(pattern.paths));
} else if (pattern.testPathPattern != null) {
return Promise.resolve(this.findMatchingTests(pattern.testPathPattern));
} else {
return Promise.resolve({ tests: [] });
}
}}
module.exports = SearchSource;

View File

@@ -0,0 +1,104 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const scroll = require('./lib/scrollList');var _require =
require('./lib/terminalUtils');const getTerminalWidth = _require.getTerminalWidth;
const Prompt = require('./lib/Prompt');
const formatTestNameByPattern = require('./lib/formatTestNameByPattern');var _require2 =
require('./lib/patternModeHelpers');const formatTypeaheadSelection = _require2.formatTypeaheadSelection,printMore = _require2.printMore,printPatternCaret = _require2.printPatternCaret,printPatternMatches = _require2.printPatternMatches,printRestoredPatternCaret = _require2.printRestoredPatternCaret,printStartTyping = _require2.printStartTyping,printTypeaheadItem = _require2.printTypeaheadItem;
const PatternPrompt = require('./PatternPrompt');
module.exports = class TestNamePatternPrompt extends PatternPrompt {
constructor(pipe, prompt) {
super(pipe, prompt);
this._entityName = 'tests';
this._cachedTestResults = [];
}
_onChange(pattern, options) {
super._onChange(pattern, options);
this._printTypeahead(pattern, options);
}
_printTypeahead(pattern, options) {
const matchedTests = this._getMatchedTests(pattern);
const total = matchedTests.length;
const pipe = this._pipe;
const prompt = this._prompt;
printPatternCaret(pattern, pipe);
if (pattern) {
printPatternMatches(
total,
'test',
pipe,
` from ${require('chalk').yellow('cached')} test suites`);
const width = getTerminalWidth();var _scroll =
scroll(total, options);const start = _scroll.start,end = _scroll.end,index = _scroll.index;
prompt.setTypeaheadLength(total);
matchedTests.
slice(start, end).
map(name => formatTestNameByPattern(name, pattern, width - 4)).
map((item, i) => formatTypeaheadSelection(item, i, index, prompt)).
forEach(item => printTypeaheadItem(item, pipe));
if (total > end) {
printMore('test', pipe, total - end);
}
} else {
printStartTyping('test name', pipe);
}
printRestoredPatternCaret(pattern, this._currentUsageRows, pipe);
}
_getMatchedTests(pattern) {
let regex;
try {
regex = new RegExp(pattern, 'i');
} catch (e) {
return [];
}
const matchedTests = [];
this._cachedTestResults.forEach((_ref) => {let testResults = _ref.testResults;return (
testResults.forEach((_ref2) => {let title = _ref2.title;
if (regex.test(title)) {
matchedTests.push(title);
}
}));});
return matchedTests;
}
updateCachedTestResults() {let testResults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
this._cachedTestResults = testResults;
}};

View File

@@ -0,0 +1,114 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk'); // eslint-disable-next-line import/default
const stringLength = require('string-length');
const scroll = require('./lib/scrollList');var _require =
require('./lib/terminalUtils');const getTerminalWidth = _require.getTerminalWidth;
const highlight = require('./lib/highlight');var _require2 =
require('./reporters/utils');const trimAndFormatPath = _require2.trimAndFormatPath;
const Prompt = require('./lib/Prompt');var _require3 =
require('./lib/patternModeHelpers');const formatTypeaheadSelection = _require3.formatTypeaheadSelection,printMore = _require3.printMore,printPatternCaret = _require3.printPatternCaret,printPatternMatches = _require3.printPatternMatches,printRestoredPatternCaret = _require3.printRestoredPatternCaret,printStartTyping = _require3.printStartTyping,printTypeaheadItem = _require3.printTypeaheadItem;
const PatternPrompt = require('./PatternPrompt');
module.exports = class TestPathPatternPrompt extends PatternPrompt {
constructor(pipe, prompt) {
super(pipe, prompt);
this._entityName = 'filenames';
}
_onChange(pattern, options) {
super._onChange(pattern, options);
this._printTypeahead(pattern, options);
}
_printTypeahead(pattern, options) {
const matchedTests = this._getMatchedTests(pattern);
const total = matchedTests.length;
const pipe = this._pipe;
const prompt = this._prompt;
printPatternCaret(pattern, pipe);
if (pattern) {
printPatternMatches(total, 'file', pipe);
const prefix = ` ${chalk.dim('\u203A')} `;
const padding = stringLength(prefix) + 2;
const width = getTerminalWidth();var _scroll =
scroll(total, options);const start = _scroll.start,end = _scroll.end,index = _scroll.index;
prompt.setTypeaheadLength(total);
matchedTests.
slice(start, end).
map((_ref) => {let path = _ref.path,context = _ref.context;
const filePath = trimAndFormatPath(
padding,
context.config,
path,
width);
return highlight(path, filePath, pattern, context.config.rootDir);
}).
map((item, i) => formatTypeaheadSelection(item, i, index, prompt)).
forEach(item => printTypeaheadItem(item, pipe));
if (total > end) {
printMore('file', pipe, total - end);
}
} else {
printStartTyping('filename', pipe);
}
printRestoredPatternCaret(pattern, this._currentUsageRows, pipe);
}
_getMatchedTests(pattern) {
let regex;
try {
regex = new RegExp(pattern, 'i');
} catch (e) {}
let tests = [];
if (regex) {
this._searchSources.forEach((_ref2) => {let searchSource = _ref2.searchSource,context = _ref2.context;
tests = tests.concat(searchSource.findMatchingTests(pattern).tests);
});
}
return tests;
}
updateSearchSources(searchSources) {
this._searchSources = searchSources;
}};

View File

@@ -0,0 +1,514 @@
'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}();function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}var _require =
require('jest-message-util');const formatExecError = _require.formatExecError; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const snapshot = require('jest-snapshot');const pify = require('pify');const throat = require('throat');const workerFarm = require('worker-farm');const DefaultReporter = require('./reporters/DefaultReporter');const NotifyReporter = require('./reporters/NotifyReporter');const SummaryReporter = require('./reporters/SummaryReporter');
const VerboseReporter = require('./reporters/VerboseReporter');
const runTest = require('./runTest');
const TestWatcher = require('./TestWatcher');
const ReporterDispatcher = require('./ReporterDispatcher');
const SLOW_TEST_TIME = 3000;
class CancelRun extends Error {
constructor(message) {
super(message);
this.name = 'CancelRun';
}}
const TEST_WORKER_PATH = require.resolve('./TestWorker');
class TestRunner {
constructor(globalConfig, options) {
this._globalConfig = globalConfig;
this._dispatcher = new ReporterDispatcher();
this._options = options;
this._setupReporters();
}
addReporter(reporter) {
this._dispatcher.register(reporter);
}
removeReporter(ReporterClass) {
this._dispatcher.unregister(ReporterClass);
}
runTests(tests, watcher) {var _this = this;return _asyncToGenerator(function* () {
const timings = [];
const contexts = new Set();
tests.forEach(function (test) {
contexts.add(test.context);
if (test.duration) {
timings.push(test.duration);
}
});
const aggregatedResults = createAggregatedResults(tests.length);
const estimatedTime = Math.ceil(
getEstimatedTime(timings, _this._options.maxWorkers) / 1000);
// Run in band if we only have one test or one worker available.
// If we are confident from previous runs that the tests will finish quickly
// we also run in band to reduce the overhead of spawning workers.
const runInBand =
_this._options.maxWorkers <= 1 ||
tests.length <= 1 ||
tests.length <= 20 &&
timings.length > 0 &&
timings.every(function (timing) {return timing < SLOW_TEST_TIME;});
const onResult = function (test, testResult) {
if (watcher.isInterrupted()) {
return Promise.resolve();
}
if (testResult.testResults.length === 0) {
const message = 'Your test suite must contain at least one test.';
onFailure(test, {
message,
stack: new Error(message).stack });
return Promise.resolve();
}
addResult(aggregatedResults, testResult);
_this._dispatcher.onTestResult(test, testResult, aggregatedResults);
return _this._bailIfNeeded(contexts, aggregatedResults, watcher);
};
const onFailure = function (test, error) {
if (watcher.isInterrupted()) {
return;
}
const testResult = buildFailureTestResult(test.path, error);
testResult.failureMessage = formatExecError(
testResult,
test.context.config,
_this._globalConfig,
test.path);
addResult(aggregatedResults, testResult);
_this._dispatcher.onTestResult(test, testResult, aggregatedResults);
};
const updateSnapshotState = function () {
contexts.forEach(function (context) {
const status = snapshot.cleanup(
context.hasteFS,
_this._globalConfig.updateSnapshot);
aggregatedResults.snapshot.filesRemoved += status.filesRemoved;
});
const updateAll = _this._globalConfig.updateSnapshot === 'all';
aggregatedResults.snapshot.didUpdate = updateAll;
aggregatedResults.snapshot.failure = !!(!updateAll && (
aggregatedResults.snapshot.unchecked ||
aggregatedResults.snapshot.unmatched ||
aggregatedResults.snapshot.filesRemoved));
};
_this._dispatcher.onRunStart(aggregatedResults, {
estimatedTime,
showStatus: !runInBand });
try {
yield runInBand ?
_this._createInBandTestRun(tests, watcher, onResult, onFailure) :
_this._createParallelTestRun(tests, watcher, onResult, onFailure);
} catch (error) {
if (!watcher.isInterrupted()) {
throw error;
}
}
updateSnapshotState();
aggregatedResults.wasInterrupted = watcher.isInterrupted();
yield _this._dispatcher.onRunComplete(contexts, aggregatedResults);
const anyTestFailures = !(aggregatedResults.numFailedTests === 0 &&
aggregatedResults.numRuntimeErrorTestSuites === 0);
const anyReporterErrors = _this._dispatcher.hasErrors();
aggregatedResults.success = !(anyTestFailures ||
aggregatedResults.snapshot.failure ||
anyReporterErrors);
return aggregatedResults;})();
}
_createInBandTestRun(
tests,
watcher,
onResult,
onFailure)
{
const mutex = throat(1);
return tests.reduce(
(promise, test) =>
mutex(() =>
promise.
then(() => {
if (watcher.isInterrupted()) {
throw new CancelRun();
}
this._dispatcher.onTestStart(test);
return runTest(
test.path,
this._globalConfig,
test.context.config,
test.context.resolver);
}).
then(result => onResult(test, result)).
catch(err => onFailure(test, err))),
Promise.resolve());
}
_createParallelTestRun(
tests,
watcher,
onResult,
onFailure)
{
const farm = workerFarm(
{
autoStart: true,
maxConcurrentCallsPerWorker: 1,
maxConcurrentWorkers: this._options.maxWorkers,
maxRetries: 2 },
TEST_WORKER_PATH);
const mutex = throat(this._options.maxWorkers);
const worker = pify(farm);
// Send test suites to workers continuously instead of all at once to track
// the start time of individual tests.
const runTestInWorker = test =>
mutex(() => {
if (watcher.isInterrupted()) {
return Promise.reject();
}
this._dispatcher.onTestStart(test);
return worker({
config: test.context.config,
globalConfig: this._globalConfig,
path: test.path,
rawModuleMap: watcher.isWatchMode() ?
test.context.moduleMap.getRawModuleMap() :
null });
});
const onError = (err, test) => {
onFailure(test, err);
if (err.type === 'ProcessTerminatedError') {
console.error(
'A worker process has quit unexpectedly! ' +
'Most likely this is an initialization error.');
process.exit(1);
}
};
const onInterrupt = new Promise((_, reject) => {
watcher.on('change', state => {
if (state.interrupted) {
reject(new CancelRun());
}
});
});
const runAllTests = Promise.all(
tests.map(test =>
runTestInWorker(test).
then(testResult => onResult(test, testResult)).
catch(error => onError(error, test))));
const cleanup = () => workerFarm.end(farm);
return Promise.race([runAllTests, onInterrupt]).then(cleanup, cleanup);
}
_shouldAddDefaultReporters(reporters) {
return (
!reporters ||
!!reporters.find(reporterConfig => reporterConfig[0] === 'default'));
}
_setupReporters() {var _globalConfig =
this._globalConfig;const collectCoverage = _globalConfig.collectCoverage,notify = _globalConfig.notify,reporters = _globalConfig.reporters;
const isDefault = this._shouldAddDefaultReporters(reporters);
if (isDefault) {
this._setupDefaultReporters();
}
if (reporters && Array.isArray(reporters)) {
this._addCustomReporters(reporters);
}
if (collectCoverage) {
// coverage reporter dependency graph is pretty big and we don't
// want to require it if we're not in the `--coverage` mode
const CoverageReporter = require('./reporters/CoverageReporter');
this.addReporter(
new CoverageReporter(this._globalConfig, {
maxWorkers: this._options.maxWorkers }));
}
if (notify) {
this.addReporter(new NotifyReporter(this._options.startRun));
}
}
_setupDefaultReporters() {
this.addReporter(
this._globalConfig.verbose ?
new VerboseReporter(this._globalConfig) :
new DefaultReporter(this._globalConfig));
this.addReporter(
new SummaryReporter(this._globalConfig, {
pattern: this._options.pattern,
testNamePattern: this._options.testNamePattern,
testPathPattern: this._options.testPathPattern }));
}
_addCustomReporters(reporters) {
const customReporters = reporters.filter(
reporterConfig => reporterConfig[0] !== 'default');
customReporters.forEach((reporter, index) => {var _getReporterProps =
this._getReporterProps(reporter);const options = _getReporterProps.options,path = _getReporterProps.path;
try {
const Reporter = require(path);
this.addReporter(new Reporter(this._globalConfig, options));
} catch (error) {
throw new Error(
'An error occurred while adding the reporter at path "' +
path +
'".' +
error.message);
}
});
}
/**
* Get properties of a reporter in an object
* to make dealing with them less painful.
*/
_getReporterProps(
reporter)
{
if (typeof reporter === 'string') {
return { path: reporter };
} else if (Array.isArray(reporter)) {var _reporter = _slicedToArray(
reporter, 2);const path = _reporter[0],options = _reporter[1];
return { options, path };
}
throw new Error('Reproter should be either a string or an array');
}
_bailIfNeeded(
contexts,
aggregatedResults,
watcher)
{
if (this._globalConfig.bail && aggregatedResults.numFailedTests !== 0) {
if (watcher.isWatchMode()) {
watcher.setState({ interrupted: true });
} else {
const exit = () => process.exit(1);
return this._dispatcher.
onRunComplete(contexts, aggregatedResults).
then(exit).
catch(exit);
}
}
return Promise.resolve();
}}
const createAggregatedResults = numTotalTestSuites => {
return {
numFailedTestSuites: 0,
numFailedTests: 0,
numPassedTestSuites: 0,
numPassedTests: 0,
numPendingTestSuites: 0,
numPendingTests: 0,
numRuntimeErrorTestSuites: 0,
numTotalTestSuites,
numTotalTests: 0,
snapshot: {
added: 0,
didUpdate: false, // is set only after the full run
failure: false,
filesAdded: 0,
// combines individual test results + results after full run
filesRemoved: 0,
filesUnmatched: 0,
filesUpdated: 0,
matched: 0,
total: 0,
unchecked: 0,
unmatched: 0,
updated: 0 },
startTime: Date.now(),
success: false,
testResults: [],
wasInterrupted: false };
};
const addResult = (
aggregatedResults,
testResult) =>
{
aggregatedResults.testResults.push(testResult);
aggregatedResults.numTotalTests +=
testResult.numPassingTests +
testResult.numFailingTests +
testResult.numPendingTests;
aggregatedResults.numFailedTests += testResult.numFailingTests;
aggregatedResults.numPassedTests += testResult.numPassingTests;
aggregatedResults.numPendingTests += testResult.numPendingTests;
if (testResult.testExecError) {
aggregatedResults.numRuntimeErrorTestSuites++;
}
if (testResult.skipped) {
aggregatedResults.numPendingTestSuites++;
} else if (testResult.numFailingTests > 0 || testResult.testExecError) {
aggregatedResults.numFailedTestSuites++;
} else {
aggregatedResults.numPassedTestSuites++;
}
// Snapshot data
if (testResult.snapshot.added) {
aggregatedResults.snapshot.filesAdded++;
}
if (testResult.snapshot.fileDeleted) {
aggregatedResults.snapshot.filesRemoved++;
}
if (testResult.snapshot.unmatched) {
aggregatedResults.snapshot.filesUnmatched++;
}
if (testResult.snapshot.updated) {
aggregatedResults.snapshot.filesUpdated++;
}
aggregatedResults.snapshot.added += testResult.snapshot.added;
aggregatedResults.snapshot.matched += testResult.snapshot.matched;
aggregatedResults.snapshot.unchecked += testResult.snapshot.unchecked;
aggregatedResults.snapshot.unmatched += testResult.snapshot.unmatched;
aggregatedResults.snapshot.updated += testResult.snapshot.updated;
aggregatedResults.snapshot.total +=
testResult.snapshot.added +
testResult.snapshot.matched +
testResult.snapshot.unmatched +
testResult.snapshot.updated;
};
const buildFailureTestResult = (
testPath,
err) =>
{
return {
console: null,
failureMessage: null,
numFailingTests: 0,
numPassingTests: 0,
numPendingTests: 0,
perfStats: {
end: 0,
start: 0 },
skipped: false,
snapshot: {
added: 0,
fileDeleted: false,
matched: 0,
unchecked: 0,
unmatched: 0,
updated: 0 },
sourceMaps: {},
testExecError: err,
testFilePath: testPath,
testResults: [] };
};
const getEstimatedTime = (timings, workers) => {
if (!timings.length) {
return 0;
}
const max = Math.max.apply(null, timings);
return timings.length <= workers ?
max :
Math.max(timings.reduce((sum, time) => sum + time) / workers, max);
};
module.exports = TestRunner;

View File

@@ -0,0 +1,116 @@
'use strict';
const fs = require('fs'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const getCacheFilePath = require('jest-haste-map').getCacheFilePath;const FAIL = 0;const SUCCESS = 1;
class TestSequencer {
constructor() {
this._cache = new Map();
}
_getCachePath(context) {const
config = context.config;
return getCacheFilePath(config.cacheDirectory, 'perf-cache-' + config.name);
}
_getCache(test) {const
context = test.context;
if (!this._cache.has(context) && context.config.cache) {
const cachePath = this._getCachePath(context);
if (fs.existsSync(cachePath)) {
try {
this._cache.set(
context,
JSON.parse(fs.readFileSync(cachePath, 'utf8')));
} catch (e) {}
}
}
let cache = this._cache.get(context);
if (!cache) {
cache = {};
this._cache.set(context, cache);
}
return cache;
}
// When running more tests than we have workers available, sort the tests
// by size - big test files usually take longer to complete, so we run
// them first in an effort to minimize worker idle time at the end of a
// long test run.
//
// After a test run we store the time it took to run a test and on
// subsequent runs we use that to run the slowest tests first, yielding the
// fastest results.
sort(tests) {
const stats = {};
const fileSize = test =>
stats[test.path] || (stats[test.path] = fs.statSync(test.path).size);
const hasFailed = (cache, test) =>
cache[test.path] && cache[test.path][0] === FAIL;
const time = (cache, test) => cache[test.path] && cache[test.path][1];
tests.forEach(test => test.duration = time(this._getCache(test), test));
return tests.sort((testA, testB) => {
const cacheA = this._getCache(testA);
const cacheB = this._getCache(testB);
const failedA = hasFailed(cacheA, testA);
const failedB = hasFailed(cacheB, testB);
const hasTimeA = testA.duration != null;
if (failedA !== failedB) {
return failedA ? -1 : 1;
} else if (hasTimeA != (testB.duration != null)) {
// Check if only one of two tests has timing information
return hasTimeA != null ? 1 : -1;
} else if (testA.duration != null && testB.duration != null) {
return testA.duration < testB.duration ? 1 : -1;
} else {
return fileSize(testA) < fileSize(testB) ? 1 : -1;
}
});
}
cacheResults(tests, results) {
const map = Object.create(null);
tests.forEach(test => map[test.path] = test);
results.testResults.forEach(testResult => {
if (testResult && map[testResult.testFilePath] && !testResult.skipped) {
const cache = this._getCache(map[testResult.testFilePath]);
const perf = testResult.perfStats;
cache[testResult.testFilePath] = [
testResult.numFailingTests ? FAIL : SUCCESS,
perf.end - perf.start || 0];
}
});
this._cache.forEach((cache, context) =>
fs.writeFileSync(this._getCachePath(context), JSON.stringify(cache)));
}}
module.exports = TestSequencer;

View File

@@ -0,0 +1,41 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require =
require('events');const EventEmitter = _require.EventEmitter;
class TestWatcher extends EventEmitter {
constructor(_ref) {let isWatchMode = _ref.isWatchMode;
super();
this.state = { interrupted: false };
this._isWatchMode = isWatchMode;
}
setState(state) {
Object.assign(this.state, state);
this.emit('change', this.state);
}
isInterrupted() {
return this.state.interrupted;
}
isWatchMode() {
return this._isWatchMode;
}}
module.exports = TestWatcher;

View File

@@ -0,0 +1,104 @@
'use strict';
// Make sure uncaught errors are logged before we exit.
process.on('uncaughtException', err => {
console.error(err.stack);
process.exit(1);
}); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require = require('jest-haste-map');const ModuleMap = _require.ModuleMap;var _require2 = require('jest-message-util');const separateMessageFromStack = _require2.separateMessageFromStack;const Runtime = require('jest-runtime');const runTest = require('./runTest');
const formatError = error => {
if (typeof error === 'string') {var _separateMessageFromS =
separateMessageFromStack(error);const message = _separateMessageFromS.message,stack = _separateMessageFromS.stack;
return {
message,
stack,
type: 'Error' };
}
return {
message: error.message,
stack: error.stack,
type: 'Error' };
};
const resolvers = Object.create(null);
const getResolver = (config, rawModuleMap) => {
// In watch mode, the raw module map with all haste modules is passed from
// the test runner to the watch command. This is because jest-haste-map's
// watch mode does not persist the haste map on disk after every file change.
// To make this fast and consistent, we pass it from the TestRunner.
if (rawModuleMap) {
return Runtime.createResolver(
config,
new ModuleMap(rawModuleMap.map, rawModuleMap.mocks));
} else {
const name = config.name;
if (!resolvers[name]) {
resolvers[name] = Runtime.createResolver(
config,
Runtime.createHasteMap(config).readModuleMap());
}
return resolvers[name];
}
};
module.exports = (_ref,
callback) =>
{let config = _ref.config,globalConfig = _ref.globalConfig,path = _ref.path,rawModuleMap = _ref.rawModuleMap;
let parentExited = false;
const disconnectCallback = () => parentExited = true;
const removeListener = () =>
process.removeListener('disconnect', disconnectCallback);
process.on('disconnect', disconnectCallback);
try {
runTest(path, globalConfig, config, getResolver(config, rawModuleMap)).then(
result => {
removeListener();
if (!parentExited) {
callback(null, result);
}
},
error => {
removeListener();
if (!parentExited) {
callback(formatError(error));
}
});
} catch (error) {
callback(formatError(error));
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,478 @@
'use strict';
const isCI = require('is-ci'); /**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const check = argv => {if (argv.runInBand && argv.hasOwnProperty('maxWorkers')) {throw new Error('Both --runInBand and --maxWorkers were specified, but these two ' + 'options do not make sense together. Which is it?');}
if (argv.onlyChanged && argv._.length > 0) {
throw new Error(
'Both --onlyChanged and a path pattern were specified, but these ' +
'two options do not make sense together. Which is it? Do you want ' +
'to run tests for changed files? Or for a specific set of files?');
}
if (argv.onlyChanged && argv.watchAll) {
throw new Error(
'Both --onlyChanged and --watchAll were specified, but these two ' +
'options do not make sense together. Try the --watch option which ' +
'reruns only tests related to changed files.');
}
if (argv.findRelatedTests && argv._.length === 0) {
throw new Error(
'The --findRelatedTests option requires file paths to be specified.\n' +
'Example usage: jest --findRelatedTests ./src/source.js ' +
'./src/index.js.');
}
return true;
};
const usage = 'Usage: $0 [--config=<pathToConfigFile>] [TestPathPattern]';
const docs = 'Documentation: https://facebook.github.io/jest/';
const options = {
automock: {
default: undefined,
description: 'Automock all files by default.',
type: 'boolean' },
bail: {
alias: 'b',
default: undefined,
description: 'Exit the test suite immediately upon the first failing test.',
type: 'boolean' },
browser: {
default: undefined,
description: 'Respect the "browser" field in package.json ' +
'when resolving modules. Some packages export different versions ' +
'based on whether they are operating in node.js or a browser.',
type: 'boolean' },
cache: {
default: undefined,
description: 'Whether to use the transform cache. Disable the cache ' +
'using --no-cache.',
type: 'boolean' },
cacheDirectory: {
description: 'The directory where Jest should store its cached ' +
' dependency information.',
type: 'string' },
ci: {
default: isCI,
description: 'Whether to run Jest in continuous integration (CI) mode. ' +
'This option is on by default in most popular CI environments. It will ' +
' prevent snapshots from being written unless explicitly requested.',
type: 'boolean' },
clearMocks: {
default: undefined,
description: 'Automatically clear mock calls and instances between every ' +
'test. Equivalent to calling jest.clearAllMocks() between each test.',
type: 'boolean' },
collectCoverage: {
default: undefined,
description: 'Alias for --coverage.',
type: 'boolean' },
collectCoverageFrom: {
description: 'relative to <rootDir> glob pattern matching the files ' +
'that coverage info needs to be collected from.',
type: 'string' },
collectCoverageOnlyFrom: {
description: 'Explicit list of paths coverage will be restricted to.',
type: 'array' },
color: {
default: undefined,
description: 'Forces test results output color highlighting (even if ' +
'stdout is not a TTY). Set to false if you would like to have no colors.',
type: 'boolean' },
colors: {
default: undefined,
description: 'Alias for `--color`.',
type: 'boolean' },
config: {
alias: 'c',
description: 'The path to a jest config file specifying how to find ' +
'and execute tests. If no rootDir is set in the config, the current ' +
'directory is assumed to be the rootDir for the project. This can also ' +
'be a JSON encoded value which Jest will use as configuration.',
type: 'string' },
coverage: {
default: undefined,
description: 'Indicates that test coverage information should be ' +
'collected and reported in the output.',
type: 'boolean' },
coverageDirectory: {
description: 'The directory where Jest should output its coverage files.',
type: 'string' },
coveragePathIgnorePatterns: {
description: 'An array of regexp pattern strings that are matched ' +
'against all file paths before executing the test. If the file path' +
'matches any of the patterns, coverage information will be skipped.',
type: 'array' },
coverageReporters: {
description: 'A list of reporter names that Jest uses when writing ' +
'coverage reports. Any istanbul reporter can be used.',
type: 'array' },
coverageThreshold: {
description: 'A JSON string with which will be used to configure ' +
'minimum threshold enforcement for coverage results',
type: 'string' },
debug: {
default: undefined,
description: 'Print debugging info about your jest config.',
type: 'boolean' },
env: {
description: 'The test environment used for all tests. This can point to ' +
'any file or node module. Examples: `jsdom`, `node` or ' +
'`path/to/my-environment.js`',
type: 'string' },
expand: {
alias: 'e',
default: undefined,
description: 'Use this flag to show full diffs instead of a patch.',
type: 'boolean' },
findRelatedTests: {
default: undefined,
description: 'Find related tests for a list of source files that were ' +
'passed in as arguments. Useful for pre-commit hook integration to run ' +
'the minimal amount of tests necessary.',
type: 'boolean' },
forceExit: {
default: undefined,
description: 'Force Jest to exit after all tests have completed running. ' +
'This is useful when resources set up by test code cannot be ' +
'adequately cleaned up.',
type: 'boolean' },
globals: {
description: 'A JSON string with map of global variables that need ' +
'to be available in all test environments.',
type: 'string' },
haste: {
description: 'A JSON string with map of variables for the haste ' +
' module system',
type: 'string' },
json: {
default: undefined,
description: 'Prints the test results in JSON. This mode will send all ' +
'other test output and user messages to stderr.',
type: 'boolean' },
lastCommit: {
default: undefined,
description: 'Will run all tests affected by file changes in the last ' +
'commit made.',
type: 'boolean' },
listTests: {
default: false,
description: 'Lists all tests Jest will run given the arguments and ' +
'exits. Most useful in a CI system together with `--findRelatedTests` ' +
'to determine the tests Jest will run based on specific files',
type: 'boolean' },
logHeapUsage: {
default: undefined,
description: 'Logs the heap usage after every test. Useful to debug ' +
'memory leaks. Use together with `--runInBand` and `--expose-gc` in ' +
'node.',
type: 'boolean' },
mapCoverage: {
default: undefined,
description: 'Maps code coverage reports against original source code ' +
'when transformers supply source maps.',
type: 'boolean' },
maxWorkers: {
alias: 'w',
description: 'Specifies the maximum number of workers the worker-pool ' +
'will spawn for running tests. This defaults to the number of the ' +
'cores available on your machine. (its usually best not to override ' +
'this default)',
type: 'number' },
moduleDirectories: {
description: 'An array of directory names to be searched recursively ' +
"up from the requiring module's location.",
type: 'array' },
moduleFileExtensions: {
description: 'An array of file extensions your modules use. If you ' +
'require modules without specifying a file extension, these are the ' +
'extensions Jest will look for. ',
type: 'array' },
moduleNameMapper: {
description: 'A JSON string with a map from regular expressions to ' +
'module names that allow to stub out resources, like images or ' +
'styles with a single module',
type: 'string' },
modulePathIgnorePatterns: {
description: 'An array of regexp pattern strings that are matched ' +
'against all module paths before those paths are to be considered ' +
'"visible" to the module loader.',
type: 'array' },
modulePaths: {
description: 'An alternative API to setting the NODE_PATH env variable, ' +
'modulePaths is an array of absolute paths to additional locations to ' +
'search when resolving modules.',
type: 'array' },
noStackTrace: {
default: undefined,
description: 'Disables stack trace in test results output',
type: 'boolean' },
notify: {
default: undefined,
description: 'Activates notifications for test results.',
type: 'boolean' },
onlyChanged: {
alias: 'o',
default: undefined,
description: 'Attempts to identify which tests to run based on which ' +
"files have changed in the current repository. Only works if you're " +
'running tests in a git repository at the moment.',
type: 'boolean' },
outputFile: {
description: 'Write test results to a file when the --json option is ' +
'also specified.',
type: 'string' },
preset: {
description: "A preset that is used as a base for Jest's configuration.",
type: 'string' },
projects: {
description: 'A list of projects that use Jest to run all tests of all ' +
'projects in a single instance of Jest.',
type: 'array' },
reporters: {
description: 'A list of custom reporters for the test suite.',
type: 'array' },
resetMocks: {
default: undefined,
description: 'Automatically reset mock state between every test. ' +
'Equivalent to calling jest.resetAllMocks() between each test.',
type: 'boolean' },
resetModules: {
default: undefined,
description: 'If enabled, the module registry for every test file will ' +
'be reset before running each individual test.',
type: 'boolean' },
resolver: {
description: 'A JSON string which allows the use of a custom resolver.',
type: 'string' },
rootDir: {
description: 'The root directory that Jest should scan for tests and ' +
'modules within.',
type: 'string' },
roots: {
description: 'A list of paths to directories that Jest should use to ' +
'search for files in.',
type: 'array' },
runInBand: {
alias: 'i',
default: undefined,
description: 'Run all tests serially in the current process (rather than ' +
'creating a worker pool of child processes that run tests). This ' +
'is sometimes useful for debugging, but such use cases are pretty ' +
'rare.',
type: 'boolean' },
setupFiles: {
description: 'The paths to modules that run some code to configure or ' +
'set up the testing environment before each test. ',
type: 'array' },
setupTestFrameworkScriptFile: {
description: 'The path to a module that runs some code to configure or ' +
'set up the testing framework before each test.',
type: 'string' },
showConfig: {
default: undefined,
description: 'Print your jest config and then exits.',
type: 'boolean' },
silent: {
default: undefined,
description: 'Prevent tests from printing messages through the console.',
type: 'boolean' },
snapshotSerializers: {
description: 'A list of paths to snapshot serializer modules Jest should ' +
'use for snapshot testing.',
type: 'array' },
testEnvironment: {
description: 'Alias for --env',
type: 'string' },
testMatch: {
description: 'The glob patterns Jest uses to detect test files.',
type: 'array' },
testNamePattern: {
alias: 't',
description: 'Run only tests with a name that matches the regex pattern.',
type: 'string' },
testPathIgnorePatterns: {
description: 'An array of regexp pattern strings that are matched ' +
'against all test paths before executing the test. If the test path ' +
'matches any of the patterns, it will be skipped.',
type: 'array' },
testPathPattern: {
description: 'A regexp pattern string that is matched against all tests ' +
'paths before executing the test.',
type: 'string' },
testRegex: {
description: 'The regexp pattern Jest uses to detect test files.',
type: 'string' },
testResultsProcessor: {
description: 'Allows the use of a custom results processor. ' +
'This processor must be a node module that exports ' +
'a function expecting as the first argument the result object',
type: 'string' },
testRunner: {
description: 'Allows to specify a custom test runner. The default is ' +
' `jasmine2`. A path to a custom test runner can be provided: ' +
'`<rootDir>/path/to/testRunner.js`.',
type: 'string' },
testURL: {
description: 'This option sets the URL for the jsdom environment.',
type: 'string' },
timers: {
description: 'Setting this value to fake allows the use of fake timers ' +
'for functions such as setTimeout.',
type: 'string' },
transform: {
description: 'A JSON string which maps from regular expressions to paths ' +
'to transformers.',
type: 'string' },
transformIgnorePatterns: {
description: 'An array of regexp pattern strings that are matched ' +
'against all source file paths before transformation.',
type: 'array' },
unmockedModulePathPatterns: {
description: 'An array of regexp pattern strings that are matched ' +
'against all modules before the module loader will automatically ' +
'return a mock for them.',
type: 'array' },
updateSnapshot: {
alias: 'u',
default: undefined,
description: 'Use this flag to re-record snapshots. ' +
'Can be used together with a test suite pattern or with ' +
'`--testNamePattern` to re-record snapshot for test matching ' +
'the pattern',
type: 'boolean' },
useStderr: {
default: undefined,
description: 'Divert all output to stderr.',
type: 'boolean' },
verbose: {
default: undefined,
description: 'Display individual test results with the test suite ' +
'hierarchy.',
type: 'boolean' },
version: {
alias: 'v',
default: undefined,
description: 'Print the version and exit',
type: 'boolean' },
watch: {
default: undefined,
description: 'Watch files for changes and rerun tests related to ' +
'changed files. If you want to re-run all tests when a file has ' +
'changed, use the `--watchAll` option.',
type: 'boolean' },
watchAll: {
default: undefined,
description: 'Watch files for changes and rerun all tests. If you want ' +
'to re-run only the tests related to the changed files, use the ' +
'`--watch` option.',
type: 'boolean' },
watchman: {
default: undefined,
description: 'Whether to use watchman for file crawling. Disable using ' +
'--no-watchman.',
type: 'boolean' } };
module.exports = {
check,
docs,
options,
usage };

View File

@@ -0,0 +1,49 @@
'use strict';
const path = require('path'); /**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const chalk = require('chalk');const fs = require('graceful-fs');function getJest(packageRoot) {const packageJSONPath = path.join(packageRoot, 'package.json');const binPath = path.join(packageRoot, 'node_modules/jest-cli');if (fs.existsSync(binPath)) {/* $FlowFixMe */
return require(binPath);
} else {
const jest = require('../jest');
// Check if Jest is specified in `package.json` but not installed.
if (fs.existsSync(packageJSONPath)) {
/* $FlowFixMe */
const packageJSON = require(packageJSONPath);
const dependencies = packageJSON.dependencies;
const devDependencies = packageJSON.devDependencies;
if (
dependencies && dependencies['jest-cli'] ||
devDependencies && devDependencies['jest-cli'])
{
process.on('exit', () =>
console.log(
chalk.red(
'Please run `npm install` to use the version of Jest intended ' +
'for this project.')));
}
}
return jest;
}
}
module.exports = getJest;

View File

@@ -0,0 +1,50 @@
'use strict'; /**
* Copyright (c) 2014, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require =
require('jest-util');const validateCLIOptions = _require.validateCLIOptions;
const yargs = require('yargs');
const args = require('./args');
const getJest = require('./getJest');
const runCLI = require('./runCLI');
function run(argv, project) {
argv = yargs(argv || process.argv.slice(2)).
usage(args.usage).
help().
alias('help', 'h').
options(args.options).
epilogue(args.docs).
check(args.check).argv;
validateCLIOptions(argv, args.options);
if (!project) {
project = process.cwd();
}
if (!argv.projects) {
argv.projects = [project];
}
const execute = argv.projects.length === 1 ? getJest(project).runCLI : runCLI;
execute(argv, argv.projects, result => {
const code = !result || result.success ? 0 : 1;
process.on('exit', () => process.exit(code));
if (argv && argv.forceExit) {
process.exit(code);
}
});
}
exports.run = run;
exports.runCLI = runCLI;

View File

@@ -0,0 +1,139 @@
'use strict';function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}
const Runtime = require('jest-runtime'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require = require('jest-util');const Console = _require.Console,clearLine = _require.clearLine;var _require2 = require('jest-util');const createDirectory = _require2.createDirectory;var _require3 = require('jest-config');const readConfig = _require3.readConfig;const chalk = require('chalk');const createContext = require('../lib/createContext');const getMaxWorkers = require('../lib/getMaxWorkers');const handleDeprecationWarnings = require('../lib/handleDeprecationWarnings');
const logDebugMessages = require('../lib/logDebugMessages');
const preRunMessage = require('../preRunMessage');
const runJest = require('../runJest');
const TestWatcher = require('../TestWatcher');
const watch = require('../watch');
const VERSION = require('../../package.json').version;
module.exports = (() => {var _ref = _asyncToGenerator(function* (
argv,
projects,
onComplete)
{
const realFs = require('fs');
const fs = require('graceful-fs');
fs.gracefulify(realFs);
const pipe = argv.json ? process.stderr : process.stdout;
if (argv.version) {
pipe.write(`v${VERSION}\n`);
onComplete && onComplete();
return;
}
const _run = (() => {var _ref2 = _asyncToGenerator(function* (globalConfig, configs) {
const hasteMapInstances = Array(configs.length);
const contexts = yield Promise.all(
configs.map((() => {var _ref4 = _asyncToGenerator(function* (_ref3, index) {let config = _ref3.config;
createDirectory(config.cacheDirectory);
const hasteMapInstance = Runtime.createHasteMap(config, {
console: new Console(pipe, pipe),
maxWorkers: getMaxWorkers(argv),
resetCache: !config.cache,
watch: globalConfig.watch,
watchman: globalConfig.watchman });
hasteMapInstances[index] = hasteMapInstance;
return createContext(config, (yield hasteMapInstance.build()));
});return function (_x6, _x7) {return _ref4.apply(this, arguments);};})()));
if (argv.watch || argv.watchAll) {
if (configs.some(function (_ref5) {let hasDeprecationWarnings = _ref5.hasDeprecationWarnings;return hasDeprecationWarnings;})) {
try {
yield handleDeprecationWarnings(pipe, process.stdin);
return watch(globalConfig, contexts, argv, pipe, hasteMapInstances);
} catch (e) {
process.exit(0);
}
}
return watch(globalConfig, contexts, argv, pipe, hasteMapInstances);
} else {
const startRun = function () {
if (!argv.listTests) {
preRunMessage.print(pipe);
}
runJest(
globalConfig,
contexts,
argv,
pipe,
new TestWatcher({ isWatchMode: false }),
startRun,
onComplete);
};
return startRun();
}
});return function _run(_x4, _x5) {return _ref2.apply(this, arguments);};})();
try {
let globalConfig;
let hasDeprecationWarnings;
let configs = [];
let config;
if (projects.length === 1) {var _readConfig =
readConfig(
argv,
projects[0]);config = _readConfig.config;globalConfig = _readConfig.globalConfig;hasDeprecationWarnings = _readConfig.hasDeprecationWarnings;
configs = [{ config, globalConfig, hasDeprecationWarnings }];
if (globalConfig.projects && globalConfig.projects.length) {
projects = globalConfig.projects;
}
}
if (projects.length > 1) {
configs = projects.map(function (root) {return readConfig(argv, root);});
// If no config was passed initially, use the one from the first project
if (!globalConfig && !config) {
globalConfig = configs[0].globalConfig;
config = configs[0].config;
}
}
if (!config || !globalConfig || !configs.length) {
throw new Error('jest: No configuration found for any project.');
}
if (argv.debug || argv.showConfig) {
logDebugMessages(globalConfig, config, pipe);
}
if (argv.showConfig) {
process.exit(0);
}
yield _run(globalConfig, configs);
} catch (error) {
clearLine(process.stderr);
clearLine(process.stdout);
console.error(chalk.red(error.stack));
process.exit(1);
}
});return function (_x, _x2, _x3) {return _ref.apply(this, arguments);};})();

View File

@@ -0,0 +1,42 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const isWindows = process.platform === 'win32';
const CLEAR = isWindows ? '\x1Bc' : '\x1B[2J\x1B[3J\x1B[H';
const KEYS = {
A: '61',
ARROW_DOWN: '1b5b42',
ARROW_LEFT: '1b5b44',
ARROW_RIGHT: '1b5b43',
ARROW_UP: '1b5b41',
BACKSPACE: isWindows ? '08' : '7f',
C: '63',
CONTROL_C: '03',
CONTROL_D: '04',
ENTER: '0d',
ESCAPE: '1b',
O: '6f',
P: '70',
Q: '71',
QUESTION_MARK: '3f',
T: '74',
U: '75',
W: '77' };
const ICONS = {
failed: isWindows ? '\u00D7' : '\u2715',
pending: '\u25CB',
success: isWindows ? '\u221A' : '\u2713' };
module.exports = { CLEAR, ICONS, KEYS };

View File

@@ -0,0 +1,29 @@
// Copyright 2004-present Facebook. All Rights Reserved.
// Instrumentation Header
{
var <%= instrumented.names.statement %>;
var <%= instrumented.names.expression %>;
var <%= instrumented.names.block %>;
var nodes = <%= coverageStorageVar %>.nodes = {};
var blocks = <%= coverageStorageVar %>.blocks = {};
<%= instrumented.names.statement %> = function(i) {
var node = nodes[i] = (nodes[i] || {index: i, count:0})
node.count++;
};
<%= instrumented.names.expression %> = function(i) {
var node = nodes[i] = (nodes[i] || {index: i, count:0})
node.count++;
};
<%= instrumented.names.block %> = function(i) {
var block = blocks[i] = (blocks[i] || {index: i, count:0})
block.count++;
};
};
////////////////////////
// Instrumented Code
<%= source %>

View File

@@ -0,0 +1,47 @@
'use strict';
const IstanbulInstrument = require('istanbul-lib-instrument'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require = require('jest-runtime');const ScriptTransformer = _require.ScriptTransformer,shouldInstrument = _require.shouldInstrument;module.exports = function (source, filename, globalConfig, config)
{
const coverageOptions = {
collectCoverage: globalConfig.collectCoverage,
collectCoverageFrom: globalConfig.collectCoverageFrom,
collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom,
mapCoverage: globalConfig.mapCoverage };
if (shouldInstrument(filename, coverageOptions, config)) {
// Transform file without instrumentation first, to make sure produced
// source code is ES6 (no flowtypes etc.) and can be instrumented
const transformResult = new ScriptTransformer(config).transformSource(
filename,
source,
false,
globalConfig.mapCoverage);
const instrumenter = IstanbulInstrument.createInstrumenter();
instrumenter.instrumentSync(transformResult.code, filename);
return {
coverage: instrumenter.fileCoverage,
sourceMapPath: transformResult.sourceMapPath };
} else {
return null;
}
};

View File

@@ -0,0 +1,25 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const VERSION = require('../package.json').version;
const SearchSource = require('./SearchSource');
const TestRunner = require('./TestRunner');
const TestWatcher = require('./TestWatcher');var _require =
require('./cli');const run = _require.run,runCLI = _require.runCLI;
module.exports = {
SearchSource,
TestRunner,
TestWatcher,
getVersion: () => VERSION,
run,
runCLI };

View File

@@ -0,0 +1,60 @@
'use strict';var _require =
require('console');const Console = _require.Console; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require2 = require('util');const format = _require2.format;const callsites = require('callsites');class BufferedConsole extends Console {constructor() {
const buffer = [];
super({ write: message => BufferedConsole.write(buffer, 'log', message) });
this._buffer = buffer;
}
static write(
buffer,
type,
message,
level)
{
const call = callsites()[level != null ? level : 2];
const origin = call.getFileName() + ':' + call.getLineNumber();
buffer.push({ message, origin, type });
return buffer;
}
log() {
BufferedConsole.write(this._buffer, 'log', format.apply(null, arguments));
}
info() {
BufferedConsole.write(this._buffer, 'info', format.apply(null, arguments));
}
warn() {
BufferedConsole.write(this._buffer, 'warn', format.apply(null, arguments));
}
error() {
BufferedConsole.write(this._buffer, 'error', format.apply(null, arguments));
}
getBuffer() {
return this._buffer;
}}
module.exports = BufferedConsole;

View File

@@ -0,0 +1,114 @@
'use strict';var _require =
require('../constants');const KEYS = _require.KEYS; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/class Prompt {
constructor() {
this._onResize = this._onResize.bind(this);
}
_onResize() {
this._onChange(this._value);
}
enter(
onChange,
onSuccess,
onCancel)
{
this._entering = true;
this._value = '';
this._onSuccess = onSuccess;
this._onCancel = onCancel;
this._typeaheadSelection = null;
this._typeaheadOffset = -1;
this._typeaheadLength = 0;
this._onChange = () =>
onChange(this._value, {
max: 10,
offset: this._typeaheadOffset });
this._onChange();
process.stdout.on('resize', this._onResize);
}
setTypeaheadLength(length) {
this._typeaheadLength = length;
}
setTypheadheadSelection(selected) {
this._typeaheadSelection = selected;
}
put(key) {
switch (key) {
case KEYS.ENTER:
this._entering = false;
this._onSuccess(this._typeaheadSelection || this._value);
this.abort();
break;
case KEYS.ESCAPE:
this._entering = false;
this._onCancel(this._value);
this.abort();
break;
case KEYS.ARROW_DOWN:
this._typeaheadOffset = Math.min(
this._typeaheadOffset + 1,
this._typeaheadLength - 1);
this._onChange();
break;
case KEYS.ARROW_UP:
this._typeaheadOffset = Math.max(this._typeaheadOffset - 1, -1);
this._onChange();
break;
case KEYS.ARROW_LEFT:
case KEYS.ARROW_RIGHT:
break;
default:
const char = new Buffer(key, 'hex').toString();
this._value = key === KEYS.BACKSPACE ?
this._value.slice(0, -1) :
this._value + char;
this._typeaheadOffset = -1;
this._typeaheadSelection = null;
this._onChange();
break;}
}
abort() {
this._entering = false;
this._value = '';
process.stdout.removeListener('resize', this._onResize);
}
isEntering() {
return this._entering;
}}
module.exports = Prompt;

View File

@@ -0,0 +1,16 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk');
module.exports = (str, start, end) =>
chalk.dim(str.slice(0, start)) +
chalk.reset(str.slice(start, end)) +
chalk.dim(str.slice(end));

View File

@@ -0,0 +1,24 @@
'use strict';
const Runtime = require('jest-runtime'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/module.exports = (config, _ref) => {let hasteFS = _ref.hasteFS,moduleMap = _ref.moduleMap;return { config, hasteFS, moduleMap,
resolver: Runtime.createResolver(config, moduleMap) };};

View File

@@ -0,0 +1,61 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk');
const colorize = require('./colorize');
const DOTS = '...';
const ENTER = '⏎';
module.exports = (testName, pattern, width) => {
const inlineTestName = testName.replace(/(\r\n|\n|\r)/gm, ENTER);
let regexp;
try {
regexp = new RegExp(pattern, 'i');
} catch (e) {
return chalk.dim(inlineTestName);
}
const match = inlineTestName.match(regexp);
if (!match) {
return chalk.dim(inlineTestName);
}
// $FlowFixMe
const startPatternIndex = Math.max(match.index, 0);
const endPatternIndex = startPatternIndex + match[0].length;
if (inlineTestName.length <= width) {
return colorize(inlineTestName, startPatternIndex, endPatternIndex);
}
const slicedTestName = inlineTestName.slice(0, width - DOTS.length);
if (startPatternIndex < slicedTestName.length) {
if (endPatternIndex > slicedTestName.length) {
return colorize(
slicedTestName + DOTS,
startPatternIndex,
slicedTestName.length + DOTS.length);
} else {
return colorize(
slicedTestName + DOTS,
Math.min(startPatternIndex, slicedTestName.length),
endPatternIndex);
}
}
return `${chalk.dim(slicedTestName)}${chalk.reset(DOTS)}`;
};

View File

@@ -0,0 +1,26 @@
'use strict';
const os = require('os'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const getMaxWorkers = argv => {if (argv.runInBand) {return 1;} else if (argv.maxWorkers) {return parseInt(argv.maxWorkers, 10);} else {const cpus = os.cpus().length;
return Math.max(argv.watch ? Math.floor(cpus / 2) : cpus - 1, 1);
}
};
module.exports = getMaxWorkers;

View File

@@ -0,0 +1,74 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require =
require('jest-util');const clearLine = _require.clearLine;
const chalk = require('chalk');
const validatePattern = require('./validatePattern');
const DEFAULT_PATTERN_INFO = {
input: '',
shouldTreatInputAsPattern: false,
testPathPattern: '' };
const showTestPathPatternError = testPathPattern => {
clearLine(process.stdout);
console.log(
chalk.red(
` Invalid testPattern ${testPathPattern} supplied. ` +
`Running all tests instead.`));
};
module.exports = argv => {
if (argv.onlyChanged) {
return {
input: '',
lastCommit: argv.lastCommit,
onlyChanged: true,
watch: argv.watch };
}
if (argv.testPathPattern) {
if (validatePattern(argv.testPathPattern)) {
return {
input: argv.testPathPattern,
shouldTreatInputAsPattern: true,
testPathPattern: argv.testPathPattern };
} else {
showTestPathPatternError(argv.testPathPattern);
}
}
if (argv._ && argv._.length) {
const testPathPattern = argv._.join('|');
if (validatePattern(testPathPattern)) {
return {
findRelatedTests: argv.findRelatedTests,
input: argv._.join(' '),
paths: argv._,
shouldTreatInputAsPattern: false,
testPathPattern };
} else {
showTestPathPatternError(testPathPattern);
}
}
return DEFAULT_PATTERN_INFO;
};

View File

@@ -0,0 +1,45 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk');var _require =
require('../constants');const KEYS = _require.KEYS;
module.exports = function (
pipe)
{let stdin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : process.stdin;
return new Promise((resolve, reject) => {
if (typeof stdin.setRawMode === 'function') {
const messages = [
chalk.red('There are deprecation warnings.\n'),
chalk.dim(' \u203A Press ') + 'Enter' + chalk.dim(' to continue.'),
chalk.dim(' \u203A Press ') + 'Esc' + chalk.dim(' to exit.')];
pipe.write(messages.join('\n'));
// $FlowFixMe
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('hex');
stdin.on('data', key => {
if (key === KEYS.ENTER) {
resolve();
} else if (
[KEYS.ESCAPE, KEYS.CONTROL_C, KEYS.CONTROL_D].indexOf(key) !== -1)
{
reject();
}
});
} else {
resolve();
}
});
};

View File

@@ -0,0 +1,59 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const path = require('path');
const chalk = require('chalk');
const colorize = require('./colorize');
const trim = '...';
const relativePathHead = './';
const highlight = (
rawPath,
filePath,
pattern,
rootDir) =>
{
let regexp;
try {
regexp = new RegExp(pattern, 'i');
} catch (e) {
return chalk.dim(filePath);
}
rawPath = chalk.stripColor(rawPath);
filePath = chalk.stripColor(filePath);
const match = rawPath.match(regexp);
if (!match) {
return chalk.dim(filePath);
}
let offset;
let trimLength;
if (filePath.startsWith(trim)) {
offset = rawPath.length - filePath.length;
trimLength = trim.length;
} else if (filePath.startsWith(relativePathHead)) {
offset = rawPath.length - filePath.length;
trimLength = relativePathHead.length;
} else {
offset = rootDir.length + path.sep.length;
trimLength = 0;
}
const start = match.index - offset;
const end = start + match[0].length;
return colorize(filePath, Math.max(start, 0), Math.max(end, trimLength));
};
module.exports = highlight;

View File

@@ -0,0 +1,31 @@
'use strict';
const path = require('path'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const SNAPSHOT_EXTENSION = 'snap';function isValidPath(globalConfig, config, filePath) {
const coverageDirectory =
globalConfig.coverageDirectory || path.resolve(config.rootDir, 'coverage');
return (
!filePath.includes(coverageDirectory) &&
!filePath.endsWith(`.${SNAPSHOT_EXTENSION}`));
}
module.exports = isValidPath;

View File

@@ -0,0 +1,32 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const VERSION = require('../../package.json').version;
const logDebugMessages = (
globalConfig,
config,
pipe) =>
{
/* $FlowFixMe */
const testFramework = require(config.testRunner);
const output = {
config,
framework: testFramework.name,
globalConfig,
version: VERSION };
pipe.write(JSON.stringify(output, null, ' ') + '\n');
};
module.exports = logDebugMessages;

View File

@@ -0,0 +1,103 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
'use strict';
const chalk = require('chalk');
const ansiEscapes = require('ansi-escapes');
const stringLength = require('string-length');
const Prompt = require('./Prompt');
const pluralize = (count, text) =>
count === 1 ? text : text + 's';
const printPatternMatches = function (
count,
entity,
pipe)
{let extraText = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
const pluralized = pluralize(count, entity);
const result = count ?
`\n\n Pattern matches ${count} ${pluralized}` :
`\n\n Pattern matches no ${pluralized}`;
pipe.write(result + extraText);
};
const printPatternCaret = (
pattern,
pipe) =>
{
const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`;
pipe.write(ansiEscapes.eraseDown);
pipe.write(inputText);
pipe.write(ansiEscapes.cursorSavePosition);
};
const printRestoredPatternCaret = (
pattern,
currentUsageRows,
pipe) =>
{
const inputText = `${chalk.dim(' pattern \u203A')} ${pattern}`;
pipe.write(
ansiEscapes.cursorTo(stringLength(inputText), currentUsageRows - 1));
pipe.write(ansiEscapes.cursorRestorePosition);
};
const printStartTyping = (
entity,
pipe) =>
{
pipe.write(
`\n\n ${chalk.italic.yellow(`Start typing to filter by a ${entity} regex pattern.`)}`);
};
const printMore = (
entity,
pipe,
more) =>
{
pipe.write(
`\n ${chalk.dim(`...and ${more} more ${pluralize(more, entity)}`)}`);
};
const printTypeaheadItem = (
item,
pipe) =>
pipe.write(`\n ${chalk.dim('\u203A')} ${item}`);
const formatTypeaheadSelection = (
item,
index,
activeIndex,
prompt) =>
{
if (index === activeIndex) {
prompt.setTypheadheadSelection(chalk.stripColor(item));
return chalk.black.bgYellow(chalk.stripColor(item));
}
return item;
};
module.exports = {
formatTypeaheadSelection,
printMore,
printPatternCaret,
printPatternMatches,
printRestoredPatternCaret,
printStartTyping,
printTypeaheadItem };

View File

@@ -0,0 +1,40 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
'use strict';
const scroll = (size, _ref) => {let offset = _ref.offset,max = _ref.max;
let start = 0;
let index = Math.min(offset, size);
const halfScreen = max / 2;
if (index <= halfScreen) {
start = 0;
} else {
if (size >= max) {
start = Math.min(index - halfScreen - 1, size - max);
}
index = Math.min(index - start, size);
}
return {
end: Math.min(size, start + max),
index,
start };
};
module.exports = scroll;

View File

@@ -0,0 +1,15 @@
"use strict"; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
/* $FlowFixMe */
const getTerminalWidth = () => process.stdout.columns;
module.exports = {
getTerminalWidth };

View File

@@ -0,0 +1,52 @@
'use strict';
const getTestPathPattern = require('./getTestPathPattern'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/module.exports = (argv, mode, options) => {
if (mode === 'watch') {
argv.watch = true;
argv.watchAll = false;
} else if (mode === 'watchAll') {
argv.watch = false;
argv.watchAll = true;
}
if (options.testPathPattern) {
argv.testPathPattern = options.testPathPattern;
} else if (options.testPathPattern === '') {
delete argv.testPathPattern;
delete argv._;
}
if (options.testNamePattern) {
argv.testNamePattern = options.testNamePattern;
} else if (options.testNamePattern === '') {
delete argv.testNamePattern;
}
argv.onlyChanged = false;
argv.onlyChanged =
getTestPathPattern(argv).input === '' &&
!argv.watchAll &&
!argv.testNamePattern;
if (options.noSCM) {
argv.noSCM = true;
}
};

View File

@@ -0,0 +1,24 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const validatePattern = pattern => {
if (pattern) {
try {
// eslint-disable-next-line no-new
new RegExp(pattern, 'i');
} catch (e) {
return false;
}
}
return true;
};
module.exports = validatePattern;

View File

@@ -0,0 +1,29 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require =
require('jest-util');const clearLine = _require.clearLine;
const chalk = require('chalk');
const isCI = require('is-ci');
const print = stream => {
if (process.stdout.isTTY && !isCI) {
stream.write(chalk.bold.dim('Determining test suites to run...'));
}
};
const remove = stream => {
if (stream.isTTY && !isCI) {
clearLine(stream);
}
};
module.exports = {
print,
remove };

View File

@@ -0,0 +1,49 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const preRunMessage = require('../preRunMessage');
class BaseReporter {
log(message) {
process.stderr.write(message + '\n');
}
onRunStart(results, options) {
preRunMessage.remove(process.stderr);
}
onTestResult(test, testResult, results) {}
onTestStart(test) {}
onRunComplete(
contexts,
aggregatedResults)
{}
_setError(error) {
this._error = error;
}
// Return an error that occurred during reporting. This error will
// define whether the test run was successful or failed.
getLastError() {
return this._error;
}}
module.exports = BaseReporter;

View File

@@ -0,0 +1,252 @@
'use strict';function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};}var _require =
require('jest-util');const clearLine = _require.clearLine; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require2 = require('istanbul-api');const createReporter = _require2.createReporter;const chalk = require('chalk');const isCI = require('is-ci');const istanbulCoverage = require('istanbul-lib-coverage');const libSourceMaps = require('istanbul-lib-source-maps');const pify = require('pify');const workerFarm = require('worker-farm');
const BaseReporter = require('./BaseReporter');
const FAIL_COLOR = chalk.bold.red;
const RUNNING_TEST_COLOR = chalk.bold.dim;
const isInteractive = process.stdout.isTTY && !isCI;
class CoverageReporter extends BaseReporter {
constructor(globalConfig, options) {
super(globalConfig);
this._coverageMap = istanbulCoverage.createCoverageMap({});
this._globalConfig = globalConfig;
this._sourceMapStore = libSourceMaps.createSourceMapStore();
this._maxWorkers = options.maxWorkers;
}
onTestResult(
test,
testResult,
aggregatedResults)
{
if (testResult.coverage) {
this._coverageMap.merge(testResult.coverage);
// Remove coverage data to free up some memory.
delete testResult.coverage;
Object.keys(testResult.sourceMaps).forEach(sourcePath => {
this._sourceMapStore.registerURL(
sourcePath,
testResult.sourceMaps[sourcePath]);
});
}
}
onRunComplete(
contexts,
aggregatedResults)
{var _this = this;return _asyncToGenerator(function* () {
yield _this._addUntestedFiles(_this._globalConfig, contexts);
let map = _this._coverageMap;
let sourceFinder;
if (_this._globalConfig.mapCoverage) {var _sourceMapStore$trans =
_this._sourceMapStore.transformCoverage(map);map = _sourceMapStore$trans.map;sourceFinder = _sourceMapStore$trans.sourceFinder;
}
const reporter = createReporter();
try {
if (_this._globalConfig.coverageDirectory) {
reporter.dir = _this._globalConfig.coverageDirectory;
}
let coverageReporters = _this._globalConfig.coverageReporters || [];
if (
!_this._globalConfig.useStderr &&
coverageReporters.length &&
coverageReporters.indexOf('text') === -1)
{
coverageReporters = coverageReporters.concat(['text-summary']);
}
reporter.addAll(coverageReporters);
reporter.write(map, sourceFinder && { sourceFinder });
aggregatedResults.coverageMap = map;
} catch (e) {
console.error(
chalk.red(`
Failed to write coverage reports:
ERROR: ${e.toString()}
STACK: ${e.stack}
`));
}
_this._checkThreshold(_this._globalConfig, map);})();
}
_addUntestedFiles(globalConfig, contexts) {
const files = [];
contexts.forEach(context => {
const config = context.config;
if (
globalConfig.collectCoverageFrom &&
globalConfig.collectCoverageFrom.length)
{
context.hasteFS.
matchFilesWithGlob(globalConfig.collectCoverageFrom, config.rootDir).
forEach(filePath =>
files.push({
config,
path: filePath }));
}
});
if (!files.length) {
return Promise.resolve();
}
if (isInteractive) {
process.stderr.write(
RUNNING_TEST_COLOR('Running coverage on untested files...'));
}
let worker;
let farm;
if (this._maxWorkers <= 1) {
worker = pify(require('./CoverageWorker'));
} else {
farm = workerFarm(
{
autoStart: true,
maxConcurrentCallsPerWorker: 1,
maxConcurrentWorkers: this._maxWorkers,
maxRetries: 2 },
require.resolve('./CoverageWorker'));
worker = pify(farm);
}
const instrumentation = [];
files.forEach(fileObj => {
const filename = fileObj.path;
const config = fileObj.config;
if (!this._coverageMap.data[filename]) {
const promise = worker({
config,
globalConfig,
path: filename }).
then(result => {
if (result) {
this._coverageMap.addFileCoverage(result.coverage);
if (result.sourceMapPath) {
this._sourceMapStore.registerURL(
filename,
result.sourceMapPath);
}
}
}).
catch(error => {
console.error(chalk.red(error.message));
});
instrumentation.push(promise);
}
});
const cleanup = () => {
if (isInteractive) {
clearLine(process.stderr);
}
if (farm) {
workerFarm.end(farm);
}
};
return Promise.all(instrumentation).then(cleanup).catch(cleanup);
}
_checkThreshold(globalConfig, map) {
if (globalConfig.coverageThreshold) {
const results = map.getCoverageSummary().toJSON();
function check(name, thresholds, actuals) {
return [
'statements',
'branches',
'lines',
'functions'].
reduce((errors, key) => {
const actual = actuals[key].pct;
const actualUncovered = actuals[key].total - actuals[key].covered;
const threshold = thresholds[key];
if (threshold != null) {
if (threshold < 0) {
if (threshold * -1 < actualUncovered) {
errors.push(
`Jest: Uncovered count for ${key} (${actualUncovered})` +
`exceeds ${name} threshold (${-1 * threshold})`);
}
} else if (actual < threshold) {
errors.push(
`Jest: Coverage for ${key} (${actual}` +
`%) does not meet ${name} threshold (${threshold}%)`);
}
}
return errors;
}, []);
}
const errors = check(
'global',
globalConfig.coverageThreshold.global,
results);
if (errors.length > 0) {
this.log(`${FAIL_COLOR(errors.join('\n'))}`);
this._setError(new Error(errors.join('\n')));
}
}
}
// Only exposed for the internal runner. Should not be used
getCoverageMap() {
return this._coverageMap;
}}
module.exports = CoverageReporter;

View File

@@ -0,0 +1,56 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const fs = require('fs');
const generateEmptyCoverage = require('../generateEmptyCoverage');
function formatCoverageError(error, filename) {
const message = `
Failed to collect coverage from ${filename}
ERROR: ${error}
STACK: ${error.stack}
`;
return {
message,
stack: error.stack,
type: 'ERROR' };
}
// Make sure uncaught errors are logged before we exit.
process.on('uncaughtException', err => {
console.error(err.stack);
process.exit(1);
});
module.exports = (_ref,
callback) =>
{let config = _ref.config,globalConfig = _ref.globalConfig,path = _ref.path;
try {
const source = fs.readFileSync(path, 'utf8');
const result = generateEmptyCoverage(source, path, globalConfig, config);
callback(null, result);
} catch (error) {
callback(formatCoverageError(error, path), undefined);
}
};

View File

@@ -0,0 +1,174 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
/* global stream$Writable, tty$WriteStream */var _require =
require('jest-util');const clearLine = _require.clearLine;
const chalk = require('chalk');
const isCI = require('is-ci');
const BaseReporter = require('./BaseReporter');
const Status = require('./Status');
const getConsoleOutput = require('./getConsoleOutput');
const getResultHeader = require('./getResultHeader');
const TITLE_BULLET = chalk.bold('\u25cf ');
const isInteractive = process.stdin.isTTY && !isCI;
class DefaultReporter extends BaseReporter {
// ANSI clear sequence for the last printed status
constructor(globalConfig) {
super();
this._globalConfig = globalConfig;
this._clear = '';
this._out = process.stdout.write.bind(process.stdout);
this._err = process.stderr.write.bind(process.stderr);
this._status = new Status();
this._wrapStdio(process.stdout);
this._wrapStdio(process.stderr);
this._status.onChange(() => {
this._clearStatus();
this._printStatus();
});
}
_wrapStdio(stream) {
const originalWrite = stream.write;
let buffer = [];
let timeout = null;
const doFlush = () => {
const string = buffer.join('');
buffer = [];
// This is to avoid conflicts between random output and status text
this._clearStatus();
originalWrite.call(stream, string);
this._printStatus();
};
const flush = () => {
// If the process blows up no errors would be printed.
// There should be a smart way to buffer stderr, but for now
// we just won't buffer it.
if (stream === process.stderr) {
doFlush();
} else {
if (!timeout) {
timeout = setTimeout(() => {
doFlush();
timeout = null;
}, 100);
}
}
};
// $FlowFixMe
stream.write = chunk => {
buffer.push(chunk);
flush();
return true;
};
}
_clearStatus() {
if (isInteractive) {
this._out(this._clear);
}
}
_printStatus() {var _status$get =
this._status.get();const content = _status$get.content,clear = _status$get.clear;
this._clear = clear;
if (isInteractive) {
this._out(content);
}
}
onRunStart(
aggregatedResults,
options)
{
this._status.runStarted(aggregatedResults, options);
}
onTestStart(test) {
this._status.testStarted(test.path, test.context.config);
}
onRunComplete() {
this._status.runFinished();
// $FlowFixMe
process.stdout.write = this._out;
// $FlowFixMe
process.stderr.write = this._err;
clearLine(process.stderr);
}
onTestResult(
test,
testResult,
aggregatedResults)
{
this._status.testFinished(
test.context.config,
testResult,
aggregatedResults);
this._printTestFileSummary(
testResult.testFilePath,
test.context.config,
testResult);
}
_printTestFileSummary(
testPath,
config,
result)
{
if (!result.skipped) {
this.log(getResultHeader(result, config));
const consoleBuffer = result.console;
if (consoleBuffer && consoleBuffer.length) {
this.log(
' ' +
TITLE_BULLET +
'Console\n\n' +
getConsoleOutput(
config.rootDir,
!!this._globalConfig.verbose,
consoleBuffer));
}
if (result.failureMessage) {
this.log(result.failureMessage);
}
}
}}
module.exports = DefaultReporter;

View File

@@ -0,0 +1,83 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const path = require('path');
const util = require('util');
const notifier = require('node-notifier');
const BaseReporter = require('./BaseReporter');
const isDarwin = process.platform === 'darwin';
const icon = path.resolve(__dirname, '../assets/jest_logo.png');
class NotifyReporter extends BaseReporter {
constructor(startRun) {
super();
this._startRun = startRun;
}
onRunComplete(contexts, result) {
const success =
result.numFailedTests === 0 && result.numRuntimeErrorTestSuites === 0;
if (success) {
const title = util.format('%d%% Passed', 100);
const message = util.format(
(isDarwin ? '\u2705 ' : '') + '%d tests passed',
result.numPassedTests);
notifier.notify({ icon, message, title });
} else {
const failed = result.numFailedTests / result.numTotalTests;
const title = util.format(
'%d%% Failed',
Math.ceil(Number.isNaN(failed) ? 0 : failed * 100));
const message = util.format(
(isDarwin ? '\u26D4\uFE0F ' : '') + '%d of %d tests failed',
result.numFailedTests,
result.numTotalTests);
const restartAnswer = 'Run again';
const quitAnswer = 'Exit tests';
notifier.notify(
{
actions: [restartAnswer, quitAnswer],
closeLabel: 'Close',
icon,
message,
title },
(err, _, metadata) => {
if (err || !metadata) {
return;
}
if (metadata.activationValue === quitAnswer) {
process.exit(0);
return;
}
if (metadata.activationValue === restartAnswer) {
this._startRun();
}
});
}
}}
module.exports = NotifyReporter;

View File

@@ -0,0 +1,198 @@
'use strict';
const chalk = require('chalk'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require = require('./utils');const getSummary = _require.getSummary,trimAndFormatPath = _require.trimAndFormatPath,wrapAnsiString = _require.wrapAnsiString;const RUNNING_TEXT = ' RUNS ';const RUNNING = chalk.reset.inverse.yellow.bold(RUNNING_TEXT) + ' '; /**
* This class is a perf optimization for sorting the list of currently
* running tests. It tries to keep tests in the same positions without
* shifting the whole list.
*/class CurrentTestList {
constructor() {
this._array = [];
}
add(testPath, config) {
const index = this._array.indexOf(null);
const record = { config, testPath };
if (index !== -1) {
this._array[index] = record;
} else {
this._array.push(record);
}
}
delete(testPath) {
const record = this._array.find(
record => record && record.testPath === testPath);
this._array[this._array.indexOf(record || null)] = null;
}
get() {
return this._array;
}}
/**
* A class that generates the CLI status of currently running tests
* and also provides an ANSI escape sequence to remove status lines
* from the terminal.
*/
class Status {
constructor() {
this._cache = null;
this._currentTests = new CurrentTestList();
this._done = false;
this._emitScheduled = false;
this._estimatedTime = 0;
this._height = 0;
this._showStatus = false;
}
onChange(callback) {
this._callback = callback;
}
runStarted(
aggregatedResults,
options)
{
this._estimatedTime = options && options.estimatedTime || 0;
this._showStatus = options && options.showStatus;
this._interval = setInterval(() => this._tick(), 1000);
this._aggregatedResults = aggregatedResults;
this._debouncedEmit();
}
runFinished() {
this._done = true;
clearInterval(this._interval);
this._emit();
}
testStarted(testPath, config) {
this._currentTests.add(testPath, config);
if (!this._showStatus) {
this._emit();
} else {
this._debouncedEmit();
}
}
testFinished(
config,
testResult,
aggregatedResults)
{const
testFilePath = testResult.testFilePath;
this._aggregatedResults = aggregatedResults;
this._currentTests.delete(testFilePath);
this._debouncedEmit();
}
get() {
if (this._cache) {
return this._cache;
}
if (this._done) {
return { clear: '', content: '' };
}
// $FlowFixMe
const width = process.stdout.columns;
let content = '\n';
this._currentTests.get().forEach(record => {
if (record) {const
config = record.config,testPath = record.testPath;
content +=
wrapAnsiString(
RUNNING +
trimAndFormatPath(
RUNNING_TEXT.length + 1,
config,
testPath,
width),
width) +
'\n';
}
});
if (this._showStatus && this._aggregatedResults) {
content +=
'\n' +
getSummary(this._aggregatedResults, {
estimatedTime: this._estimatedTime,
roundTime: true,
width });
}
let height = 0;
for (let i = 0; i < content.length; i++) {
if (content[i] === '\n') {
height++;
}
}
const clear = '\r\x1B[K\r\x1B[1A'.repeat(height);
return this._cache = { clear, content };
}
_emit() {
this._cache = null;
this._lastUpdated = Date.now();
this._callback();
}
_debouncedEmit() {
if (!this._emitScheduled) {
// Perf optimization to avoid two separate renders When
// one test finishes and another test starts executing.
this._emitScheduled = true;
setTimeout(() => {
this._emit();
this._emitScheduled = false;
}, 100);
}
}
_tick() {
this._debouncedEmit();
}}
module.exports = Status;

View File

@@ -0,0 +1,281 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk');
const BaseReporter = require('./BaseReporter');var _require =
require('./utils');const getSummary = _require.getSummary,pluralize = _require.pluralize;
const getResultHeader = require('./getResultHeader');
const ARROW = ' \u203A ';
const FAIL_COLOR = chalk.bold.red;
const SNAPSHOT_ADDED = chalk.bold.green;
const SNAPSHOT_NOTE = chalk.dim;
const SNAPSHOT_REMOVED = chalk.bold.red;
const SNAPSHOT_SUMMARY = chalk.bold;
const SNAPSHOT_UPDATED = chalk.bold.green;
const TEST_SUMMARY_THRESHOLD = 20;
const NPM_EVENTS = new Set([
'prepublish',
'publish',
'postpublish',
'preinstall',
'install',
'postinstall',
'preuninstall',
'uninstall',
'postuninstall',
'preversion',
'version',
'postversion',
'pretest',
'test',
'posttest',
'prestop',
'stop',
'poststop',
'prestart',
'start',
'poststart',
'prerestart',
'restart',
'postrestart']);
class SummaryReporter extends BaseReporter {
constructor(globalConfig, options) {
super(globalConfig);
this._globalConfig = globalConfig;
this._estimatedTime = 0;
this._options = options;
}
// If we write more than one character at a time it is possible that
// Node.js exits in the middle of printing the result. This was first observed
// in Node.js 0.10 and still persists in Node.js 6.7+.
// Let's print the test failure summary character by character which is safer
// when hundreds of tests are failing.
_write(string) {
for (let i = 0; i < string.length; i++) {
process.stderr.write(string.charAt(i));
}
}
onRunStart(
aggregatedResults,
options)
{
super.onRunStart(aggregatedResults, options);
this._estimatedTime = options.estimatedTime;
}
onRunComplete(contexts, aggregatedResults) {const
numTotalTestSuites = aggregatedResults.numTotalTestSuites,testResults = aggregatedResults.testResults,wasInterrupted = aggregatedResults.wasInterrupted;
if (numTotalTestSuites) {
const lastResult = testResults[testResults.length - 1];
// Print a newline if the last test did not fail to line up newlines
// similar to when an error would have been thrown in the test.
if (
!this._globalConfig.verbose &&
lastResult &&
!lastResult.numFailingTests &&
!lastResult.testExecError)
{
this.log('');
}
this._printSummary(aggregatedResults, this._globalConfig);
this._printSnapshotSummary(
aggregatedResults.snapshot,
this._globalConfig);
if (numTotalTestSuites) {
const testSummary = wasInterrupted ?
chalk.bold.red('Test run was interrupted.') :
this._getTestSummary(
contexts,
this._options.pattern,
this._options.testNamePattern,
this._options.testPathPattern);
this.log(
getSummary(aggregatedResults, {
estimatedTime: this._estimatedTime }) +
'\n' +
testSummary);
}
}
}
_printSnapshotSummary(
snapshots,
globalConfig)
{
if (
snapshots.added ||
snapshots.filesRemoved ||
snapshots.unchecked ||
snapshots.unmatched ||
snapshots.updated)
{
let updateCommand;
const event = process.env.npm_lifecycle_event;
const prefix = NPM_EVENTS.has(event) ? '' : 'run ';
const client = typeof process.env.npm_config_user_agent === 'string' &&
process.env.npm_config_user_agent.match('yarn') !== null ?
'yarn' :
'npm';
if (globalConfig.watch) {
updateCommand = 'press `u`';
} else if (event) {
updateCommand = `run with \`${client + ' ' + prefix + event} -- -u\``;
} else {
updateCommand = 're-run with `-u`';
}
this.log(SNAPSHOT_SUMMARY('Snapshot Summary'));
if (snapshots.added) {
this.log(
SNAPSHOT_ADDED(ARROW + pluralize('snapshot', snapshots.added)) +
` written in ${pluralize('test suite', snapshots.filesAdded)}.`);
}
if (snapshots.unmatched) {
this.log(
FAIL_COLOR(ARROW + pluralize('snapshot test', snapshots.unmatched)) +
` failed in ` +
`${pluralize('test suite', snapshots.filesUnmatched)}. ` +
SNAPSHOT_NOTE(
'Inspect your code changes or ' +
updateCommand +
' to update them.'));
}
if (snapshots.updated) {
this.log(
SNAPSHOT_UPDATED(ARROW + pluralize('snapshot', snapshots.updated)) +
` updated in ${pluralize('test suite', snapshots.filesUpdated)}.`);
}
if (snapshots.filesRemoved) {
this.log(
SNAPSHOT_REMOVED(
ARROW + pluralize('obsolete snapshot file', snapshots.filesRemoved)) + (
snapshots.didUpdate ?
' removed.' :
' found, ' +
updateCommand +
' to remove ' + (
snapshots.filesRemoved === 1 ? 'it' : 'them.') +
'.'));
}
if (snapshots.unchecked) {
this.log(
FAIL_COLOR(
ARROW + pluralize('obsolete snapshot', snapshots.unchecked)) + (
snapshots.didUpdate ?
' removed.' :
' found, ' +
updateCommand +
' to remove ' + (
snapshots.filesRemoved === 1 ? 'it' : 'them') +
'.'));
}
this.log(''); // print empty line
}
}
_printSummary(
aggregatedResults,
globalConfig)
{
// If there were any failing tests and there was a large number of tests
// executed, re-print the failing results at the end of execution output.
const failedTests = aggregatedResults.numFailedTests;
const runtimeErrors = aggregatedResults.numRuntimeErrorTestSuites;
if (
failedTests + runtimeErrors > 0 &&
aggregatedResults.numTotalTestSuites > TEST_SUMMARY_THRESHOLD)
{
this.log(chalk.bold('Summary of all failing tests'));
aggregatedResults.testResults.forEach(testResult => {const
failureMessage = testResult.failureMessage;
if (failureMessage) {
this._write(
getResultHeader(testResult, globalConfig) +
'\n' +
failureMessage +
'\n');
}
});
this.log(''); // print empty line
}
}
_getTestSummary(
contexts,
pattern,
testNamePattern,
testPathPattern)
{
const testInfo = pattern.onlyChanged ?
chalk.dim(' related to changed files') :
pattern.input !== '' ? chalk.dim(' matching ') + testPathPattern : '';
const nameInfo = testNamePattern ?
chalk.dim(' with tests matching ') + `"${testNamePattern}"` :
'';
const contextInfo = contexts.size > 1 ?
chalk.dim(' in ') + contexts.size + chalk.dim(' projects') :
'';
return (
chalk.dim('Ran all test suites') +
testInfo +
nameInfo +
contextInfo +
chalk.dim('.'));
}}
module.exports = SummaryReporter;

View File

@@ -0,0 +1,132 @@
'use strict';
const chalk = require('chalk'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/var _require = require('../constants');const ICONS = _require.ICONS;const DefaultReporter = require('./DefaultReporter');class VerboseReporter extends DefaultReporter {constructor(globalConfig) {super(globalConfig);
this._globalConfig = globalConfig;
}
static filterTestResults(testResults) {
return testResults.filter((_ref) => {let status = _ref.status;return status !== 'pending';});
}
static groupTestsBySuites(testResults) {
const root = { suites: [], tests: [], title: '' };
testResults.forEach(testResult => {
let targetSuite = root;
// Find the target suite for this test,
// creating nested suites as necessary.
for (const title of testResult.ancestorTitles) {
let matchingSuite = targetSuite.suites.find(s => s.title === title);
if (!matchingSuite) {
matchingSuite = { suites: [], tests: [], title };
targetSuite.suites.push(matchingSuite);
}
targetSuite = matchingSuite;
}
targetSuite.tests.push(testResult);
});
return root;
}
onTestResult(
test,
result,
aggregatedResults)
{
super.onTestResult(test, result, aggregatedResults);
if (!result.testExecError && !result.skipped) {
this._logTestResults(result.testResults);
}
}
_logTestResults(testResults) {
this._logSuite(VerboseReporter.groupTestsBySuites(testResults), 0);
this._logLine();
}
_logSuite(suite, indentLevel) {
if (suite.title) {
this._logLine(suite.title, indentLevel);
}
this._logTests(suite.tests, indentLevel + 1);
suite.suites.forEach(suite => this._logSuite(suite, indentLevel + 1));
}
_getIcon(status) {
if (status === 'failed') {
return chalk.red(ICONS.failed);
} else if (status === 'pending') {
return chalk.yellow(ICONS.pending);
} else {
return chalk.green(ICONS.success);
}
}
_logTest(test, indentLevel) {
const status = this._getIcon(test.status);
const time = test.duration ? ` (${test.duration.toFixed(0)}ms)` : '';
this._logLine(status + ' ' + chalk.dim(test.title + time), indentLevel);
}
_logTests(tests, indentLevel) {
if (this._globalConfig.expand) {
tests.forEach(test => this._logTest(test, indentLevel));
} else {
const skippedCount = tests.reduce((result, test) => {
if (test.status === 'pending') {
result += 1;
} else {
this._logTest(test, indentLevel);
}
return result;
}, 0);
if (skippedCount > 0) {
this._logSkippedTests(skippedCount, indentLevel);
}
}
}
_logSkippedTests(count, indentLevel) {
const icon = this._getIcon('pending');
const text = chalk.dim(`skipped ${count} test${count === 1 ? '' : 's'}`);
this._logLine(`${icon} ${text}`, indentLevel);
}
_logLine(str, indentLevel) {
const indentation = ' '.repeat(indentLevel || 0);
this.log(indentation + (str || ''));
}}
module.exports = VerboseReporter;

View File

@@ -0,0 +1,44 @@
'use strict';
const path = require('path'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const chalk = require('chalk');module.exports = (root, verbose, buffer) => {const TITLE_INDENT = verbose ? ' ' : ' ';const CONSOLE_INDENT = TITLE_INDENT + ' ';return buffer.reduce((output, _ref) => {let type = _ref.type,message = _ref.message,origin = _ref.origin;origin = path.relative(root, origin);
message = message.split(/\n/).map(line => CONSOLE_INDENT + line).join('\n');
let typeMessage = 'console.' + type;
if (type === 'warn') {
message = chalk.yellow(message);
typeMessage = chalk.yellow(typeMessage);
} else if (type === 'error') {
message = chalk.red(message);
typeMessage = chalk.red(typeMessage);
}
return (
output +
TITLE_INDENT +
chalk.dim(typeMessage) +
' ' +
chalk.dim(origin) +
'\n' +
message +
'\n');
}, '');
};

View File

@@ -0,0 +1,47 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const chalk = require('chalk');var _require =
require('./utils');const formatTestPath = _require.formatTestPath;
const LONG_TEST_COLOR = chalk.reset.bold.bgRed;
// Explicitly reset for these messages since they can get written out in the
// middle of error logging
const FAIL = chalk.reset.inverse.bold.red(' FAIL ');
const PASS = chalk.reset.inverse.bold.green(' PASS ');
module.exports = (result, config) => {
const testPath = result.testFilePath;
const status = result.numFailingTests > 0 || result.testExecError ?
FAIL :
PASS;
const runTime = result.perfStats ?
(result.perfStats.end - result.perfStats.start) / 1000 :
null;
const testDetail = [];
if (runTime !== null && runTime > 5) {
testDetail.push(LONG_TEST_COLOR(runTime + 's'));
}
if (result.memoryUsage) {
const toMB = bytes => Math.floor(bytes / 1024 / 1024);
testDetail.push(`${toMB(result.memoryUsage)} MB heap size`);
}
return (
`${status} ${formatTestPath(config, testPath)}` + (
testDetail.length ? ` (${testDetail.join(', ')})` : ''));
};

View File

@@ -0,0 +1,239 @@
'use strict';var _slicedToArray = function () {function sliceIterator(arr, i) {var _arr = [];var _n = true;var _d = false;var _e = undefined;try {for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {_arr.push(_s.value);if (i && _arr.length === i) break;}} catch (err) {_d = true;_e = err;} finally {try {if (!_n && _i["return"]) _i["return"]();} finally {if (_d) throw _e;}}return _arr;}return function (arr, i) {if (Array.isArray(arr)) {return arr;} else if (Symbol.iterator in Object(arr)) {return sliceIterator(arr, i);} else {throw new TypeError("Invalid attempt to destructure non-iterable instance");}};}(); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const path = require('path');
const chalk = require('chalk');
const slash = require('slash');
const PROGRESS_BAR_WIDTH = 40;
const trimAndFormatPath = (
pad,
config,
testPath,
columns) =>
{
const maxLength = columns - pad;
const relative = relativePath(config, testPath);const
basename = relative.basename;let
dirname = relative.dirname;
// length is ok
if ((dirname + path.sep + basename).length <= maxLength) {
return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename));
}
// we can fit trimmed dirname and full basename
const basenameLength = basename.length;
if (basenameLength + 4 < maxLength) {
const dirnameLength = maxLength - 4 - basenameLength;
dirname =
'...' + dirname.slice(dirname.length - dirnameLength, dirname.length);
return slash(chalk.dim(dirname + path.sep) + chalk.bold(basename));
}
if (basenameLength + 4 === maxLength) {
return slash(chalk.dim('...' + path.sep) + chalk.bold(basename));
}
// can't fit dirname, but can fit trimmed basename
return slash(
chalk.bold(
'...' + basename.slice(basename.length - maxLength - 4, basename.length)));
};
const formatTestPath = (config, testPath) => {var _relativePath =
relativePath(config, testPath);const dirname = _relativePath.dirname,basename = _relativePath.basename;
return chalk.dim(dirname + path.sep) + chalk.bold(basename);
};
const relativePath = (config, testPath) => {
testPath = path.relative(config.rootDir, testPath);
const dirname = path.dirname(testPath);
const basename = path.basename(testPath);
return { basename, dirname };
};
const pluralize = (word, count) =>
`${count} ${word}${count === 1 ? '' : 's'}`;
const getSummary = (
aggregatedResults,
options) =>
{
let runTime = (Date.now() - aggregatedResults.startTime) / 1000;
if (options && options.roundTime) {
runTime = Math.floor(runTime);
}
const estimatedTime = options && options.estimatedTime || 0;
const snapshotResults = aggregatedResults.snapshot;
const snapshotsAdded = snapshotResults.added;
const snapshotsFailed = snapshotResults.unmatched;
const snapshotsPassed = snapshotResults.matched;
const snapshotsTotal = snapshotResults.total;
const snapshotsUpdated = snapshotResults.updated;
const suitesFailed = aggregatedResults.numFailedTestSuites;
const suitesPassed = aggregatedResults.numPassedTestSuites;
const suitesPending = aggregatedResults.numPendingTestSuites;
const suitesRun = suitesFailed + suitesPassed;
const suitesTotal = aggregatedResults.numTotalTestSuites;
const testsFailed = aggregatedResults.numFailedTests;
const testsPassed = aggregatedResults.numPassedTests;
const testsPending = aggregatedResults.numPendingTests;
const testsTotal = aggregatedResults.numTotalTests;
const width = options && options.width || 0;
const suites =
chalk.bold('Test Suites: ') + (
suitesFailed ? chalk.bold.red(`${suitesFailed} failed`) + ', ' : '') + (
suitesPending ?
chalk.bold.yellow(`${suitesPending} skipped`) + ', ' :
'') + (
suitesPassed ? chalk.bold.green(`${suitesPassed} passed`) + ', ' : '') + (
suitesRun !== suitesTotal ?
suitesRun + ' of ' + suitesTotal :
suitesTotal) +
` total`;
const tests =
chalk.bold('Tests: ') + (
testsFailed ? chalk.bold.red(`${testsFailed} failed`) + ', ' : '') + (
testsPending ? chalk.bold.yellow(`${testsPending} skipped`) + ', ' : '') + (
testsPassed ? chalk.bold.green(`${testsPassed} passed`) + ', ' : '') +
`${testsTotal} total`;
const snapshots =
chalk.bold('Snapshots: ') + (
snapshotsFailed ?
chalk.bold.red(`${snapshotsFailed} failed`) + ', ' :
'') + (
snapshotsUpdated ?
chalk.bold.green(`${snapshotsUpdated} updated`) + ', ' :
'') + (
snapshotsAdded ? chalk.bold.green(`${snapshotsAdded} added`) + ', ' : '') + (
snapshotsPassed ?
chalk.bold.green(`${snapshotsPassed} passed`) + ', ' :
'') +
`${snapshotsTotal} total`;
const time = renderTime(runTime, estimatedTime, width);
return [suites, tests, snapshots, time].join('\n');
};
const renderTime = (runTime, estimatedTime, width) => {
// If we are more than one second over the estimated time, highlight it.
const renderedTime = estimatedTime && runTime >= estimatedTime + 1 ?
chalk.bold.yellow(runTime + 's') :
runTime + 's';
let time = chalk.bold(`Time:`) + ` ${renderedTime}`;
if (runTime < estimatedTime) {
time += `, estimated ${estimatedTime}s`;
}
// Only show a progress bar if the test run is actually going to take
// some time.
if (estimatedTime > 2 && runTime < estimatedTime && width) {
const availableWidth = Math.min(PROGRESS_BAR_WIDTH, width);
const length = Math.min(
Math.floor(runTime / estimatedTime * availableWidth),
availableWidth);
if (availableWidth >= 2) {
time +=
'\n' +
chalk.green('█').repeat(length) +
chalk.white('█').repeat(availableWidth - length);
}
}
return time;
};
// word-wrap a string that contains ANSI escape sequences.
// ANSI escape sequences do not add to the string length.
const wrapAnsiString = (string, terminalWidth) => {
if (terminalWidth === 0) {
// if the terminal width is zero, don't bother word-wrapping
return string;
}
const ANSI_REGEXP = /[\u001b\u009b]\[\d{1,2}m/g;
const tokens = [];
let lastIndex = 0;
let match;
while (match = ANSI_REGEXP.exec(string)) {
const ansi = match[0];
const index = match['index'];
if (index != lastIndex) {
tokens.push(['string', string.slice(lastIndex, index)]);
}
tokens.push(['ansi', ansi]);
lastIndex = index + ansi.length;
}
if (lastIndex != string.length - 1) {
tokens.push(['string', string.slice(lastIndex, string.length)]);
}
let lastLineLength = 0;
return tokens.
reduce(
(lines, _ref) => {var _ref2 = _slicedToArray(_ref, 2);let kind = _ref2[0],token = _ref2[1];
if (kind === 'string') {
if (lastLineLength + token.length > terminalWidth) {
while (token.length) {
const chunk = token.slice(0, terminalWidth - lastLineLength);
const remaining = token.slice(
terminalWidth - lastLineLength,
token.length);
lines[lines.length - 1] += chunk;
lastLineLength += chunk.length;
token = remaining;
if (token.length) {
lines.push('');
lastLineLength = 0;
}
}
} else {
lines[lines.length - 1] += token;
lastLineLength += token.length;
}
} else {
lines[lines.length - 1] += token;
}
return lines;
},
['']).
join('\n');
};
module.exports = {
formatTestPath,
getSummary,
pluralize,
relativePath,
trimAndFormatPath,
wrapAnsiString };

View File

@@ -0,0 +1,219 @@
'use strict';function _asyncToGenerator(fn) {return function () {var gen = fn.apply(this, arguments);return new Promise(function (resolve, reject) {function step(key, arg) {try {var info = gen[key](arg);var value = info.value;} catch (error) {reject(error);return;}if (info.done) {resolve(value);} else {return Promise.resolve(value).then(function (value) {step("next", value);}, function (err) {step("throw", err);});}}return step("next");});};} /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const path = require('path');var _require =
require('jest-util');const Console = _require.Console,formatTestResults = _require.formatTestResults;
const chalk = require('chalk');
const fs = require('graceful-fs');
const getMaxWorkers = require('./lib/getMaxWorkers');
const getTestPathPattern = require('./lib/getTestPathPattern');
const SearchSource = require('./SearchSource');
const updateArgv = require('./lib/updateArgv');
const TestRunner = require('./TestRunner');
const TestSequencer = require('./TestSequencer');
const setConfig = (contexts, newConfig) =>
contexts.forEach(
context =>
context.config = Object.freeze(
Object.assign({}, context.config, newConfig)));
const formatTestPathPattern = pattern => {
const testPattern = pattern.testPathPattern;
const input = pattern.input;
const formattedPattern = `/${testPattern || ''}/`;
const formattedInput = pattern.shouldTreatInputAsPattern ?
`/${input || ''}/` :
`"${input || ''}"`;
return input === testPattern ? formattedInput : formattedPattern;
};
const getNoTestsFoundMessage = (testRunData, pattern) => {
if (pattern.onlyChanged) {
return (
chalk.bold(
'No tests found related to files changed since last commit.\n') +
chalk.dim(
pattern.watch ?
'Press `a` to run all tests, or run Jest with `--watchAll`.' :
'Run Jest without `-o` to run all tests.'));
}
const pluralize = (word, count, ending) =>
`${count} ${word}${count === 1 ? '' : ending}`;
const testPathPattern = formatTestPathPattern(pattern);
const individualResults = testRunData.map(testRun => {
const stats = testRun.matches.stats || {};
const config = testRun.context.config;
const statsMessage = Object.keys(stats).
map(key => {
if (key === 'roots' && config.roots.length === 1) {
return null;
}
const value = config[key];
if (value) {
const matches = pluralize('match', stats[key], 'es');
return ` ${key}: ${chalk.yellow(value)} - ${matches}`;
}
return null;
}).
filter(line => line).
join('\n');
return testRun.matches.total ?
`In ${chalk.bold(config.rootDir)}\n` +
` ${pluralize('file', testRun.matches.total || 0, 's')} checked.\n` +
statsMessage :
`No files found in ${config.rootDir}.\n` +
`Make sure Jest's configuration does not exclude this directory.` +
`\nTo set up Jest, make sure a package.json file exists.\n` +
`Jest Documentation: ` +
`facebook.github.io/jest/docs/configuration.html`;
});
return (
chalk.bold('No tests found') +
'\n' +
individualResults.join('\n') +
'\n' +
`Pattern: ${chalk.yellow(testPathPattern)} - 0 matches`);
};
const getTestPaths = (() => {var _ref = _asyncToGenerator(function* (globalConfig, context, pattern, argv, pipe) {
const source = new SearchSource(context);
let data = yield source.getTestPaths(pattern);
if (!data.tests.length) {
if (pattern.onlyChanged && data.noSCM) {
if (globalConfig.watch) {
// Run all the tests
updateArgv(argv, 'watchAll', { noSCM: true });
pattern = getTestPathPattern(argv);
data = yield source.getTestPaths(pattern);
} else {
new Console(pipe, pipe).log(
'Jest can only find uncommitted changed files in a git or hg ' +
'repository. If you make your project a git or hg ' +
'repository (`git init` or `hg init`), Jest will be able ' +
'to only run tests related to files changed since the last ' +
'commit.');
}
}
}
return data;
});return function getTestPaths(_x, _x2, _x3, _x4, _x5) {return _ref.apply(this, arguments);};})();
const processResults = (runResults, options) => {
if (options.testResultsProcessor) {
/* $FlowFixMe */
runResults = require(options.testResultsProcessor)(runResults);
}
if (options.isJSON) {
if (options.outputFile) {
const outputFile = path.resolve(process.cwd(), options.outputFile);
fs.writeFileSync(
outputFile,
JSON.stringify(formatTestResults(runResults)));
process.stdout.write(
`Test results written to: ` +
`${path.relative(process.cwd(), outputFile)}\n`);
} else {
process.stdout.write(JSON.stringify(formatTestResults(runResults)));
}
}
return options.onComplete && options.onComplete(runResults);
};
const runJest = (() => {var _ref2 = _asyncToGenerator(function* (
globalConfig,
contexts,
argv,
pipe,
testWatcher,
startRun,
onComplete)
{
const maxWorkers = getMaxWorkers(argv);
const pattern = getTestPathPattern(argv);
const sequencer = new TestSequencer();
let allTests = [];
const testRunData = yield Promise.all(
contexts.map((() => {var _ref3 = _asyncToGenerator(function* (context) {
const matches = yield getTestPaths(
globalConfig,
context,
pattern,
argv,
pipe);
allTests = allTests.concat(matches.tests);
return { context, matches };
});return function (_x13) {return _ref3.apply(this, arguments);};})()));
allTests = sequencer.sort(allTests);
if (argv.listTests) {
console.log(JSON.stringify(allTests.map(function (test) {return test.path;})));
onComplete && onComplete({ success: true });
return null;
}
if (!allTests.length) {
new Console(pipe, pipe).log(getNoTestsFoundMessage(testRunData, pattern));
} else if (
allTests.length === 1 &&
globalConfig.silent !== true &&
globalConfig.verbose !== false)
{
// $FlowFixMe
globalConfig = Object.freeze(
Object.assign({}, globalConfig, { verbose: true }));
}
// When using more than one context, make all printed paths relative to the
// current cwd. rootDir is only used as a token during normalization and
// has no special meaning afterwards except for printing information to the
// CLI.
setConfig(contexts, { rootDir: process.cwd() });
const results = yield new TestRunner(globalConfig, {
maxWorkers,
pattern,
startRun,
testNamePattern: argv.testNamePattern,
testPathPattern: formatTestPathPattern(pattern) }).
runTests(allTests, testWatcher);
sequencer.cacheResults(allTests, results);
return processResults(results, {
isJSON: argv.json,
onComplete,
outputFile: argv.outputFile,
testResultsProcessor: globalConfig.testResultsProcessor });
});return function runJest(_x6, _x7, _x8, _x9, _x10, _x11, _x12) {return _ref2.apply(this, arguments);};})();
module.exports = runJest;

View File

@@ -0,0 +1,121 @@
'use strict'; /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/
const fs = require('fs');var _require =
require('jest-util');const Console = _require.Console,NullConsole = _require.NullConsole,setGlobal = _require.setGlobal;var _require2 =
require('jest-config');const getTestEnvironment = _require2.getTestEnvironment;
const docblock = require('jest-docblock');
const BufferedConsole = require('./lib/BufferedConsole');
const getConsoleOutput = require('./reporters/getConsoleOutput');
function runTest(
path,
globalConfig,
config,
resolver)
{
let testSource;
try {
testSource = fs.readFileSync(path, 'utf8');
} catch (e) {
return Promise.reject(e);
}
const parsedDocblock = docblock.parse(docblock.extract(testSource));
const customEnvironment = parsedDocblock['jest-environment'];
let testEnvironment = config.testEnvironment;
if (customEnvironment) {
testEnvironment = getTestEnvironment(
Object.assign({}, config, {
testEnvironment: customEnvironment }));
}
/* $FlowFixMe */
const TestEnvironment = require(testEnvironment);
/* $FlowFixMe */
const testFramework = require(config.testRunner);
/* $FlowFixMe */
const Runtime = require(config.moduleLoader || 'jest-runtime');
const environment = new TestEnvironment(config);
const TestConsole = globalConfig.verbose ?
Console :
globalConfig.silent ? NullConsole : BufferedConsole;
const testConsole = new TestConsole(
globalConfig.useStderr ? process.stderr : process.stdout,
process.stderr,
(type, message) =>
getConsoleOutput(
config.rootDir,
!!globalConfig.verbose,
// 4 = the console call is buried 4 stack frames deep
BufferedConsole.write([], type, message, 4)));
const cacheFS = { [path]: testSource };
setGlobal(environment.global, 'console', testConsole);
const runtime = new Runtime(config, environment, resolver, cacheFS, {
collectCoverage: globalConfig.collectCoverage,
collectCoverageFrom: globalConfig.collectCoverageFrom,
collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom,
mapCoverage: globalConfig.mapCoverage });
const start = Date.now();
return testFramework(globalConfig, config, environment, runtime, path).
then(result => {
const testCount =
result.numPassingTests +
result.numFailingTests +
result.numPendingTests;
result.perfStats = { end: Date.now(), start };
result.testFilePath = path;
result.coverage = runtime.getAllCoverageInfo();
result.sourceMaps = runtime.getSourceMapInfo();
result.console = testConsole.getBuffer();
result.skipped = testCount === result.numPendingTests;
return result;
}).
then(
result =>
Promise.resolve().then(() => {
environment.dispose();
if (config.logHeapUsage) {
if (global.gc) {
global.gc();
}
result.memoryUsage = process.memoryUsage().heapUsed;
}
// Delay the resolution to allow log messages to be output.
return new Promise(resolve => setImmediate(() => resolve(result)));
}),
err =>
Promise.resolve().then(() => {
environment.dispose();
throw err;
}));
}
module.exports = runTest;

View File

@@ -0,0 +1,325 @@
'use strict';
const ansiEscapes = require('ansi-escapes'); /**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*
*/const chalk = require('chalk');var _require = require('jest-regex-util');const replacePathSepForRegex = _require.replacePathSepForRegex;const HasteMap = require('jest-haste-map');const isCI = require('is-ci');const isValidPath = require('./lib/isValidPath');const preRunMessage = require('./preRunMessage');const createContext = require('./lib/createContext');const runJest = require('./runJest');
const updateArgv = require('./lib/updateArgv');
const SearchSource = require('./SearchSource');
const TestWatcher = require('./TestWatcher');
const Prompt = require('./lib/Prompt');
const TestPathPatternPrompt = require('./TestPathPatternPrompt');
const TestNamePatternPrompt = require('./TestNamePatternPrompt');var _require2 =
require('./constants');const KEYS = _require2.KEYS,CLEAR = _require2.CLEAR;
const isInteractive = process.stdout.isTTY && !isCI;
let hasExitListener = false;
const watch = function (
initialGlobalConfig,
contexts,
argv,
pipe,
hasteMapInstances)
{let stdin = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : process.stdin;
updateArgv(argv, argv.watch ? 'watch' : 'watchAll', {
testNamePattern: argv.testNamePattern,
testPathPattern: argv.testPathPattern || (argv._ || []).join('|') });
const prompt = new Prompt();
const testPathPatternPrompt = new TestPathPatternPrompt(pipe, prompt);
const testNamePatternPrompt = new TestNamePatternPrompt(pipe, prompt);
let searchSources = contexts.map(context => ({
context,
searchSource: new SearchSource(context) }));
let hasSnapshotFailure = false;
let isRunning = false;
let testWatcher;
let shouldDisplayWatchUsage = true;
let isWatchUsageDisplayed = false;
testPathPatternPrompt.updateSearchSources(searchSources);
hasteMapInstances.forEach((hasteMapInstance, index) => {
hasteMapInstance.on('change', (_ref) => {let eventsQueue = _ref.eventsQueue,hasteFS = _ref.hasteFS,moduleMap = _ref.moduleMap;
const validPaths = eventsQueue.filter((_ref2) => {let filePath = _ref2.filePath;
return isValidPath(
initialGlobalConfig,
contexts[index].config,
filePath);
});
if (validPaths.length) {
const context = contexts[index] = createContext(
contexts[index].config,
{
hasteFS,
moduleMap });
prompt.abort();
searchSources = searchSources.slice();
searchSources[index] = {
context,
searchSource: new SearchSource(context) };
testPathPatternPrompt.updateSearchSources(searchSources);
startRun();
}
});
});
if (!hasExitListener) {
hasExitListener = true;
process.on('exit', () => {
if (prompt.isEntering()) {
pipe.write(ansiEscapes.cursorDown());
pipe.write(ansiEscapes.eraseDown);
}
});
}
const startRun = function () {let overrideConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (isRunning) {
return null;
}
testWatcher = new TestWatcher({ isWatchMode: true });
isInteractive && pipe.write(CLEAR);
preRunMessage.print(pipe);
isRunning = true;
const globalConfig = Object.freeze(
Object.assign({}, initialGlobalConfig, overrideConfig, {
testNamePattern: argv.testNamePattern,
testPathPattern: argv.testPathPattern }));
return runJest(
// $FlowFixMe
globalConfig,
contexts,
argv,
pipe,
testWatcher,
startRun,
results => {
isRunning = false;
hasSnapshotFailure = !!results.snapshot.failure;
// Create a new testWatcher instance so that re-runs won't be blocked.
// The old instance that was passed to Jest will still be interrupted
// and prevent test runs from the previous run.
testWatcher = new TestWatcher({ isWatchMode: true });
if (shouldDisplayWatchUsage) {
pipe.write(usage(argv, hasSnapshotFailure));
shouldDisplayWatchUsage = false; // hide Watch Usage after first run
isWatchUsageDisplayed = true;
} else {
pipe.write(showToggleUsagePrompt());
shouldDisplayWatchUsage = false;
isWatchUsageDisplayed = false;
}
testNamePatternPrompt.updateCachedTestResults(results.testResults);
}).
catch(error => console.error(chalk.red(error.stack)));
};
const onKeypress = key => {
if (key === KEYS.CONTROL_C || key === KEYS.CONTROL_D) {
process.exit(0);
return;
}
if (prompt.isEntering()) {
prompt.put(key);
return;
}
// Abort test run
if (
isRunning &&
testWatcher &&
[KEYS.Q, KEYS.ENTER, KEYS.A, KEYS.O, KEYS.P, KEYS.T].indexOf(key) !== -1)
{
testWatcher.setState({ interrupted: true });
return;
}
switch (key) {
case KEYS.Q:
process.exit(0);
return;
case KEYS.ENTER:
startRun();
break;
case KEYS.U:
startRun({ updateSnapshot: 'all' });
break;
case KEYS.A:
updateArgv(argv, 'watchAll', {
testNamePattern: '',
testPathPattern: '' });
startRun();
break;
case KEYS.C:
updateArgv(argv, 'watch', {
testNamePattern: '',
testPathPattern: '' });
startRun();
break;
case KEYS.O:
updateArgv(argv, 'watch', {
testNamePattern: '',
testPathPattern: '' });
startRun();
break;
case KEYS.P:
testPathPatternPrompt.run(
testPathPattern => {
updateArgv(argv, 'watch', {
testNamePattern: '',
testPathPattern: replacePathSepForRegex(testPathPattern) });
startRun();
},
onCancelPatternPrompt,
{ header: activeFilters(argv) });
break;
case KEYS.T:
testNamePatternPrompt.run(
testNamePattern => {
updateArgv(argv, 'watch', {
testNamePattern,
testPathPattern: argv.testPathPattern });
startRun();
},
onCancelPatternPrompt,
{ header: activeFilters(argv) });
break;
case KEYS.QUESTION_MARK:
break;
case KEYS.W:
if (!shouldDisplayWatchUsage && !isWatchUsageDisplayed) {
pipe.write(ansiEscapes.cursorUp());
pipe.write(ansiEscapes.eraseDown);
pipe.write(usage(argv, hasSnapshotFailure));
isWatchUsageDisplayed = true;
shouldDisplayWatchUsage = false;
}
break;}
};
const onCancelPatternPrompt = () => {
pipe.write(ansiEscapes.cursorHide);
pipe.write(ansiEscapes.clearScreen);
pipe.write(usage(argv, hasSnapshotFailure));
pipe.write(ansiEscapes.cursorShow);
};
if (typeof stdin.setRawMode === 'function') {
stdin.setRawMode(true);
stdin.resume();
stdin.setEncoding('hex');
stdin.on('data', onKeypress);
}
startRun();
return Promise.resolve();
};
const activeFilters = function (argv) {let delimiter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '\n';const
testNamePattern = argv.testNamePattern,testPathPattern = argv.testPathPattern;
if (testNamePattern || testPathPattern) {
const filters = [
testPathPattern ?
chalk.dim('filename ') + chalk.yellow('/' + testPathPattern + '/') :
null,
testNamePattern ?
chalk.dim('test name ') + chalk.yellow('/' + testNamePattern + '/') :
null].
filter(f => !!f).
join(', ');
const messages = ['\n' + chalk.bold('Active Filters: ') + filters];
return messages.filter(message => !!message).join(delimiter);
}
return '';
};
const usage = function (argv, snapshotFailure) {let delimiter = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '\n';
const messages = [
activeFilters(argv),
argv.testPathPattern || argv.testNamePattern ?
chalk.dim(' \u203A Press ') + 'c' + chalk.dim(' to clear filters.') :
null,
'\n' + chalk.bold('Watch Usage'),
argv.watch ?
chalk.dim(' \u203A Press ') + 'a' + chalk.dim(' to run all tests.') :
null,
(argv.watchAll || argv.testPathPattern || argv.testNamePattern) &&
!argv.noSCM ?
chalk.dim(' \u203A Press ') +
'o' +
chalk.dim(' to only run tests related to changed files.') :
null,
snapshotFailure ?
chalk.dim(' \u203A Press ') +
'u' +
chalk.dim(' to update failing snapshots.') :
null,
chalk.dim(' \u203A Press ') +
'p' +
chalk.dim(' to filter by a filename regex pattern.'),
chalk.dim(' \u203A Press ') +
't' +
chalk.dim(' to filter by a test name regex pattern.'),
chalk.dim(' \u203A Press ') + 'q' + chalk.dim(' to quit watch mode.'),
chalk.dim(' \u203A Press ') +
'Enter' +
chalk.dim(' to trigger a test run.')];
return messages.filter(message => !!message).join(delimiter) + '\n';
};
const showToggleUsagePrompt = () =>
'\n' +
chalk.bold('Watch Usage: ') +
chalk.dim('Press ') +
'w' +
chalk.dim(' to show more.');
module.exports = watch;

View File

@@ -0,0 +1,107 @@
{
"_args": [
[
"jest-cli@20.0.4",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project"
]
],
"_from": "jest-cli@20.0.4",
"_id": "jest-cli@20.0.4",
"_inBundle": false,
"_integrity": "sha1-5TKxnYiuW8bEF+iwWTpv6VSx3JM=",
"_location": "/react-scripts/jest/jest-cli",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "jest-cli@20.0.4",
"name": "jest-cli",
"escapedName": "jest-cli",
"rawSpec": "20.0.4",
"saveSpec": null,
"fetchSpec": "20.0.4"
},
"_requiredBy": [
"/react-scripts/jest"
],
"_resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-20.0.4.tgz",
"_spec": "20.0.4",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project",
"bin": {
"jest": "./bin/jest.js"
},
"bugs": {
"url": "https://github.com/facebook/jest/issues"
},
"dependencies": {
"ansi-escapes": "^1.4.0",
"callsites": "^2.0.0",
"chalk": "^1.1.3",
"graceful-fs": "^4.1.11",
"is-ci": "^1.0.10",
"istanbul-api": "^1.1.1",
"istanbul-lib-coverage": "^1.0.1",
"istanbul-lib-instrument": "^1.4.2",
"istanbul-lib-source-maps": "^1.1.0",
"jest-changed-files": "^20.0.3",
"jest-config": "^20.0.4",
"jest-docblock": "^20.0.3",
"jest-environment-jsdom": "^20.0.3",
"jest-haste-map": "^20.0.4",
"jest-jasmine2": "^20.0.4",
"jest-message-util": "^20.0.3",
"jest-regex-util": "^20.0.3",
"jest-resolve-dependencies": "^20.0.3",
"jest-runtime": "^20.0.4",
"jest-snapshot": "^20.0.3",
"jest-util": "^20.0.3",
"micromatch": "^2.3.11",
"node-notifier": "^5.0.2",
"pify": "^2.3.0",
"slash": "^1.0.0",
"string-length": "^1.0.1",
"throat": "^3.0.0",
"which": "^1.2.12",
"worker-farm": "^1.3.1",
"yargs": "^7.0.2"
},
"description": "Delightful JavaScript Testing.",
"engines": {
"node": ">= 4"
},
"homepage": "http://facebook.github.io/jest/",
"keywords": [
"ava",
"babel",
"coverage",
"easy",
"expect",
"facebook",
"immersive",
"instant",
"jasmine",
"jest",
"jsdom",
"mocha",
"mocking",
"painless",
"qunit",
"runner",
"sandboxed",
"snapshot",
"tap",
"tape",
"test",
"testing",
"typescript",
"watch"
],
"license": "BSD-3-Clause",
"main": "build/jest.js",
"name": "jest-cli",
"repository": {
"type": "git",
"url": "git+https://github.com/facebook/jest.git"
},
"version": "20.0.4"
}

View File

@@ -0,0 +1,107 @@
{
"_args": [
[
"jest@20.0.4",
"C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project"
]
],
"_from": "jest@20.0.4",
"_id": "jest@20.0.4",
"_inBundle": false,
"_integrity": "sha1-PdJgwpidba1nix6cxNkZRPbWAqw=",
"_location": "/react-scripts/jest",
"_phantomChildren": {
"chalk": "1.1.3",
"graceful-fs": "4.1.11",
"is-ci": "1.0.10",
"istanbul-api": "1.2.1",
"istanbul-lib-coverage": "1.1.1",
"istanbul-lib-instrument": "1.9.1",
"istanbul-lib-source-maps": "1.2.2",
"jest-changed-files": "20.0.3",
"jest-config": "20.0.4",
"jest-docblock": "20.0.3",
"jest-environment-jsdom": "20.0.3",
"jest-haste-map": "20.0.5",
"jest-jasmine2": "20.0.4",
"jest-message-util": "20.0.3",
"jest-regex-util": "20.0.3",
"jest-resolve-dependencies": "20.0.3",
"jest-runtime": "20.0.4",
"jest-snapshot": "20.0.3",
"jest-util": "20.0.3",
"micromatch": "2.3.11",
"node-notifier": "5.1.2",
"pify": "2.3.0",
"slash": "1.0.0",
"string-length": "1.0.1",
"throat": "3.2.0",
"which": "1.3.0",
"worker-farm": "1.5.1",
"yargs": "7.1.0"
},
"_requested": {
"type": "version",
"registry": true,
"raw": "jest@20.0.4",
"name": "jest",
"escapedName": "jest",
"rawSpec": "20.0.4",
"saveSpec": null,
"fetchSpec": "20.0.4"
},
"_requiredBy": [
"/react-scripts"
],
"_resolved": "https://registry.npmjs.org/jest/-/jest-20.0.4.tgz",
"_spec": "20.0.4",
"_where": "C:\\Users\\deranjer\\go\\src\\github.com\\deranjer\\goTorrent\\torrent-project",
"bin": {
"jest": "./bin/jest.js"
},
"bugs": {
"url": "https://github.com/facebook/jest/issues"
},
"dependencies": {
"jest-cli": "^20.0.4"
},
"description": "Delightful JavaScript Testing.",
"engines": {
"node": ">= 4"
},
"homepage": "http://facebook.github.io/jest/",
"keywords": [
"ava",
"babel",
"coverage",
"easy",
"expect",
"facebook",
"immersive",
"instant",
"jasmine",
"jest",
"jsdom",
"mocha",
"mocking",
"painless",
"qunit",
"runner",
"sandboxed",
"snapshot",
"tap",
"tape",
"test",
"testing",
"typescript",
"watch"
],
"license": "BSD-3-Clause",
"main": "build/jest.js",
"name": "jest",
"repository": {
"type": "git",
"url": "git+https://github.com/facebook/jest.git"
},
"version": "20.0.4"
}