Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/release-source/release/sandbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ A convenience reference for [`sinon.assert`](./assertions)

Works exactly like `sinon.spy`, only also adds the returned spy to the internal collection of fakes for easy restoring through `sandbox.restore()`

#### `sandbox.createStubInstance();`

Works almost exactly like `sinon.createStubInstance`, only also adds the returned stubs to the internal collection of fakes for easy restoring through `sandbox.restore()`.

#### `sandbox.stub();`

Expand Down
7 changes: 7 additions & 0 deletions lib/sinon/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ var collection = {
return this.add(sinonSpy.apply(sinonSpy, arguments));
},

createStubInstance: function createStubInstance(constructor) {
if (typeof constructor !== "function") {
throw new TypeError("The constructor should be a function.");
}
return this.stub.call(this, Object.create(constructor.prototype));
},

stub: function stub(object, property) {
if (object && typeof property !== "undefined"
&& !(property in object)) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"test-webworker": "browserify --no-commondir --full-paths -p [ mocaccino -R spec --color ] test/webworker/webworker-support-assessment.js | phantomic --web-security false",
"test": "run-s test-node test-headless test-webworker",
"check-dependencies": "dependency-check package.json --unused --no-dev",
"build": "./build.js",
"build": "node ./build.js",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change was necessary to run npm build or npm test locally on a Windows box. If it's inappropriate, then I'll happily revert this change.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fine. At some point we agreed that it was not a pre-requisite that the entire build process runs on Windows, as none of the maintainers were using it, but we are certainly not opposed to improving the situation :-)

"lint": "eslint .",
"precommit": "lint-staged",
"pretest-webworker": "npm run build",
Expand Down
91 changes: 91 additions & 0 deletions test/collection-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var sinonCollection = require("../lib/sinon/collection");
var sinonSpy = require("../lib/sinon/spy");
var sinonStub = require("../lib/sinon/stub");
var assert = referee.assert;
var refute = referee.refute;
var deprecated = require("../lib/sinon/util/core/deprecated");

describe("collection", function () {
Expand All @@ -18,6 +19,96 @@ describe("collection", function () {
assert.isFunction(collection.mock);
});

describe(".createStubInstance", function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These tests have largely been copied from stub-test.js.

beforeEach(function () {
this.collection = Object.create(sinonCollection);
});

it("stubs existing methods", function () {
var Class = function () {};
Class.prototype.method = function () {};

var stub = this.collection.createStubInstance(Class);
stub.method.returns(3);
assert.equals(3, stub.method());
});

it("resets all stub methods on reset()", function () {
var Class = function () {};
Class.prototype.method1 = function () {};
Class.prototype.method2 = function () {};
Class.prototype.method3 = function () {};

var stub = this.collection.createStubInstance(Class);
stub.method1.returns(1);
stub.method2.returns(2);
stub.method3.returns(3);

assert.equals(3, stub.method3());

this.collection.reset();
assert.equals(undefined, stub.method1());
assert.equals(undefined, stub.method2());
assert.equals(undefined, stub.method3());
});

it("doesn't stub fake methods", function () {
var Class = function () {};

var stub = this.collection.createStubInstance(Class);
assert.exception(function () {
stub.method.returns(3);
});
});

it("doesn't call the constructor", function () {
var Class = function (a, b) {
var c = a + b;
throw c;
};
Class.prototype.method = function () {};

var stub = this.collection.createStubInstance(Class);
refute.exception(function () {
stub.method(3);
});
});

it("retains non function values", function () {
var TYPE = "some-value";
var Class = function () {};
Class.prototype.type = TYPE;

var stub = this.collection.createStubInstance(Class);
assert.equals(TYPE, stub.type);
});

it("has no side effects on the prototype", function () {
var proto = {
method: function () {
throw "error";
}
};
var Class = function () {};
Class.prototype = proto;

var stub = this.collection.createStubInstance(Class);
refute.exception(stub.method);
assert.exception(proto.method);
});

it("throws exception for non function params", function () {
var types = [{}, 3, "hi!"];

for (var i = 0; i < types.length; i++) {
// yes, it's silly to create functions in a loop, it's also a test
assert.exception(function () { // eslint-disable-line no-loop-func
this.collection.createStubInstance(types[i]);
});
}
});
});

describe(".stub", function () {
beforeEach(function () {
this.collection = Object.create(sinonCollection);
Expand Down