From 41ebd5d0a790089861f65ffd212d666884bfe8b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bazyli=20Brzo=CC=81ska?= Date: Mon, 30 Apr 2018 22:50:54 +0200 Subject: [PATCH] feat(jest-jasmine2): introduce legacyExecutionOrder flag to enable undocumented execution order We do not set the currentDeclarationSuite upon node start in order to keep a legacy, undocumented ordering of beforeEach execution. Specifically, this applies to beforeEach that were added inside of tests. Facebook depends on this behavior internally (see #5964 for discussion) Also: Added type of CreateOptions in jasmine_light --- .../__snapshots__/before-each-queue.js.snap | 21 ++++++++++++++++++- .../__snapshots__/failures.test.js.snap | 2 +- .../__snapshots__/show_config.test.js.snap | 1 + .../__tests__/before-each-queue.js | 9 ++++++-- .../__tests__/before-each-queue.test.js | 0 .../with-legacy-execution-order/package.json | 5 +++++ .../__tests__/before-each-queue.test.js | 21 +++++++++++++++++++ .../package.json | 0 packages/jest-config/src/defaults.js | 1 + packages/jest-config/src/index.js | 1 + packages/jest-config/src/normalize.js | 1 + packages/jest-config/src/valid_config.js | 1 + packages/jest-jasmine2/src/index.js | 1 + packages/jest-jasmine2/src/jasmine/Env.js | 8 ++++++- .../src/jasmine/jasmine_light.js | 8 ++++++- packages/jest-jasmine2/src/tree_processor.js | 7 +------ types/Config.js | 3 +++ 17 files changed, 78 insertions(+), 12 deletions(-) rename integration-tests/before-each-queue/{ => with-legacy-execution-order}/__tests__/before-each-queue.test.js (100%) create mode 100644 integration-tests/before-each-queue/with-legacy-execution-order/package.json create mode 100644 integration-tests/before-each-queue/without-legacy-execution-order/__tests__/before-each-queue.test.js rename integration-tests/before-each-queue/{ => without-legacy-execution-order}/package.json (100%) diff --git a/integration-tests/__tests__/__snapshots__/before-each-queue.js.snap b/integration-tests/__tests__/__snapshots__/before-each-queue.js.snap index 030491cd1f2d..cbc621db9e34 100644 --- a/integration-tests/__tests__/__snapshots__/before-each-queue.js.snap +++ b/integration-tests/__tests__/__snapshots__/before-each-queue.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Correct beforeEach order ensures the correct order for beforeEach 1`] = ` +exports[`Correct beforeEach order ensures the correct order for beforeEach with legacyExecutionOrder flag 1`] = ` " console.log __tests__/before-each-queue.test.js:3 BeforeEach @@ -18,3 +18,22 @@ exports[`Correct beforeEach order ensures the correct order for beforeEach 1`] = " `; + +exports[`Correct beforeEach order ensures the correct order for beforeEach without legacyExecutionOrder flag 1`] = ` +" console.log __tests__/before-each-queue.test.js:3 + BeforeEach + + console.log __tests__/before-each-queue.test.js:7 + It Foo + + console.log __tests__/before-each-queue.test.js:3 + BeforeEach + + console.log __tests__/before-each-queue.test.js:10 + BeforeEach Inline Foo + + console.log __tests__/before-each-queue.test.js:15 + It Bar + +" +`; diff --git a/integration-tests/__tests__/__snapshots__/failures.test.js.snap b/integration-tests/__tests__/__snapshots__/failures.test.js.snap index a225e1118c9b..085386f2d5b5 100644 --- a/integration-tests/__tests__/__snapshots__/failures.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/failures.test.js.snap @@ -247,7 +247,7 @@ exports[`not throwing Error objects 5`] = ` 37 | }); 38 | - at packages/jest-jasmine2/build/jasmine/Env.js:542:34 + at packages/jest-jasmine2/build/jasmine/Env.js:558:34 at __tests__/during_tests.test.js:36:3 " diff --git a/integration-tests/__tests__/__snapshots__/show_config.test.js.snap b/integration-tests/__tests__/__snapshots__/show_config.test.js.snap index 01f890657c16..32c88da5049e 100644 --- a/integration-tests/__tests__/__snapshots__/show_config.test.js.snap +++ b/integration-tests/__tests__/__snapshots__/show_config.test.js.snap @@ -19,6 +19,7 @@ exports[`--showConfig outputs config info and exits 1`] = ` \\"haste\\": { \\"providesModuleNodeModules\\": [] }, + \\"legacyExecutionOrder\\": false, \\"moduleDirectories\\": [ \\"node_modules\\" ], diff --git a/integration-tests/__tests__/before-each-queue.js b/integration-tests/__tests__/before-each-queue.js index ad352b0f269a..98ab95236fde 100644 --- a/integration-tests/__tests__/before-each-queue.js +++ b/integration-tests/__tests__/before-each-queue.js @@ -11,8 +11,13 @@ const runJest = require('../runJest'); describe('Correct beforeEach order', () => { - it('ensures the correct order for beforeEach', () => { - const result = runJest('before-each-queue'); + it('ensures the correct order for beforeEach with legacyExecutionOrder flag', () => { + const result = runJest('before-each-queue/with-legacy-execution-order'); + expect(result.stdout).toMatchSnapshot(); + }); + + it('ensures the correct order for beforeEach without legacyExecutionOrder flag', () => { + const result = runJest('before-each-queue/without-legacy-execution-order'); expect(result.stdout).toMatchSnapshot(); }); }); diff --git a/integration-tests/before-each-queue/__tests__/before-each-queue.test.js b/integration-tests/before-each-queue/with-legacy-execution-order/__tests__/before-each-queue.test.js similarity index 100% rename from integration-tests/before-each-queue/__tests__/before-each-queue.test.js rename to integration-tests/before-each-queue/with-legacy-execution-order/__tests__/before-each-queue.test.js diff --git a/integration-tests/before-each-queue/with-legacy-execution-order/package.json b/integration-tests/before-each-queue/with-legacy-execution-order/package.json new file mode 100644 index 000000000000..7d9227473bfa --- /dev/null +++ b/integration-tests/before-each-queue/with-legacy-execution-order/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "legacyExecutionOrder": true + } +} diff --git a/integration-tests/before-each-queue/without-legacy-execution-order/__tests__/before-each-queue.test.js b/integration-tests/before-each-queue/without-legacy-execution-order/__tests__/before-each-queue.test.js new file mode 100644 index 000000000000..8f49fe124c27 --- /dev/null +++ b/integration-tests/before-each-queue/without-legacy-execution-order/__tests__/before-each-queue.test.js @@ -0,0 +1,21 @@ +describe('test', () => { + beforeEach(() => { + console.log('BeforeEach'); + }); + + it('foo', () => { + console.log('It Foo'); + + beforeEach(() => { + console.log('BeforeEach Inline Foo'); + }); + }); + + it('bar', () => { + console.log('It Bar'); + + beforeEach(() => { + console.log('BeforeEach Inline Bar'); + }); + }); +}); diff --git a/integration-tests/before-each-queue/package.json b/integration-tests/before-each-queue/without-legacy-execution-order/package.json similarity index 100% rename from integration-tests/before-each-queue/package.json rename to integration-tests/before-each-queue/without-legacy-execution-order/package.json diff --git a/packages/jest-config/src/defaults.js b/packages/jest-config/src/defaults.js index 20f1c7ddcbb5..4f44bc90c476 100644 --- a/packages/jest-config/src/defaults.js +++ b/packages/jest-config/src/defaults.js @@ -47,6 +47,7 @@ export default ({ haste: { providesModuleNodeModules: [], }, + legacyExecutionOrder: false, moduleDirectories: ['node_modules'], moduleFileExtensions: ['js', 'json', 'jsx', 'node'], moduleNameMapper: {}, diff --git a/packages/jest-config/src/index.js b/packages/jest-config/src/index.js index e3e206172738..f6feec0290cd 100644 --- a/packages/jest-config/src/index.js +++ b/packages/jest-config/src/index.js @@ -159,6 +159,7 @@ const getConfigs = ( forceCoverageMatch: options.forceCoverageMatch, globals: options.globals, haste: options.haste, + legacyExecutionOrder: options.legacyExecutionOrder, moduleDirectories: options.moduleDirectories, moduleFileExtensions: options.moduleFileExtensions, moduleLoader: options.moduleLoader, diff --git a/packages/jest-config/src/normalize.js b/packages/jest-config/src/normalize.js index 79010175d8e8..fd2c4d0265e8 100644 --- a/packages/jest-config/src/normalize.js +++ b/packages/jest-config/src/normalize.js @@ -512,6 +512,7 @@ export default function normalize(options: InitialOptions, argv: Argv) { case 'forceCoverageMatch': case 'forceExit': case 'lastCommit': + case 'legacyExecutionOrder': case 'listTests': case 'logHeapUsage': case 'mapCoverage': diff --git a/packages/jest-config/src/valid_config.js b/packages/jest-config/src/valid_config.js index 75e30f6365e9..1880bfbfd93a 100644 --- a/packages/jest-config/src/valid_config.js +++ b/packages/jest-config/src/valid_config.js @@ -49,6 +49,7 @@ export default ({ }, json: false, lastCommit: false, + legacyExecutionOrder: false, logHeapUsage: true, moduleDirectories: ['node_modules'], moduleFileExtensions: ['js', 'json', 'jsx', 'node'], diff --git a/packages/jest-jasmine2/src/index.js b/packages/jest-jasmine2/src/index.js index 9f144d349a9f..370c52c9ae06 100644 --- a/packages/jest-jasmine2/src/index.js +++ b/packages/jest-jasmine2/src/index.js @@ -38,6 +38,7 @@ async function jasmine2( ); const jasmineFactory = runtime.requireInternalModule(JASMINE); const jasmine = jasmineFactory.create({ + legacyExecutionOrder: config.legacyExecutionOrder, process, testPath, }); diff --git a/packages/jest-jasmine2/src/jasmine/Env.js b/packages/jest-jasmine2/src/jasmine/Env.js index f73c1745065b..26f370ac4af5 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.js +++ b/packages/jest-jasmine2/src/jasmine/Env.js @@ -252,7 +252,13 @@ export default function(j$) { } }, nodeStart(suite) { - currentDeclarationSuite = suite; + if (!j$.legacyExecutionOrder) { + // We do not set the currentDeclarationSuite upon node start + // in order to keep a legacy, undocumented ordering of beforeEach execution. + // Specifically, this applies to beforeEach that were added inside of tests. + // Facebook depends on this behavior internally (see #5964 for discussion) + currentDeclarationSuite = suite; + } currentlyExecutingSuites.push(suite); defaultResourcesForRunnable( suite.id, diff --git a/packages/jest-jasmine2/src/jasmine/jasmine_light.js b/packages/jest-jasmine2/src/jasmine/jasmine_light.js index b0113aa03913..4b2ca882cc56 100644 --- a/packages/jest-jasmine2/src/jasmine/jasmine_light.js +++ b/packages/jest-jasmine2/src/jasmine/jasmine_light.js @@ -42,7 +42,13 @@ import SpyRegistry from './spy_registry'; import Suite from './Suite'; import Timer from './Timer'; -exports.create = function(createOptions: Object) { +type CreateOptions = {| + legacyExecutionOrder: boolean, + process: typeof process, + testPath: string, +|}; + +exports.create = function(createOptions: CreateOptions) { const j$ = Object.assign({}, createOptions); j$.DEFAULT_TIMEOUT_INTERVAL = 5000; diff --git a/packages/jest-jasmine2/src/tree_processor.js b/packages/jest-jasmine2/src/tree_processor.js index 9bea3c4db383..0ebcc01a59da 100644 --- a/packages/jest-jasmine2/src/tree_processor.js +++ b/packages/jest-jasmine2/src/tree_processor.js @@ -57,16 +57,11 @@ export default function treeProcessor(options: Options) { } function getNodeWithChildrenHandler(node: TreeNode, enabled: boolean) { - // NOTE: We create the array of queueableFns preemptively, - // in order to keep a legacy, undocumented ordering of beforeEach execution. - // Specifically, this applies to beforeEach that were added inside of tests. - // Facebook depends on this behavior internally (see #5964 for discussion) - const queueableFns = wrapChildren(node, enabled); return async function fn(done: (error?: any) => void = () => {}) { nodeStart(node); await queueRunnerFactory({ onException: error => node.onException(error), - queueableFns, + queueableFns: wrapChildren(node, enabled), userContext: node.sharedUserContext(), }); nodeComplete(node); diff --git a/types/Config.js b/types/Config.js index de8b5ff9edb4..2b4068431282 100644 --- a/types/Config.js +++ b/types/Config.js @@ -37,6 +37,7 @@ export type DefaultOptions = {| globals: ConfigGlobals, globalSetup: ?string, globalTeardown: ?string, + legacyExecutionOrder: boolean, haste: HasteConfig, detectLeaks: boolean, moduleDirectories: Array, @@ -99,6 +100,7 @@ export type InitialOptions = { globals?: ConfigGlobals, globalSetup?: ?string, globalTeardown?: ?string, + legacyExecutionOrder?: boolean, haste?: HasteConfig, reporters?: Array, logHeapUsage?: boolean, @@ -231,6 +233,7 @@ export type ProjectConfig = {| forceCoverageMatch: Array, globals: ConfigGlobals, haste: HasteConfig, + legacyExecutionOrder: boolean, moduleDirectories: Array, moduleFileExtensions: Array, moduleLoader: Path,