From 0566325cf1001ea4d4de4554a952a93eeef4c447 Mon Sep 17 00:00:00 2001 From: Gil Tayar Date: Fri, 27 Jan 2017 14:57:09 +0200 Subject: [PATCH] Fixed #1314: yielding a function should not call the function (#1315) * Fixed #1314: yielding a function should not call the function When rejecting a non-promise value, string.replace is used, and the value is passed as second parameter. But string.replace, if the second value is a function, will call that function. This commit fixes this by using value.toString(). * changed how value is converted to string in error about yielding non-promises --- src/generators.js | 2 +- test/mocha/generator.js | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/generators.js b/src/generators.js index f0660884e..2e6029c03 100644 --- a/src/generators.js +++ b/src/generators.js @@ -160,7 +160,7 @@ PromiseSpawn.prototype._continue = function (result) { if (maybePromise === null) { this._promiseRejected( new TypeError( - YIELDED_NON_PROMISE_ERROR.replace("%s", value) + + YIELDED_NON_PROMISE_ERROR.replace("%s", String(value)) + FROM_COROUTINE_CREATED_AT + this._stack.split("\n").slice(1, -7).join("\n") ) diff --git a/test/mocha/generator.js b/test/mocha/generator.js index 2b056186b..eac2d7cb9 100644 --- a/test/mocha/generator.js +++ b/test/mocha/generator.js @@ -82,6 +82,22 @@ describe("yielding", function() { assert.equal(val, 4); }); }); + + specify("yielding a function should not call the function", function() { + let functionWasCalled = false; + return Promise.coroutine(function*(){ + try { + yield (function() {functionWasCalled = true;}); + } + catch(e){ + assert(e instanceof TypeError); + assert.equal(functionWasCalled, false); + return 4; + } + })().then(function(val){ + assert.equal(val, 4); + }); + }); }); describe("thenables", function(){ @@ -367,7 +383,7 @@ describe("Spawn", function() { describe("custom yield handlers", function() { specify("should work with timers", function() { var n = 0; - return Promise.coroutine.addYieldHandler(function(v) { + Promise.coroutine.addYieldHandler(function(v) { if (typeof v === "number") { n = 1; return Promise.resolve(n); @@ -417,18 +433,18 @@ describe("custom yield handlers", function() { }); }); - Promise.coroutine.addYieldHandler(function(v) { - if (typeof v === "function") { - var cb; - var promise = Promise.fromNode(function(callback) { - cb = callback; - }); - try { v(cb); } catch (e) { cb(e); } - return promise; - } - }); - specify("should work with thunks", function(){ + Promise.coroutine.addYieldHandler(function(v) { + if (typeof v === "function") { + var cb; + var promise = Promise.fromNode(function(callback) { + cb = callback; + }); + try { v(cb); } catch (e) { cb(e); } + return promise; + } + }); + var thunk = function(a) { return function(callback) { setTimeout(function(){