From a79ccaeb20bbb558902ae77b20bd026719de3004 Mon Sep 17 00:00:00 2001 From: bojavou <134245276+bojavou@users.noreply.github.com> Date: Tue, 20 Jun 2023 08:41:36 -0600 Subject: [PATCH] Support callable instances (#2517) * Support callable instances * Clean prettier lint --------- Co-authored-by: - <-> --- lib/sinon/proxy-invoke.js | 5 ++++- test/proxy-call-test.js | 42 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/sinon/proxy-invoke.js b/lib/sinon/proxy-invoke.js index 844f461d0..4c9c29f0a 100644 --- a/lib/sinon/proxy-invoke.js +++ b/lib/sinon/proxy-invoke.js @@ -43,7 +43,10 @@ module.exports = function invoke(func, thisValue, args) { concat([thisValue], args) ))(); - if (typeof returnValue !== "object") { + if ( + typeof returnValue !== "object" && + typeof returnValue !== "function" + ) { returnValue = thisValue; } } else { diff --git a/test/proxy-call-test.js b/test/proxy-call-test.js index 5dbf902da..8cbec51ca 100644 --- a/test/proxy-call-test.js +++ b/test/proxy-call-test.js @@ -1246,6 +1246,48 @@ describe("sinonSpy.call", function () { }); }); + describe("constructor return", function () { + it("preserves returned object", function () { + const customReturn = {}; + function CustomConstructor() { + return customReturn; + } + const SpiedCustomConstructor = sinonSpy(CustomConstructor); + const myInstance = new SpiedCustomConstructor(); + + assert(myInstance === customReturn); + }); + + it("allows explicit returned object", function () { + const StubConstructor = sinonStub(); + const customReturn = {}; + StubConstructor.returns(customReturn); + const myInstance = new StubConstructor(); + + assert(myInstance === customReturn); + }); + + it("preserves returned function", function () { + function customReturn() {} // eslint-disable-line no-empty-function + function CustomConstructor() { + return customReturn; + } + const SpiedCustomConstructor = sinonSpy(CustomConstructor); + const myInstance = new SpiedCustomConstructor(); + + assert(myInstance === customReturn); + }); + + it("allows explicit returned function", function () { + const StubConstructor = sinonStub(); + function customReturn() {} // eslint-disable-line no-empty-function + StubConstructor.returns(customReturn); + const myInstance = new StubConstructor(); + + assert(myInstance === customReturn); + }); + }); + describe("functions", function () { it("throws if spying on non-existent property", function () { const myObj = {};