diff --git a/docs/Configuration.md b/docs/Configuration.md index 6755ecd34690..3734a9a32e8d 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -318,7 +318,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 `@testEnvironment` pragma. + +```js +/** + * @testEnvironment 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..935600b88e07 --- /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 pragma', () => { + 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..38704f8b6e78 --- /dev/null +++ b/integration_tests/test-environment/__tests__/env-test.js @@ -0,0 +1,15 @@ +/** + * 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. + * + * @testEnvironment jsdom + */ +/* 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 8e9f6698d207..c9fb2343ec38 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -14,6 +14,7 @@ "istanbul-lib-instrument": "^1.1.1", "jest-changed-files": "^19.0.2", "jest-config": "^19.0.2", + "jest-docblock": "^19.0.0", "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 19027e4f679a..462bc85f6d13 100644 --- a/packages/jest-cli/src/runTest.js +++ b/packages/jest-cli/src/runTest.js @@ -19,11 +19,34 @@ const { NullConsole, setGlobal, } = require('jest-util'); + +const fs = require('fs'); +const docblock = require('jest-docblock'); +const {getTestEnvironment} = require('jest-config'); const getConsoleOutput = require('./reporters/getConsoleOutput'); function runTest(path: Path, config: Config, resolver: Resolver) { + let data; + + try { + data = fs.readFileSync(path, 'utf8'); + } catch (e) { + return Promise.reject(e); + } + let testEnvironment = config.testEnvironment; + + const testEnvironmentPragma = docblock.parse(docblock.extract(data)); + + if (testEnvironmentPragma.testEnvironment) { + testEnvironment = getTestEnvironment( + Object.assign({}, config, { + testEnvironment: testEnvironmentPragma.testEnvironment, + }) + ); + } + /* $FlowFixMe */ - const TestEnvironment = require(config.testEnvironment); + const TestEnvironment = require(testEnvironment); /* $FlowFixMe */ const TestRunner = require(config.testRunner); /* $FlowFixMe */ @@ -36,14 +59,14 @@ function runTest(path: Path, config: Config, resolver: Resolver) { : (config.silent ? NullConsole : BufferedConsole - ); + ); const testConsole = new TestConsole( config.useStderr ? process.stderr : process.stdout, process.stderr, (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, };