diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js index 2a50a3cf..197929cb 100644 --- a/lib/jasmine-core/jasmine.js +++ b/lib/jasmine-core/jasmine.js @@ -244,6 +244,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return j$.isA_('AsyncFunction', value); }; + j$.isGeneratorFunction_ = function(value) { + return j$.isA_('GeneratorFunction', value); + }; + j$.isTypedArray_ = function(value) { return ( j$.isA_('Float32Array', value) || @@ -8308,7 +8312,13 @@ getJasmineRequireObj().SpyStrategy = function(j$) { * @param {Function} fn The function to invoke with the passed parameters. */ SpyStrategy.prototype.callFake = function(fn) { - if (!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) { + if ( + !( + j$.isFunction_(fn) || + j$.isAsyncFunction_(fn) || + j$.isGeneratorFunction_(fn) + ) + ) { throw new Error( 'Argument passed to callFake should be a function, got ' + fn ); diff --git a/spec/core/SpyStrategySpec.js b/spec/core/SpyStrategySpec.js index 76a3a1e2..85624083 100644 --- a/spec/core/SpyStrategySpec.js +++ b/spec/core/SpyStrategySpec.js @@ -334,6 +334,17 @@ describe('SpyStrategy', function() { }).toThrowError(/^Argument passed to callFake should be a function, got/); }); + it('allows generator functions to be passed to callFake strategy', function() { + jasmine.getEnv().requireGeneratorFunctions(); + + var generator = jasmine.getEnv().makeGeneratorFunction('yield "ok";'), + spyStrategy = new jasmineUnderTest.SpyStrategy({ fn: function() {} }); + + spyStrategy.callFake(generator); + + expect(spyStrategy.exec().next().value).toEqual('ok'); + }); + it('allows a return to plan stubbing after another strategy', function() { var originalFn = jasmine.createSpy('original'), fakeFn = jasmine.createSpy('fake').and.returnValue(67), diff --git a/spec/helpers/generator.js b/spec/helpers/generator.js new file mode 100644 index 00000000..b62f5acd --- /dev/null +++ b/spec/helpers/generator.js @@ -0,0 +1,22 @@ +(function(env) { + function getGeneratorFuncCtor() { + try { + eval('var func = function*() {}'); + } catch (e) { + return null; + } + + return Object.getPrototypeOf(func).constructor; + } + + env.makeGeneratorFunction = function(text) { + var GeneratorFunction = getGeneratorFuncCtor(); + return new GeneratorFunction(text || ''); + }; + + env.requireGeneratorFunctions = function() { + if (!getGeneratorFuncCtor()) { + env.pending('Environment does not support generator functions'); + } + }; +})(jasmine.getEnv()); diff --git a/spec/support/jasmine-browser.js b/spec/support/jasmine-browser.js index 61076dbb..2f5f7146 100644 --- a/spec/support/jasmine-browser.js +++ b/spec/support/jasmine-browser.js @@ -18,6 +18,7 @@ module.exports = { specFiles: ['**/*[Ss]pec.js', '!npmPackage/**/*'], helpers: [ 'helpers/asyncAwait.js', + 'helpers/generator.js', 'helpers/BrowserFlags.js', 'helpers/checkForMap.js', 'helpers/checkForSet.js', diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json index b48efde5..0276ca92 100644 --- a/spec/support/jasmine.json +++ b/spec/support/jasmine.json @@ -6,6 +6,7 @@ ], "helpers": [ "helpers/asyncAwait.js", + "helpers/generator.js", "helpers/checkForMap.js", "helpers/checkForSet.js", "helpers/checkForSymbol.js", diff --git a/src/core/SpyStrategy.js b/src/core/SpyStrategy.js index 41aa9258..382164b6 100644 --- a/src/core/SpyStrategy.js +++ b/src/core/SpyStrategy.js @@ -168,7 +168,13 @@ getJasmineRequireObj().SpyStrategy = function(j$) { * @param {Function} fn The function to invoke with the passed parameters. */ SpyStrategy.prototype.callFake = function(fn) { - if (!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) { + if ( + !( + j$.isFunction_(fn) || + j$.isAsyncFunction_(fn) || + j$.isGeneratorFunction_(fn) + ) + ) { throw new Error( 'Argument passed to callFake should be a function, got ' + fn ); diff --git a/src/core/base.js b/src/core/base.js index 121ff614..d02606d5 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -76,6 +76,10 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return j$.isA_('AsyncFunction', value); }; + j$.isGeneratorFunction_ = function(value) { + return j$.isA_('GeneratorFunction', value); + }; + j$.isTypedArray_ = function(value) { return ( j$.isA_('Float32Array', value) ||