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

testdouble

Package Overview
Dependencies
Maintainers
2
Versions
115
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

testdouble - npm Package Compare versions

Comparing version 1.1.3 to 1.2.0

docs/img/stub.gif

15

docs/5-stubbing-results.md

@@ -25,3 +25,3 @@ # Stubbing behavior

The `when()` function returns an object containing the function `thenReturn`, which is used to specify the value the test double should return if it's invoked as specified in the `when()` call. For now, only `thenReturn` is supported as a response type. For whatever reason, we haven't found an urgent need to implement two other typical responses, `thenDo` (to invoke a function that has some side effect, [#8](https://github.com/testdouble/testdouble.js/issues/8)) and `thenThrow` (to throw some error, [#7](https://github.com/testdouble/testdouble.js/issues/7)), but we'd gladly accept pull requests for either.
The `when()` function returns an object containing the function `thenReturn`, which is used to specify the value the test double should return if it's invoked as specified in the `when()` call. There are also a `thenDo` and `thenThrow` response type which are described below.

@@ -247,2 +247,15 @@ ## Simple, precise argument stubbing

#### td.matchers.not()
When you only care that a test double function _isn't_ passed a certain value,
you can use the `not` matcher:
``` js
var didSucceed = td.function()
didSucceed(true)
td.verify(didSucceed(td.matchers.not(false)))
```
### Stubbing callback APIs

@@ -249,0 +262,0 @@

@@ -10,5 +10,9 @@ ### Custom argument matchers

when it matches and falsey when it doesn't is considered a matcher by
testdouble.js. Anything without a `__matches` function will only match an
testdouble.js. That said, we provide a `td.matchers.create()` helper for creating
your own custom matchers in a way that'll help ensure your users will get better
messages from `td.explain` calls and `td.verify` failures.
(For the record, arguments without a `__matches` property will only match an
actual invocation if it passes lodash's deep
[_.isEqual](https://lodash.com/docs#isEqual) test.
[_.isEqual](https://lodash.com/docs#isEqual) test.)

@@ -24,9 +28,9 @@ The examples in this document assume you've aliased `testdouble` to `td`.

``` javascript
isA = function(expected) {
return {
__matches: function(actual) {
return actual instanceof expected;
}
isA = td.matchers.create({
name: 'isA',
matches: function(matcherArgs, actual) {
var expected = matcherArgs[0]
return actual instanceof expected
}
}
})
```

@@ -44,1 +48,22 @@

```
#### td.matchers.create API
The `create` function takes a configuration object with the following properties
* **matches(matcherArgs, actual)** - _required_ - a function that returns truthy
when an `actual` argument satisfies the matcher's rules, given what the user
passed to the matcher as `matcherArgs` when setting it up. For instance, if
`td.when(func(isFooBar('foo','bar')).thenReturn('baz')` is configured, then
`func('biz')` is invoked, then `isFooBar`'s `matches` function will be invoked
with `matcherArgs` of `['foo','bar']` and `actual` of `'biz'`
* **name** - _optional_ - a string name for better messages. A function can
also be provided, which will be passed the user's `matcherArgs` and should return
a string name
* **onCreate(matcherInstance, matcherArgs)** - _optional_ - a function invoked
whenever an instance of a matcher is created to give the matcher author an
opportunity to mutate the matcher instance or have some other side effect. The
`td.callback` functionality of the library depends on this option
For some examples of `td.matchers.create()` in action, check out the
[built-in matchers](src/matchers/index.coffee) provided by testdouble.js.

29

lib/args-match.js
// Generated by CoffeeScript 1.10.0
(function() {
var _, argumentMatchesExpectation, matcherHidingInExpectedArgument, satisfiesEqualityPlusAnyArgumentMatchers;
var _, argumentMatchesExpectation, arityMismatch, equalsWithMatchers, matcherFor;

@@ -8,16 +8,15 @@ _ = require('lodash');

module.exports = function(expectedArgs, actualArgs, config) {
if (_.eq(expectedArgs, actualArgs)) {
return true;
}
if (expectedArgs.length !== actualArgs.length && !config.ignoreExtraArgs) {
if (arityMismatch(expectedArgs, actualArgs, config)) {
return false;
}
return satisfiesEqualityPlusAnyArgumentMatchers(expectedArgs, actualArgs);
return equalsWithMatchers(expectedArgs, actualArgs);
};
satisfiesEqualityPlusAnyArgumentMatchers = function(expectedArgs, actualArgs) {
return _.eq(expectedArgs, actualArgs, function(expected, actual) {
return _.all(expectedArgs, function(expectedArg, i) {
return argumentMatchesExpectation(expectedArg, actualArgs[i]);
});
arityMismatch = function(expectedArgs, actualArgs, config) {
return expectedArgs.length !== actualArgs.length && !config.ignoreExtraArgs;
};
equalsWithMatchers = function(expectedArgs, actualArgs) {
return _.all(expectedArgs, function(expectedArg, i) {
return argumentMatchesExpectation(expectedArg, actualArgs[i]);
});

@@ -28,12 +27,10 @@ };

var matcher;
if (_.eq(expectedArg, actualArg)) {
return true;
} else if (matcher = matcherHidingInExpectedArgument(expectedArg)) {
if (matcher = matcherFor(expectedArg)) {
return matcher(actualArg);
} else {
return false;
return _.eq(expectedArg, actualArg);
}
};
matcherHidingInExpectedArgument = function(expectedArg) {
matcherFor = function(expectedArg) {
if (_.isFunction(expectedArg != null ? expectedArg.__matches : void 0)) {

@@ -40,0 +37,0 @@ return expectedArg.__matches;

// Generated by CoffeeScript 1.10.0
(function() {
var _, callDescription, callsStore, nullDescription, store, stringifyArgs, stringifyName, stubbingDescription, stubbingsStore;
var _, callDescription, callsStore, nullDescription, store, stringifyArgs, stringifyName, stubbingDescription, stubbingsStore, testdoubleDescription;

@@ -13,3 +13,3 @@ _ = require('lodash');

stringifyArgs = require('./stringify-args');
stringifyArgs = require('./stringify/arguments');

@@ -26,3 +26,3 @@ module.exports = function(testDouble) {

calls: calls,
description: ("This test double " + (stringifyName(testDouble)) + "has " + stubs.length + " stubbings and " + calls.length + " invocations.") + stubbingDescription(stubs) + callDescription(calls),
description: testdoubleDescription(testDouble, stubs, calls) + stubbingDescription(stubs) + callDescription(calls),
isTestDouble: true

@@ -41,2 +41,6 @@ };

testdoubleDescription = function(testDouble, stubs, calls) {
return "This test double " + (stringifyName(testDouble)) + "has " + stubs.length + " stubbings and " + calls.length + " invocations.";
};
stubbingDescription = function(stubs) {

@@ -43,0 +47,0 @@ if (stubs.length === 0) {

// Generated by CoffeeScript 1.10.0
(function() {
var _, callback,
slice = [].slice;
var _, callback, create;
_ = require('lodash');
module.exports = callback = function() {
var args;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return {
args: args,
__testdouble_callback: true,
__matches: _.isFunction
};
};
create = require('./create');
module.exports = callback = create({
name: 'callback',
matches: function(matcherArgs, actual) {
return _.isFunction(actual);
},
onCreate: function(matcherInstance, matcherArgs) {
matcherInstance.args = matcherArgs;
return matcherInstance.__testdouble_callback = true;
}
});
callback.__name = 'callback';
callback.__matches = _.isFunction;

@@ -19,0 +23,0 @@

// Generated by CoffeeScript 1.10.0
(function() {
var create;
create = require('./create');
module.exports = function() {
var captor;
return captor = {
capture: function() {
return {
__matches: function(actual) {
captor.value = actual;
return true;
}
};
}
capture: create({
name: 'captor.capture',
matches: function(matcherArgs, actual) {
captor.value = actual;
return true;
}
})
};

@@ -15,0 +18,0 @@ };

// Generated by CoffeeScript 1.10.0
(function() {
var _, captor,
slice = [].slice;
var _, create, stringifyArguments;
_ = require('lodash');
captor = require('./captor');
create = require('./create');
stringifyArguments = require('../stringify/arguments');
module.exports = {
captor: captor,
isA: function(type) {
return {
__matches: function(actual) {
if (type === Number) {
return _.isNumber(actual);
} else if (type === String) {
return _.isString(actual);
} else if (type === Boolean) {
return _.isBoolean(actual);
} else {
return actual instanceof type;
}
create: create,
captor: require('./captor'),
isA: create({
name: function(matcherArgs) {
var ref, s;
s = ((ref = matcherArgs[0]) != null ? ref.name : void 0) != null ? matcherArgs[0].name : stringifyArguments(matcherArgs);
return "isA(" + s + ")";
},
matches: function(matcherArgs, actual) {
var type;
type = matcherArgs[0];
if (type === Number) {
return _.isNumber(actual);
} else if (type === String) {
return _.isString(actual);
} else if (type === Boolean) {
return _.isBoolean(actual);
} else {
return actual instanceof type;
}
};
},
anything: function() {
return {
__matches: function() {
return true;
}
};
},
contains: function() {
var containings, containsAllSpecified;
containings = 1 <= arguments.length ? slice.call(arguments, 0) : [];
containsAllSpecified = function(containing, actual) {
return _.all(containing, function(val, key) {
if (actual == null) {
return false;
}
if (_.isPlainObject(val)) {
return containsAllSpecified(val, actual[key]);
}
}),
anything: create({
name: 'anything',
matches: function() {
return true;
}
}),
contains: create({
name: 'contains',
matches: function(containings, actualArg) {
var containsAllSpecified;
containsAllSpecified = function(containing, actual) {
return _.all(containing, function(val, key) {
if (actual == null) {
return false;
}
if (_.isPlainObject(val)) {
return containsAllSpecified(val, actual[key]);
} else {
return _.eq(val, actual[key]);
}
});
};
return _.all(containings, function(containing) {
if (_.isString(containing)) {
return _.include(actualArg, containing);
} else if (_.isArray(containing)) {
return _.any(actualArg, function(actualElement) {
return _.eq(actualElement, containing);
});
} else if (_.isPlainObject(containing)) {
return containsAllSpecified(containing, actualArg);
} else {
return _.eq(val, actual[key]);
throw new Error("the contains() matcher only supports strings, arrays, and plain objects");
}
});
};
return {
__matches: function(actual) {
return _.all(containings, function(containing) {
if (_.isString(containing)) {
return _.include(actual, containing);
} else if (_.isArray(containing)) {
return _.any(actual, function(actualElement) {
return _.eq(actualElement, containing);
});
} else if (_.isPlainObject(containing)) {
return containsAllSpecified(containing, actual);
} else {
throw new Error("the contains() matcher only supports strings, arrays, and plain objects");
}
});
}
};
},
argThat: function(predicate) {
return {
__matches: function(actual) {
return predicate(actual);
}
};
}
}
}),
argThat: create({
name: 'argThat',
matches: function(matcherArgs, actual) {
var predicate;
predicate = matcherArgs[0];
return predicate(actual);
}
}),
not: create({
name: 'not',
matches: function(matcherArgs, actual) {
var expected;
expected = matcherArgs[0];
return !_.eq(expected, actual);
}
})
};
}).call(this);

@@ -11,3 +11,3 @@ // Generated by CoffeeScript 1.10.0

stringifyArgs = require('./stringify-args');
stringifyArgs = require('./stringify/arguments');

@@ -14,0 +14,0 @@ module.exports = function(__userDoesPretendInvocationHere__, config) {

// Generated by CoffeeScript 1.10.0
(function() {
module.exports = '1.1.3';
module.exports = '1.2.0';
}).call(this);
{
"name": "testdouble",
"version": "1.1.3",
"version": "1.2.0",
"description": "A minimal test double library for TDD with JavaScript",

@@ -22,3 +22,3 @@ "homepage": "https://github.com/testdouble/testdouble.js",

"compile": "npm run compile:node && npm run compile:test && npm run compile:browser",
"test": "mocha --ui mocha-given --reporter $npm_package_config_mocha_reporter --compilers coffee:coffee-script --recursive test/node-helper.coffee test/lib",
"test": "mocha --ui mocha-given --reporter $npm_package_config_mocha_reporter --compilers coffee:coffee-script --recursive test/node-helper.coffee test/src",
"test:browser": "npm run compile && testem ci",

@@ -44,3 +44,4 @@ "test:example:webpack": "cd examples/webpack && npm i && npm test & cd ../..",

"lodash": "^3.10.1",
"quibble": "^0.3.0"
"quibble": "^0.3.0",
"stringify-object-with-one-liners": "^1.0.0"
},

@@ -47,0 +48,0 @@ "devDependencies": {

@@ -15,2 +15,23 @@ # testdouble.js

## Coming from Sinon.js?
Right now, Sinon.js is the test double incumbent in JavaScript, with over 1.7
million downloads in the last month. If you've got experience with Sinon, [check
out our side-by-side
comparison](http://blog.testdouble.com/posts/2016-03-13-testdouble-vs-sinon.html)
to see why we wrote testdouble.js and how some of the API translates.
## The Very Basics
Before diving into our in-depth docs, here are a couple demo GIFs of the basic
uses:
### Stubbing return values for functions
![simple stubbing example animation](docs/img/stub.gif)
### Verifying a function was invoked
![simple verification of a function invocation](docs/img/verify.gif)
## Docs

@@ -50,2 +71,3 @@

4. [td.matchers.argThat()](docs/5-stubbing-results.md#tdmatchersargthat)
5. [td.matchers.not()](docs/5-stubbing-results.md#tdmatchersnot)
6. [Stubbing callback APIs](docs/5-stubbing-results.md#stubbing-callback-apis)

@@ -52,0 +74,0 @@ 7. [Stub exceptions with thenThrow](docs/5-stubbing-results.md#stub-exceptions-with-thenthrow)

@@ -22,4 +22,4 @@ var pkg = require('./package.json');

// tests
"generated/test/lib/**/*.js"
"generated/test/src/**/*.js"
]
};
}

Sorry, the diff of this file is too big to display

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

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