New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

sinon-test

Package Overview
Dependencies
Maintainers
4
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sinon-test - npm Package Compare versions

Comparing version 0.0.1 to 1.0.0

AUTHORS

135

lib/test.js

@@ -13,3 +13,60 @@ /**

var slice = Array.prototype.slice;
var DEFAULT_CONFIG = {
injectIntoThis: true,
injectInto: null,
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
useFakeTimers: true,
useFakeServer: true
};
function finish(sandbox, error, dontThrow) {
if (error) {
sandbox.restore();
if (dontThrow) {
return;
}
throw error;
}
sandbox.verifyAndRestore();
}
function handleFn(sandbox, result) {
if (result && utils.isPromise(result)) {
return result.then(
function sinonHandlePromiseResolve(value) {
finish(sandbox);
return value;
},
function sinonHandlePromiseReject(error) {
finish(
sandbox,
error || new Error("Promise rejected with no/falsy error")
);
}
);
}
finish(sandbox);
return result;
}
function handleAsyncFn(sandbox, result, isAsync) {
if (result && utils.isPromise(result)) {
finish(sandbox, new Error(
"Your test should take a callback *or* return a promise. "
+ "It should not do both."
));
}
// the function had an arity of 1 or more, but it was not passed a callback
if (!isAsync) {
finish(sandbox);
}
}
function configure(sinon, config) {

@@ -20,10 +77,23 @@ if (!utils.isSinon(sinon)) {

if (!config) {
config = {
injectIntoThis: true,
injectInto: null,
properties: ["spy", "stub", "mock", "clock", "server", "requests"],
useFakeTimers: true,
useFakeServer: true
};
function callSandboxedFn(context, args, fn, handler) {
config = sinon.getConfig(config || DEFAULT_CONFIG);
config.injectInto = config.injectIntoThis && context || config.injectInto;
var sandbox = sinon.sandbox.create(config);
var done = args.length && args[args.length - 1];
var result;
if (typeof done === "function") {
args[args.length - 1] = function sinonDone(error) {
finish(sandbox, error, true);
done(error);
};
}
try {
result = fn.apply(context, args.concat(sandbox.args));
} catch (e) {
finish(sandbox, e);
}
return handler(sandbox, result, typeof done === "function");
}

@@ -38,47 +108,10 @@

function sinonSandboxedTest() {
config = sinon.getConfig(config);
config.injectInto = config.injectIntoThis && this || config.injectInto;
var sandbox = sinon.sandbox.create(config);
var args = slice.call(arguments);
var oldDone = args.length && args[args.length - 1];
var exception, result;
if (typeof oldDone === "function") {
args[args.length - 1] = function sinonDone(res) {
if (res) {
sandbox.restore();
} else {
sandbox.verifyAndRestore();
}
oldDone(res);
};
return callback.length
? function sinonAsyncSandboxedTest(_) { // eslint-disable-line no-unused-vars
return callSandboxedFn(this, slice.call(arguments), callback, handleAsyncFn);
}
try {
result = callback.apply(this, args.concat(sandbox.args));
} catch (e) {
exception = e;
: function sinonSandboxedTest() {
return callSandboxedFn(this, slice.call(arguments), callback, handleFn);
}
if (typeof oldDone !== "function") {
if (typeof exception !== "undefined") {
sandbox.restore();
throw exception;
} else {
sandbox.verifyAndRestore();
}
}
return result;
}
if (callback.length) {
return function sinonAsyncSandboxedTest(done) { // eslint-disable-line no-unused-vars
return sinonSandboxedTest.apply(this, arguments);
};
}
return sinonSandboxedTest;
;
};

@@ -85,0 +118,0 @@ }

@@ -11,2 +11,6 @@ /**

exports.isPromise = function (object) {
return typeof object === "object" && typeof object.then === "function";
};
exports.isSinon = function (obj) {

@@ -13,0 +17,0 @@ return !!obj && typeof obj === "object" &&

{
"name": "sinon-test",
"version": "0.0.1",
"version": "1.0.0",
"description": "",
"main": "lib/index.js",
"scripts": {
"test": "./scripts/ci-test.sh",
"build": "rollup -c | uglifyjs --mangle --compress if_return,dead_code,unsafe,unsafe_comps,join_vars,comparisons,loops,collapse_vars,cascade,pure_getters > dist/sinon-test.js",
"coverage": "nyc report --reporter text-lcov | coveralls",
"test": "nyc mocha",
"lint": "eslint .",

@@ -21,12 +23,18 @@ "eslint-pre-commit": "./scripts/eslint-pre-commit"

"devDependencies": {
"browserify": "^13.0.0",
"browserify-shim": "^3.8.12",
"buster": "0.7.18",
"buster-core": "^0.6.4",
"buster-istanbul": "^0.1.15",
"eslint": "^1.7.1",
"eslint-config-defaults": "^2.1.0",
"es6-promise": "^4.0.5",
"eslint": "^3.7.1",
"eslint-config-defaults": "^9.0.0",
"mocha": "^3.0.2",
"nyc": "^8.3.0",
"phantomjs-prebuilt": "^2.1.7",
"pre-commit": "^1.1.2",
"sinon": "git+https://github.com/sinonjs/sinon.git"
"rollup": "^0.36.1",
"rollup-plugin-commonjs": "^5.0.4",
"sinon": "^2.0.0-pre",
"uglify-js": "^2.7.3"
},
"peerDependencies": {
"sinon": "^2.0.0-pre"
},
"browserify-shim": {

@@ -33,0 +41,0 @@ "buster": "global:buster"

# Sinon Test
> Automatic sandbox setup and teardown for SinonJS
Test Framework helpers for SinonJS
## Why?
Instead of writing tedious setup and teardown code for each
individual test case you can let Sinon do all the cleanup for you.
So instead of doing this (using [Mocha](https://mochajs.org/) syntax):
```javascript
var spy1;
var spy2;
afterEach(()=>{
spy1.restore();
spy2.restore();
});
it('should do something', ()=>{
spy1 = sinon.spy(myFunc);
spy2 = sinon.spy(myOtherFunc);
myFunc(1);
myFunc(2);
assert(spy1.calledWith(1));
assert(spy1.calledWith(2));
});
```
You could write just this
```javascript
it('should do something', sinon.test(function(){
var spy1 = this.spy(myFunc);
var spy2 = this.spy(myOtherFunc);
myFunc(1);
myFunc(2);
assert(spy1.calledWith(1));
assert(spy1.calledWith(2));
})); //auto-cleanup
```
Sinon will take care of removing all the spies and stubs
from the wrapped functions for you. It does this by using
`sinon.sandbox` internally.
Do notice that
we use a `function` and not a arrow function (ES2015)
when wrapping the test with `sinon.test` as it needs
to be able to access the `this` pointer used inside
of the function.
See the [Usage](#usage) section for more details.
## Installation

@@ -11,7 +60,11 @@

or just add it as a `<script src="dist/sinon-test.js"></script>`
tag to the html where you write your tests. A pre-built browser
version is found in [dist/sinon-test.js](./dist/sinon-test.js).
## Usage
See the [sinon project homepage](http://sinonjs.org/) for documentation on usage.
See the [sinon documentation](http://sinonjs.org/docs/#sinon-test) for documentation on usage.
`sinon-test` instances need to be configured with a `sinon` instance before they can be used, you can emulate the sinon 1.x methods with the following:
`sinon-test` instances need to be configured with a `sinon` instance (version 2+) before they can be used; you can emulate the sinon 1.x methods with the following:

@@ -21,5 +74,24 @@ ```js

var sinonTest = require('sinon-test');
var assert = require('assert');
sinon.test = sinonTest.configureTest(sinon);
sinon.testCase = sinonTest.configureTestCase(sinon);
describe('my function', function() {
var myFunc = require('./my-func');
it('should do something', sinon.test(function(){
var spy = this.spy(myFunc);
myFunc(1);
assert(spy.calledWith(1));
})); //auto-cleanup
});
```
In order to configure with options, a configuration hash can be passed as a 2nd argument to `sinonTest.configureTest`:
```js
sinon.test = sinonTest.configureTest(sinon, {useFakeTimers: false});
```

@@ -13,4 +13,4 @@ "use strict";

buster.testCase("sinon-test.testCase", {
setUp: function () {
module.exports = {
beforeEach: function () {
testCaseInstance = sinonTestCase.configure(sinon);

@@ -266,4 +266,2 @@ },

}
});
};

@@ -6,4 +6,7 @@ "use strict";

var sinon = require("sinon");
var Promise = require("es6-promise").Promise;
var nextTick = buster.nextTick;
var nextTick = typeof process !== "undefined" && process.nextTick || function (fn) {
setTimeout(fn, 0);
};
var assert = buster.assert;

@@ -14,4 +17,33 @@ var refute = buster.refute;

buster.testCase("sinon-test", {
setUp: function () {
// promise-like structure
function stubPromise() {
var thenStub = sinon.stub();
var promise = {
then: thenStub,
index: 0,
resolve: function (object) {
var callback = thenStub.getCall(this.index++).args[0];
if (object) {
callback(object);
} else {
callback();
}
},
reject: function (error) {
var callback = thenStub.getCall(this.index++).args[1];
if (error) {
callback(error);
} else {
callback();
}
}
};
thenStub.returns(promise);
return promise;
}
module.exports = {
beforeEach: function () {
this.boundTestCase = function () {

@@ -99,2 +131,65 @@ var properties = {

"throws when an async method throws": function () {
var method = function () {};
var object = { method: method };
var fakeDone = function () {};
assert.exception(function () {
instance(function (done) { // eslint-disable-line no-unused-vars
this.stub(object, "method");
throw new Error();
}).call({}, fakeDone);
}, "Error");
},
"restores stub after promise resolves": function () {
var object = {};
var promise = instance(function () {
return new Promise(function (resolve) {
nextTick(function () { resolve(object); });
});
}).call({});
return promise.then(function (result) {
assert.same(result, object);
});
},
"restores stub after promise is resolved": function () {
var method = function () {};
var object = { method: method };
var promise = instance(function () {
this.stub(object, "method");
return new Promise(function (resolve) {
nextTick(function () { resolve(object); });
});
}).call({});
assert.equals(object.method === method, false);
return promise.then(function () {
assert.same(object.method, method);
});
},
"restores stub after promise is rejected": function () {
var method = function () {};
var object = { method: method };
var promise = instance(function () {
this.stub(object, "method");
return new Promise(function (_, reject) {
nextTick(function () { reject(new Error()); });
});
}).call({});
assert.equals(object.method === method, false);
return promise.then(null, function (err) {
assert.equals(err instanceof Error, true);
});
},
"restores stub when method throws": function () {

@@ -225,2 +320,191 @@ var method = function () {};

"async tests should not allow thenables to be returned": function () {
var thenable = {
then: function () {
}
};
var test = instance(function (_) { // eslint-disable-line no-unused-vars
return thenable;
});
assert.exception(test, {
message: /callback .* promise.* both/
});
},
"sync tests with thenable return value": {
beforeEach: function () {
var method = this.method = function () {};
var object = this.object = {method: method};
var promise = this.promise = stubPromise();
this.sinonTest = instance(function () {
this.stub(object, "method");
return promise;
});
},
afterEach: function () {
// ensure sandbox is restored
if (this.promise.index < this.promise.then.callCount) {
this.promise.resolve();
}
},
"should listen to returned promise": function (done) {
var self = this;
var promise = self.sinonTest.call({});
assert(promise.then.calledOnce);
assert(promise.then.getCall(0).args.length, 2);
assert.isFunction(promise.then.getCall(0).args[0]);
assert.isFunction(promise.then.getCall(0).args[1]);
// allow any other actions to take place
nextTick(function () {
refute.same(self.object.method, self.method, "should wait to restore stubs");
done();
});
},
"restores sandbox after promise is fulfilled": function () {
var promise = this.sinonTest.call({});
promise.resolve();
assert.same(this.object.method, this.method);
},
"restores sandbox after promise is rejected": function () {
var promise = this.sinonTest.call({});
var error = new Error("expected");
assert.exception(
function () {
promise.reject(error);
},
{message: "expected"},
"should re-throw error from rejected promise"
);
assert.same(this.object.method, this.method);
},
"ensures test rejects with a non-falsy value": function () {
var promise = this.sinonTest.call({});
assert.exception(
function () {
promise.reject(false);
},
{message: /rejected.*falsy/}
);
assert.same(this.object.method, this.method);
}
},
"sync tests with A+ promise returned": {
beforeEach: function () {
if (typeof Promise === "undefined") {
this.skip();
}
this.method = function () {};
this.object = {method: this.method};
},
"restores the sandbox when the promise is fulfilled": function (done) {
var self = this;
var expected = {};
var test = instance(function () {
var sandbox = this;
return new Promise(function (resolve) {
sandbox.stub(self.object, "method");
resolve(expected);
});
});
test.call({}).then(function (thing) {
assert.equals(self.object.method, self.method);
assert.same(thing, expected);
done();
});
},
"restores the sandbox when the promise is rejected": function (done) {
var self = this;
var test = instance(function () {
var sandbox = this;
return new Promise(function (_, reject) {
sandbox.stub(self.object, "method");
reject();
});
});
test.call({}).catch(function () {
assert.equals(self.object.method, self.method);
done();
});
},
"ensures test rejects with a non-falsy value": function (done) {
var self = this;
var test = instance(function () {
return Promise.reject(false);
});
test.call({}).catch(function (error) {
assert.match(error.message, /rejected.*falsy/);
assert.same(self.object.method, self.method);
done();
});
},
"re-throws the error if the promise is rejected": function (done) {
var expectedError = new Error("expected");
var test = instance(function () {
return Promise.reject(expectedError);
});
test.call({}).catch(function (error) {
assert.equals(error, expectedError);
done();
});
},
"verifies mocks when promise is resolved": function (done) {
var self = this;
var test = instance(function () {
var sandbox = this;
return new Promise(function (resolve) {
sandbox.mock(self.object).expects("method").withExactArgs(1).once();
self.object.method(42);
resolve();
});
});
test.call({}).catch(function (error) {
assert.equals(error.name, "ExpectationError");
assert.match(error.message, /Expected method\(1\) once/);
done();
});
}
},
"verifies mocks": function () {

@@ -375,6 +659,2 @@ var method = function () {};

"browser options": {
requiresSupportFor: {
"ajax/browser": typeof XMLHttpRequest !== "undefined" || typeof ActiveXObject !== "undefined"
},
"yields server when faking xhr": function () {

@@ -614,2 +894,2 @@ var stubbed, mocked, server;

}
});
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc