diff --git a/CHANGELOG.md b/CHANGELOG.md index 8caaba089165..174677949fb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,5 @@ ## master -None for now - ### Fixes * `[babel-jest]` moduleFileExtensions not passed to babel transformer. @@ -9,6 +7,9 @@ None for now ### Features +* `[jest-jasmine2]` Support generator functions as specs. + ([#5166](https://github.com/facebook/jest/pull/5166)) + ### Chore & Maintenance ## jest 22.0.1 diff --git a/docs/GlobalAPI.md b/docs/GlobalAPI.md index b4d17d4167a2..173052c3d21a 100644 --- a/docs/GlobalAPI.md +++ b/docs/GlobalAPI.md @@ -17,7 +17,8 @@ environment. You don't have to require or import anything to use them. ### `afterAll(fn, timeout)` Runs a function after all the tests in this file have completed. If the function -returns a promise, Jest waits for that promise to resolve before continuing. +returns a promise or is a generator, Jest waits for that promise to resolve +before continuing. Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ @@ -63,8 +64,8 @@ If you want to run some cleanup after every test instead of after all tests, use ### `afterEach(fn, timeout)` Runs a function after each one of the tests in this file completes. If the -function returns a promise, Jest waits for that promise to resolve before -continuing. +function returns a promise or is a generator, Jest waits for that promise to +resolve before continuing. Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ @@ -110,7 +111,8 @@ If you want to run some cleanup just once, after all of the tests run, use ### `beforeAll(fn, timeout)` Runs a function before any of the tests in this file run. If the function -returns a promise, Jest waits for that promise to resolve before running tests. +returns a promise or is a generator, Jest waits for that promise to resolve +before running tests. Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ @@ -154,8 +156,8 @@ use `beforeEach` instead. ### `beforeEach(fn, timeout)` Runs a function before each of the tests in this file runs. If the function -returns a promise, Jest waits for that promise to resolve before running the -test. +returns a promise or is a generator, Jest waits for that promise to resolve +before running the test. Optionally, you can provide a `timeout` (in milliseconds) for specifying how long to wait before aborting. _Note: The default timeout is 5 seconds._ diff --git a/integration_tests/__tests__/jasmine_async.test.js b/integration_tests/__tests__/jasmine_async.test.js index ba5e40af88e9..52ef3763f5c9 100644 --- a/integration_tests/__tests__/jasmine_async.test.js +++ b/integration_tests/__tests__/jasmine_async.test.js @@ -141,4 +141,10 @@ describe('async jasmine', () => { expect.stringContaining('Expected value to be truthy, instead received'), ); }); + + it('generator test', () => { + const result = runJest('jasmine_async', ['generator.test.js']); + + expect(result.status).toBe(0); + }); }); diff --git a/integration_tests/jasmine_async/__tests__/generator.test.js b/integration_tests/jasmine_async/__tests__/generator.test.js new file mode 100644 index 000000000000..d74ddf32326b --- /dev/null +++ b/integration_tests/jasmine_async/__tests__/generator.test.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +function* someFunc() { + return 3; +} + +describe('generators', () => { + beforeEach(function*() { + // This shouldn't throw + yield someFunc(); + }); + + it('in spec', function*() { + const data = yield someFunc(); + + expect(data).toBe(3); + }); +}); diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index e2380a777df7..c23969a21073 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -10,8 +10,10 @@ "dependencies": { "callsites": "^2.0.0", "chalk": "^2.0.1", + "co": "^4.6.0", "expect": "^22.0.3", "graceful-fs": "^4.1.11", + "is-generator-fn": "^1.0.0", "jest-diff": "^22.0.3", "jest-matcher-utils": "^22.0.3", "jest-message-util": "^22.0.3", diff --git a/packages/jest-jasmine2/src/jasmine_async.js b/packages/jest-jasmine2/src/jasmine_async.js index 15b20e551c21..1f04efde23bc 100644 --- a/packages/jest-jasmine2/src/jasmine_async.js +++ b/packages/jest-jasmine2/src/jasmine_async.js @@ -14,6 +14,9 @@ import type {Global} from 'types/Global'; +import isGeneratorFn from 'is-generator-fn'; +import co from 'co'; + function isPromise(obj) { return obj && typeof obj.then === 'function'; } @@ -34,7 +37,8 @@ function promisifyLifeCycleFunction(originalFn, env) { // We make *all* functions async and run `done` right away if they // didn't return a promise. const asyncFn = function(done) { - const returnValue = fn.call({}); + const wrappedFn = isGeneratorFn(fn) ? co.wrap(fn) : fn; + const returnValue = wrappedFn.call({}); if (isPromise(returnValue)) { returnValue.then(done.bind(null, null), done.fail); @@ -64,7 +68,8 @@ function promisifyIt(originalFn, env) { } const asyncFn = function(done) { - const returnValue = fn.call({}); + const wrappedFn = isGeneratorFn(fn) ? co.wrap(fn) : fn; + const returnValue = wrappedFn.call({}); if (isPromise(returnValue)) { returnValue.then(done.bind(null, null), done.fail); diff --git a/yarn.lock b/yarn.lock index 2481484a64ad..819273fc414e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3988,6 +3988,10 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"