Skip to content

Commit

Permalink
Use vm.Script and refactor coverage caching. (#1239)
Browse files Browse the repository at this point in the history
* Use `vm.Script`.

* Rewrite basic coverage support in Jest.

* Move `vm.Script` creation and caching into `transform`.

* Copy all jest packages into example folders.

This ensures we are using the latest version of every package.

* Cache the wrapped code.

* Use babel-jest for Jest itself; update setup.

* Added a transform.js test.
* Relax jest.mock babel transform restrictions.
* Updated package.json and .npmignore for all packages.

* Make watch script resilient to deleted files.
  • Loading branch information
cpojer authored Jul 7, 2016
1 parent ca1a290 commit 25b8369
Show file tree
Hide file tree
Showing 76 changed files with 586 additions and 426 deletions.
7 changes: 7 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"plugins": [
"syntax-trailing-function-commas",
"transform-flow-strip-types"
],
"retainLines": true
}
4 changes: 2 additions & 2 deletions examples/react/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"react": "~0.14.0",
"react-dom": "~0.14.0"
"react": "~15.2.0",
"react-dom": "~15.2.0"
},
"devDependencies": {
"babel-jest": "*",
Expand Down
4 changes: 2 additions & 2 deletions integration_tests/__tests__/snapshot-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const originalTestPath = path.resolve(
__dirname,
'../snapshot/__tests__/snapshot-test.js'
);
const originalTestContent = fs.readFileSync(originalTestPath, 'utf-8');
const originalTestContent = fs.readFileSync(originalTestPath, 'utf8');
const copyOfTestPath = originalTestPath.replace('.js', '_copy.js');

const snapshotEscapeDir =
Expand All @@ -49,7 +49,7 @@ const fileExists = filePath => {
const getSnapshotOfCopy = () => {
const exports = Object.create(null);
// eslint-disable-next-line no-eval
eval(fs.readFileSync(snapshotOfCopy, 'utf-8'));
eval(fs.readFileSync(snapshotOfCopy, 'utf8'));
return exports;
};

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"clean": "rm -rf ./packages/*/node_modules; npm run build-clean",
"lint": "eslint .",
"postinstall": "node ./scripts/postinstall.js && node ./scripts/build.js",
"publish": "npm run build-clean && npm run build && lerna publish",
"t": "node ./scripts/test.js",
"test": "npm run typecheck && npm run lint && npm run build && npm run t",
"typecheck": "flow check",
Expand Down
3 changes: 3 additions & 0 deletions packages/babel-jest/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/__mocks__/**
**/__tests__/**
src
2 changes: 1 addition & 1 deletion packages/babel-plugin-jest-hoist/.babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["es2015", {plugins: ["./"]}]
"presets": ["es2015", {"plugins": ["./"]}]
}
5 changes: 3 additions & 2 deletions packages/babel-plugin-jest-hoist/.npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__tests__/
__test_modules__/
**/__mocks__/**
**/__tests__/**
src
2 changes: 1 addition & 1 deletion packages/babel-plugin-jest-hoist/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"react": "^0.14.0"
},
"jest": {
"rootDir": "./build",
"rootDir": "./src",
"scriptPreprocessor": "../../babel-jest",
"testEnvironment": "node"
},
Expand Down
18 changes: 12 additions & 6 deletions packages/babel-plugin-jest-hoist/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ function invariant(condition, message) {
}
}

// We allow `jest`, `require`, all default Node.js globals and all ES2015
// built-ins to be used inside of a `jest.mock` factory.
// We allow `jest`, `expect`, `require`, all default Node.js globals and all
// ES2015 built-ins to be used inside of a `jest.mock` factory.
// We also allow variables prefixed with `mock` as an escape-hatch.
const WHITELISTED_IDENTIFIERS = {
jest: true,
expect: true,
require: true,
Infinity: true,
NaN: true,
Expand Down Expand Up @@ -103,12 +105,16 @@ FUNCTIONS.mock = args => {

if (!found) {
invariant(
scope.hasGlobal(name) && WHITELISTED_IDENTIFIERS[name],
'The second argument of `jest.mock()` is not allowed to ' +
'reference any outside variables.\n' +
(scope.hasGlobal(name) && WHITELISTED_IDENTIFIERS[name]) ||
/^mock/.test(name),
'The module factory of `jest.mock()` is not allowed to ' +
'reference any out-of-scope variables.\n' +
'Invalid variable access: ' + name + '\n' +
'Whitelisted objects: ' +
Object.keys(WHITELISTED_IDENTIFIERS).join(', ') + '.',
Object.keys(WHITELISTED_IDENTIFIERS).join(', ') + '.\n' +
'Note: This is a precaution to guard against uninitialized mock ' +
'variables. If it is ensured that the mock is required lazily, ' +
'variable names prefixed with `mock` are permitted.',
);
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/babel-preset-jest/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/__mocks__/**
**/__tests__/**
src
4 changes: 2 additions & 2 deletions packages/jest-changed-files/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__mocks__/
__tests__/
**/__mocks__/**
**/__tests__/**
src
3 changes: 2 additions & 1 deletion packages/jest-changed-files/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"rimraf": "^2.5.2"
},
"jest": {
"rootDir": "./build",
"rootDir": "./src",
"scriptPreprocessor": "../../babel-jest",
"testEnvironment": "node"
},
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-cli/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__tests__
__mocks__
**/__mocks__/**
**/__tests__/**
src
6 changes: 3 additions & 3 deletions packages/jest-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"jest-util": "^13.2.2",
"jest-snapshot": "^13.2.3",
"json-stable-stringify": "^1.0.0",
"lodash.template": "^4.2.4",
"sane": "^1.2.0",
"which": "^1.1.1",
"worker-farm": "^1.3.1",
Expand Down Expand Up @@ -48,8 +47,9 @@
"test": "./bin/jest.js"
},
"jest": {
"rootDir": "./build",
"testEnvironment": "jest-environment-node"
"rootDir": "./src",
"scriptPreprocessor": "../../babel-jest",
"testEnvironment": "node"
},
"bugs": {
"url": "https://github.com/facebook/jest/issues"
Expand Down
80 changes: 0 additions & 80 deletions packages/jest-cli/src/CoverageCollector.js

This file was deleted.

4 changes: 2 additions & 2 deletions packages/jest-config/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__tests__
__mocks__
**/__mocks__/**
**/__tests__/**
src
1 change: 1 addition & 0 deletions packages/jest-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"jest": {
"rootDir": "./build",
"scriptPreprocessor": "../../babel-jest",
"testEnvironment": "jest-environment-node"
},
"scripts": {
Expand Down
26 changes: 17 additions & 9 deletions packages/jest-config/src/IstanbulCollector.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,36 @@
* 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.
*
* @flow
*/
'use strict';

import type {Path} from 'types/Config';

const istanbul = require('istanbul');

class IstanbulCollector {

constructor(sourceText, filename) {
const instr = new istanbul.Instrumenter();
this._coverageDataStore = {};
this._instrumentor = instr;
this._origSourceText = sourceText;
this._instrumentedSourceText = instr.instrumentSync(sourceText, filename);
_coverageDataStore: Object;

constructor() {
this._coverageDataStore = Object.create(null);
}

getCoverageDataStore() {
return this._coverageDataStore;
}

getInstrumentedSource(storageVarName) {
return this._instrumentedSourceText + storageVarName + '.coverState=' +
this._instrumentor.currentState.trackerVar + ';';
getInstrumentedSource(
sourceText: string,
filename: Path,
storageVarName: string,
) {
const instrumentor = new istanbul.Instrumenter();
const source = instrumentor.instrumentSync(sourceText, filename);
const tracker = instrumentor.currentState.trackerVar;
return source + storageVarName + '.coverState=' + tracker + ';';
}

extractRuntimeCoverageInfo() {
Expand Down
50 changes: 32 additions & 18 deletions packages/jest-config/src/reporters/IstanbulTestReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,31 @@
*/
'use strict';

import type {Config} from 'types/Config';
import type {AggregatedResult, TestResult} from 'types/TestResult';
import type {Process} from 'types/Process';

const DefaultTestReporter = require('./DefaultTestReporter');

const chalk = require('chalk');
const istanbul = require('istanbul');
const collector = new istanbul.Collector();
const testCollectors = Object.create(null);
const reporter = new istanbul.Reporter();

const FAIL_COLOR = chalk.bold.red;

import type {Config} from 'types/Config';
import type {AggregatedResult, TestResult} from 'types/TestResult';

class IstanbulTestReporter extends DefaultTestReporter {

_collector: istanbul.Collector;
_reporter: istanbul.Reporter;
_testCollectors: Object;

constructor(customProcess: Process) {
super(customProcess);

this._collector = new istanbul.Collector();
this._testCollectors = Object.create(null);
this._reporter = new istanbul.Reporter();
}

onTestResult(
config: Config,
testResult: TestResult,
Expand All @@ -30,27 +42,29 @@ class IstanbulTestReporter extends DefaultTestReporter {
super.onTestResult(config, testResult, aggregatedResults);

if (config.collectCoverage && testResult.coverage) {
collector.add(testResult.coverage);
if (!testCollectors[testResult.testFilePath]) {
testCollectors[testResult.testFilePath] = new istanbul.Collector();
const testFilePath = testResult.testFilePath;
this._collector.add(testResult.coverage);
if (!this._testCollectors[testFilePath]) {
this._testCollectors[testFilePath] = new istanbul.Collector();
}
testCollectors[testResult.testFilePath].add(testResult.coverage);
this._testCollectors[testFilePath].add(testResult.coverage);
}
}

onRunComplete(config: Config, aggregatedResults: AggregatedResult) {
aggregatedResults.success = super.onRunComplete(config, aggregatedResults);

const reporter = this._reporter;
if (config.collectCoverage) {
try {
if (config.coverageDirectory) {
reporter.dir = config.coverageDirectory;
}
reporter.addAll(config.coverageReporters);
reporter.write(collector, true, () => {});
reporter.write(this._collector, true, () => {});
} catch (e) {}
if (config.coverageThreshold) {
const rawCoverage = collector.getFinalCoverage();
const rawCoverage = this._collector.getFinalCoverage();
const globalResults = istanbul.utils.summarizeCoverage(rawCoverage);

function check(name, thresholds, actuals) {
Expand Down Expand Up @@ -97,16 +111,16 @@ class IstanbulTestReporter extends DefaultTestReporter {
return aggregatedResults.success;
}

static getReporter() {
return reporter;
getReporter() {
return this._reporter;
}

static getCollector() {
return collector;
getCollector() {
return this._collector;
}

static getTestCollectors() {
return testCollectors;
getTestCollectors() {
return this._testCollectors;
}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/jest-environment-jsdom/.npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__tests__
__mocks__
**/__mocks__/**
**/__tests__/**
src
Loading

0 comments on commit 25b8369

Please sign in to comment.