diff --git a/docs/Configuration.md b/docs/Configuration.md index 2753a88d5a74..e8f9182f8949 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -352,7 +352,18 @@ To make a dependency explicit instead of implicit, you can call [`expect.addSnap ### `testEnvironment` [string] Default: `"jsdom"` -The test environment that will be used for testing. The default environment in Jest is a browser-like environment through [jsdom](https://github.com/tmpvar/jsdom). If you are building a node service, you can use the `node` option to use a node-like environment instead. Combining the test environments is currently not possible but the `jsdom` environment can be seen as a superset of the `node` one. +The test environment that will be used for testing. The default environment in Jest is a browser-like environment through [jsdom](https://github.com/tmpvar/jsdom). If you are building a node service, you can use the `node` option to use a node-like environment instead. If some tests require another environment, you can add a `@jest-environment` docblock. + +```js +/** + * @jest-environment jsdom + */ + +test('use jsdom in this test file', () => { + const element = document.createElement('div'); + expect(element).not.toBeNull(); +}); +``` You can create your own module that will be used for setting up the test environment. The module must export a class with `runScript` and `dispose` methods. See the [node](https://github.com/facebook/jest/blob/master/packages/jest-environment-node/src/index.js) or [jsdom](https://github.com/facebook/jest/blob/master/packages/jest-environment-jsdom/src/index.js) environments as examples. diff --git a/integration_tests/__tests__/test-environment-test.js b/integration_tests/__tests__/test-environment-test.js new file mode 100644 index 000000000000..f2c53ce54040 --- /dev/null +++ b/integration_tests/__tests__/test-environment-test.js @@ -0,0 +1,26 @@ +/** + * 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. + * + * @emails oncall+jsinfra + */ +'use strict'; + +const runJest = require('../runJest'); +const skipOnWindows = require('skipOnWindows'); + +skipOnWindows.suite(); + +const testFixturePackage = require('../test-environment/package.json'); + +it('respects testEnvironment docblock', () => { + expect(testFixturePackage.jest.testEnvironment).toEqual('node'); + + const result = runJest.json('test-environment').json; + + expect(result.success).toBe(true); + expect(result.numTotalTests).toBe(1); +}); diff --git a/integration_tests/test-environment/__tests__/env-test.js b/integration_tests/test-environment/__tests__/env-test.js new file mode 100644 index 000000000000..1781c6be6304 --- /dev/null +++ b/integration_tests/test-environment/__tests__/env-test.js @@ -0,0 +1,16 @@ +/** + * 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. + * + * @jest-environment jsdom + */ +'use strict'; +/* eslint-env browser*/ + +test('stub', () => { + const element = document.createElement('div'); + expect(element).not.toBeNull(); +}); diff --git a/integration_tests/test-environment/package.json b/integration_tests/test-environment/package.json new file mode 100644 index 000000000000..148788b25446 --- /dev/null +++ b/integration_tests/test-environment/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "node" + } +} diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index ad32f4018853..c78e451f63a1 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -15,6 +15,7 @@ "istanbul-lib-source-maps": "^1.1.0", "jest-changed-files": "^19.0.2", "jest-config": "^19.0.2", + "jest-docblock": "^19.0.2", "jest-environment-jsdom": "^19.0.2", "jest-haste-map": "^19.0.0", "jest-jasmine2": "^19.0.2", diff --git a/packages/jest-cli/src/runTest.js b/packages/jest-cli/src/runTest.js index 79d63c62b51c..adf8ebd7ffee 100644 --- a/packages/jest-cli/src/runTest.js +++ b/packages/jest-cli/src/runTest.js @@ -19,11 +19,35 @@ const { NullConsole, setGlobal, } = require('jest-util'); + +const {getTestEnvironment} = require('jest-config'); +const fs = require('fs'); +const docblock = require('jest-docblock'); const getConsoleOutput = require('./reporters/getConsoleOutput'); function runTest(path: Path, config: Config, resolver: 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(config.testEnvironment); + const TestEnvironment = require(testEnvironment); /* $FlowFixMe */ const TestRunner = require(config.testRunner); /* $FlowFixMe */ @@ -39,7 +63,7 @@ function runTest(path: Path, config: Config, resolver: Resolver) { (type, message) => getConsoleOutput( config.rootDir, !!config.verbose, - // 4 = the console call is burried 4 stack frames deep + // 4 = the console call is buried 4 stack frames deep BufferedConsole.write([], type, message, 4), ), ); diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index ed59352bb8b3..c59950bb1921 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -15,6 +15,7 @@ const loadFromFile = require('./loadFromFile'); const loadFromPackage = require('./loadFromPackage'); const normalize = require('./normalize'); const setFromArgv = require('./setFromArgv'); +const {getTestEnvironment} = require('./utils'); const readConfig = (argv: Object, packageRoot: string) => readRawConfig(argv, packageRoot) @@ -60,6 +61,7 @@ const readRawConfig = (argv, root) => { }; module.exports = { + getTestEnvironment, normalize, readConfig, };