Skip to content

Commit

Permalink
Deprecate stubbing sandbox value in favor of value behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfcosta committed May 21, 2017
1 parent dbefd45 commit c89fb21
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 7 deletions.
12 changes: 5 additions & 7 deletions lib/sinon/collection.js
Expand Up @@ -3,9 +3,8 @@
var sinonSpy = require("./spy");
var sinonStub = require("./stub");
var sinonMock = require("./mock");
var throwOnFalsyObject = require("./throw-on-falsy-object");
var sandboxStub = require("./sandbox-stub");
var collectOwnMethods = require("./collect-own-methods");
var stubNonFunctionProperty = require("./stub-non-function-property");

var push = [].push;

Expand Down Expand Up @@ -81,13 +80,12 @@ var collection = {
},

stub: function stub(object, property/*, value*/) {
throwOnFalsyObject.apply(null, arguments);
if (arguments.length > 2) {
return sandboxStub.apply(this, arguments);
}

var stubbed = sinonStub.apply(null, arguments);
var isStubbingEntireObject = typeof property === "undefined" && typeof object === "object";
var isStubbingNonFunctionProperty = property && typeof object[property] !== "function";
var stubbed = isStubbingNonFunctionProperty ?
stubNonFunctionProperty.apply(null, arguments) :
sinonStub.apply(null, arguments);

if (isStubbingEntireObject) {
var ownMethods = collectOwnMethods(stubbed);
Expand Down
19 changes: 19 additions & 0 deletions lib/sinon/default-behaviors.js
@@ -1,4 +1,5 @@
"use strict";
var getPropertyDescriptor = require("./util/core/get-property-descriptor");

var slice = [].slice;
var useLeftMostCallback = -1;
Expand Down Expand Up @@ -186,6 +187,24 @@ module.exports = {
set: setterFunction
});

return fake;
},

value: function value(fake, newVal) {
var rootStub = fake.stub || fake;

var oldVal = getPropertyDescriptor(rootStub.rootObj, rootStub.propName).value;

Object.defineProperty(rootStub.rootObj, rootStub.propName, {
value: newVal
});

fake.restore = function restore() {
Object.defineProperty(rootStub.rootObj, rootStub.propName, {
value: oldVal
});
};

return fake;
}
};
Expand Down
51 changes: 51 additions & 0 deletions lib/sinon/sandbox-stub.js
@@ -0,0 +1,51 @@
"use strict";

var collectOwnMethods = require("./collect-own-methods");
var deprecated = require("./util/core/deprecated");
var getPropertyDescriptor = require("./util/core/get-property-descriptor");
var stubNonFunctionProperty = require("./stub-non-function-property");
var sinonStub = require("./stub");
var throwOnFalsyObject = require("./throw-on-falsy-object");

// This is deprecated and will be removed in a future version of sinon.
// We will only consider pull requests that fix serious bugs in the implementation
function sandboxStub(object, property/*, value*/) {
deprecated.printWarning(
"sandbox.stub(obj, 'meth', val) is deprecated and will be removed from " +
"the public API in a future version of sinon." +
"\n Use sandbox(obj, 'meth').callsFake(fn) instead in order to stub a function." +
"\n Use sandbox(obj, 'meth').value(fn) instead in order to stub a non-function value."
);

throwOnFalsyObject.apply(null, arguments);

var actualDescriptor = getPropertyDescriptor(object, property);
var isStubbingEntireObject = typeof property === "undefined" && typeof object === "object";
var isStubbingNonFuncProperty = typeof object === "object"
&& typeof property !== "undefined"
&& (typeof actualDescriptor === "undefined"
|| typeof actualDescriptor.value !== "function");


// When passing a value as third argument it will be applied to stubNonFunctionProperty
var stubbed = isStubbingNonFuncProperty ?
stubNonFunctionProperty.apply(null, arguments) :
sinonStub.apply(null, arguments);

if (isStubbingEntireObject) {
var ownMethods = collectOwnMethods(stubbed);
ownMethods.forEach(this.add.bind(this));
if (this.promiseLibrary) {
ownMethods.forEach(this.addUsingPromise.bind(this));
}
} else {
this.add(stubbed);
if (this.promiseLibrary) {
stubbed.usingPromise(this.promiseLibrary);
}
}

return stubbed;
}

module.exports = sandboxStub;
62 changes: 62 additions & 0 deletions test/sandbox-test.js
Expand Up @@ -548,4 +548,66 @@ describe("sinonSandbox", function () {
sandbox.restore();
});
});

describe("getters and setters", function () {
it("allows stubbing getters", function () {
var object = {
foo: "bar"
};

var sandbox = sinonSandbox.create();
sandbox.stub(object, "foo").get(function () {
return "baz";
});

assert.equals(object.foo, "baz");
});

it("allows restoring getters", function () {
var object = {
foo: "bar"
};

var sandbox = sinonSandbox.create();
sandbox.stub(object, "foo").get(function () {
return "baz";
});

sandbox.restore();

assert.equals(object.foo, "bar");
});

it("allows stubbing setters", function () {
var object = {
prop: "bar"
};

var sandbox = sinonSandbox.create();
sandbox.stub(object, "foo").set(function (val) {
object.prop = val + "bla";
});

object.foo = "bla";

assert.equals(object.prop, "blabla");
});

it("allows restoring setters", function () {
var object = {
prop: "bar"
};

var sandbox = sinonSandbox.create();
sandbox.stub(object, "prop").set(function setterFn(val) {
object.prop = val + "bla";
});

sandbox.restore();

object.prop = "bla";

assert.equals(object.prop, "bla");
});
});
});
22 changes: 22 additions & 0 deletions test/stub-test.js
Expand Up @@ -2524,4 +2524,26 @@ describe("stub", function () {
assert.equals(myObj.otherProp, "bar");
});
});

describe(".value", function () {
it("allows stubbing property descriptor values", function () {
var myObj = {
prop: "rawString"
};

createStub(myObj, "prop").value("newString");
assert.equals(myObj.prop, "newString");
});

it("allows restoring stubbed property descriptor values", function () {
var myObj = {
prop: "rawString"
};

var stub = createStub(myObj, "prop").value("newString");
stub.restore();

assert.equals(myObj.prop, "rawString");
});
});
});

3 comments on commit c89fb21

@StefanSchoof
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the deprecation message missing a .stub?

"\n Use sandbox.stub(obj, 'meth').callsFake(fn) instead in order to stub a function." +
"\n Use sandbox.stub(obj, 'meth').value(fn) instead in order to stub a non-function value."

@fatso83
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are right, Stefan. Feel free to supply us with a patch :-)

@StefanSchoof
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is the patch: #1440

Please sign in to comment.