testdouble
Advanced tools
Comparing version 3.2.6 to 3.2.7
@@ -135,3 +135,3 @@ # Creating Test Doubles | ||
If passed either a string name or no arguments at all, `td.object` will return an [ES2015 Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) object designed to forward any property access as if it was a test double function. By using `Proxy`, testdouble.js is able to intercept calls to properties that don't exist, immediately create a new test double function, and invoke that function for use in either stubbing or verifying behavior. | ||
If passed either a string name or no arguments at all, `td.object` will return an [ES2015 Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) object designed to forward any property access as if it were a test double function. By using `Proxy`, testdouble.js is able to intercept calls to properties that don't exist, immediately create a new test double function, and invoke that function for use in either stubbing or verifying behavior. | ||
@@ -226,3 +226,3 @@ ``` javascript | ||
As you can see, there are a plethora of ways to create test doubles with testdouble.js, each designed to handle a different style of organizing JavaScript code. We recommend on landing on one consistent style (e.g. each module as one function) for each project, which in turn would encourage one consistent style of creating test doubles. This API is written to be flexible for a number of potential contexts across objects, but it has come at the cost of a large enough surface area that if any project were to make ample use of all or most of the above invocation styles, it would confuse readers. | ||
As you can see, there are a plethora of ways to create test doubles with testdouble.js, each designed to handle a different style of organizing JavaScript code. We recommend landing on one consistent style (e.g. each module as one function) for each project, which in turn would encourage one consistent style of creating test doubles. This API is written to be flexible for a number of potential contexts across objects, but it has come at the cost of a large enough surface area that if any project were to make ample use of all or most of the above invocation styles, it would confuse readers. | ||
@@ -229,0 +229,0 @@ *** |
@@ -108,3 +108,3 @@ # Stubbing behavior | ||
For instance, if the stubbing was unconditional, we might pat ourselves on the back for writing this test: | ||
For instance, if the stubbing were unconditional, we might pat ourselves on the back for writing this test: | ||
@@ -111,0 +111,0 @@ ``` javascript |
@@ -46,14 +46,50 @@ # Replacing Real Dependencies with Test Doubles | ||
``` javascript | ||
var brake = td.replace('../../lib/brake'), | ||
subject = require('../../lib/car') | ||
module.exports = { | ||
beforeEach: function() { | ||
var brake = td.replace('../../lib/brake') | ||
var subject = require('../../lib/car') | ||
}, | ||
'slowing applies the break': function () { | ||
subject.slowDown() | ||
subject.slowDown() | ||
td.verify(brake(10)) | ||
td.verify(brake(10)) | ||
} | ||
} | ||
``` | ||
In order to make the above test pass, we first need to create `lib/brake.js` and | ||
export a function, so that testdouble.js knows to replace `require` calls with | ||
a test double function (as opposed to a default `module.exports` object): | ||
There are few very important things to note about how to use module replacement | ||
safely (with great power, etc.): | ||
* Most importantly: **move your replacements and requirements into a | ||
`beforeEach` hook (or equivalent)** and be sure you're calling `td.reset()` | ||
after each test case. Because `td.replace('../module/path')` will disrupt | ||
Node's module caching behavior and cause `require()` to return a fake, it | ||
would cause test pollution to keep the `require` stanzas at the top of the | ||
file | ||
* As a result, your tests will need to use `require` and not the ES static | ||
`import` keyword. This _only applies to your test files_, however, you can | ||
still feel free to use `import` in your production source files, where it | ||
actually matters if you're leveraging a bundling tool like Webpack or Rollup. | ||
Keep in mind that you'll like be doing a lot of | ||
`td.replace('../path').default` assignments if you're using default exports | ||
* `td.replace` is designed to be used as part of an outside-in test-driven | ||
development workflow, and so calling `td.replace` for some path will trigger | ||
an error until it actually exists and exports the basic shape (e.g. a | ||
function, or a bag of functions, or a class) that is expected to be consumed | ||
by the subject under test | ||
* Because `td.replace` first requires the module being replaced and then | ||
performs a deep imitation of whatever the real module exports, any | ||
side-effects the to-be-replaced module has will be inadvertently triggered by | ||
the test (remember, good modules should be loadable without triggering side | ||
effects!) | ||
That's a lot of caveats, but so long as your test and module design is simple | ||
and consistent, it's a powerful feature that can drastically simplify the setup | ||
of your isolation tests. | ||
Now, in order to make the above test pass, we first need to create | ||
`lib/brake.js` and export a function, so that testdouble.js knows to replace | ||
`require` calls with a test double function (as opposed to a default | ||
`module.exports` object): | ||
``` javascript | ||
@@ -86,4 +122,4 @@ module.exports = function(){} | ||
check out the [babel example | ||
project](../examples/babel/test/lib/calculator-test.js). (Note that the test | ||
itself must fall back to CommonJS-style `require` statements, since module | ||
project](../examples/babel/test/lib/calculator-test.js). (Note again that the | ||
test itself must fall back to CommonJS-style `require` statements, since module | ||
replacement requires the dependency be loaded after the replacements are | ||
@@ -90,0 +126,0 @@ configured, which precludes the use of the static `import` statement.) |
@@ -16,3 +16,3 @@ # Custom argument matchers | ||
actual invocation if it passes lodash's deep | ||
[_.isEqual](https://lodash.com/docs#isEqual) test.) | ||
[`_.isEqual`](https://lodash.com/docs#isEqual) test.) | ||
@@ -53,14 +53,21 @@ The examples in this document assume you've aliased `testdouble` to `td`. | ||
* **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 | ||
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 | ||
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 | ||
* **afterSatisfaction(matcherArgs, actual)** - _optional_ - a function invoked | ||
whenever `td.when` is satisfied (e.g. all arguments of an invocation match the | ||
arguments & matchers of the stubbing) or `td.verify` is satisfied (e.g. one or | ||
more invocations match the given arguments & matchers). This is useful when a | ||
matcher's behavior depends on whether actual invocations matched the test's | ||
expectations (as is the case with [argument | ||
captors](6-verifying-invocations.md#multi-phase-assertions-with-argument-captors)) | ||
@@ -67,0 +74,0 @@ For some examples of `td.matchers.create()` in action, check out the |
@@ -12,4 +12,4 @@ { | ||
"semver": "^5.3.0", | ||
"testdouble": "*" | ||
"testdouble": "../../" | ||
} | ||
} |
@@ -7,4 +7,4 @@ { | ||
"test:style": "standard", | ||
"test": "yarn run test:unit && yarn run test:style", | ||
"test:debug": "yarn test -- --debug-brk" | ||
"test": "npm run test:unit && npm run test:style", | ||
"test:debug": "npm test -- --debug-brk" | ||
}, | ||
@@ -17,6 +17,9 @@ "devDependencies": { | ||
"teenytest": "^5.0.2", | ||
"testdouble": "*" | ||
"testdouble": "../../" | ||
}, | ||
"standard": { | ||
"globals": ["td", "assert"] | ||
"globals": [ | ||
"td", | ||
"assert" | ||
] | ||
}, | ||
@@ -23,0 +26,0 @@ "teenytest": { |
@@ -9,3 +9,3 @@ { | ||
"devDependencies": { | ||
"testdouble": "*", | ||
"testdouble": "../../", | ||
"testem": "^1.15.0", | ||
@@ -12,0 +12,0 @@ "webpack": "^2.2.1" |
module.exports = { | ||
entry: './test/math-problem-test.js', | ||
output: { | ||
filename: 'test-bundle.js', | ||
path: './built' | ||
filename: 'test-bundle.js' | ||
} | ||
} | ||
@@ -7,3 +7,3 @@ "use strict"; | ||
var td = require("../.."); | ||
var Dog = (function () { | ||
var Dog = /** @class */ (function () { | ||
function Dog() { | ||
@@ -14,3 +14,3 @@ } | ||
}()); | ||
var Cat = (function () { | ||
var Cat = /** @class */ (function () { | ||
function Cat() { | ||
@@ -33,3 +33,3 @@ } | ||
if (eval("typeof Proxy") !== "undefined") { | ||
var Bear = (function () { | ||
var Bear = /** @class */ (function () { | ||
function Bear() { | ||
@@ -36,0 +36,0 @@ } |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -26,3 +26,3 @@ var _isMatcher = require('./matchers/is-matcher'); | ||
} else { | ||
return _lodashWrap2.default.isEqual(expectedArgs, actualArgs); | ||
return _lodash2.default.isEqual(expectedArgs, actualArgs); | ||
} | ||
@@ -36,3 +36,3 @@ }; | ||
var equalsWithMatchers = function equalsWithMatchers(expectedArgs, actualArgs) { | ||
return _lodashWrap2.default.every(expectedArgs, function (expectedArg, key) { | ||
return _lodash2.default.every(expectedArgs, function (expectedArg, key) { | ||
return argumentMatchesExpectation(expectedArg, actualArgs[key]); | ||
@@ -46,3 +46,3 @@ }); | ||
} else { | ||
return _lodashWrap2.default.isEqualWith(expectedArg, actualArg, function (expectedEl, actualEl) { | ||
return _lodash2.default.isEqualWith(expectedArg, actualArg, function (expectedEl, actualEl) { | ||
if ((0, _isMatcher2.default)(expectedEl)) { | ||
@@ -49,0 +49,0 @@ return matcherTestFor(expectedEl)(actualEl); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -18,6 +18,6 @@ var _create = require('./matchers/create'); | ||
exports.default = _lodashWrap2.default.tap((0, _create2.default)({ | ||
var callback = (0, _create2.default)({ | ||
name: 'callback', | ||
matches: function matches(matcherArgs, actual) { | ||
return _lodashWrap2.default.isFunction(actual); | ||
return _lodash2.default.isFunction(actual); | ||
}, | ||
@@ -28,10 +28,8 @@ onCreate: function onCreate(matcherInstance, matcherArgs) { | ||
} | ||
}), function (callback) { | ||
// Make callback itself quack like a matcher for its non-invoked use case. | ||
callback.__name = 'callback'; | ||
callback.__matches = _lodashWrap2.default.isFunction; | ||
}); | ||
callback.isCallback = function (obj) { | ||
return obj && (obj === callback || obj.__testdouble_callback === true); | ||
}; | ||
}); | ||
// Make callback itself quack like a matcher for its non-invoked use case. | ||
callback.__name = 'callback'; | ||
callback.__matches = _lodash2.default.isFunction; | ||
exports.default = callback; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -29,11 +29,11 @@ var _log = require('./log'); | ||
var configData = _lodashWrap2.default.extend({}, DEFAULTS); | ||
var configData = _lodash2.default.extend({}, DEFAULTS); | ||
exports.default = _lodashWrap2.default.tap(function (overrides) { | ||
exports.default = _lodash2.default.tap(function (overrides) { | ||
deleteDeletedOptions(overrides); | ||
ensureOverridesExist(overrides); | ||
return _lodashWrap2.default.extend(configData, overrides); | ||
return _lodash2.default.extend(configData, overrides); | ||
}, function (config) { | ||
config.reset = function () { | ||
configData = _lodashWrap2.default.extend({}, DEFAULTS); | ||
configData = _lodash2.default.extend({}, DEFAULTS); | ||
}; | ||
@@ -44,4 +44,4 @@ }); | ||
var deleteDeletedOptions = function deleteDeletedOptions(overrides) { | ||
_lodashWrap2.default.each(overrides, function (val, key) { | ||
if (_lodashWrap2.default.includes(DELETED_OPTIONS, key)) { | ||
_lodash2.default.each(overrides, function (val, key) { | ||
if (_lodash2.default.includes(DELETED_OPTIONS, key)) { | ||
_log2.default.warn('td.config', '"' + key + '" is no longer a valid configuration key. Remove it from your calls to td.config() or it may throw an error in the future. For more information, try hunting around our GitHub repo for it:\n\n https://github.com/testdouble/testdouble.js/search?q=' + key); | ||
@@ -54,7 +54,7 @@ delete overrides[key]; | ||
var ensureOverridesExist = function ensureOverridesExist(overrides) { | ||
_lodashWrap2.default.each(overrides, function (val, key) { | ||
_lodash2.default.each(overrides, function (val, key) { | ||
if (!configData.hasOwnProperty(key)) { | ||
_log2.default.error('td.config', '"' + key + '" is not a valid configuration key (valid keys are: ' + (0, _anything2.default)(_lodashWrap2.default.keys(configData)) + ')'); | ||
_log2.default.error('td.config', '"' + key + '" is not a valid configuration key (valid keys are: ' + (0, _anything2.default)(_lodash2.default.keys(configData)) + ')'); | ||
} | ||
}); | ||
}; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -23,7 +23,7 @@ var _function = require('./function'); | ||
exports.default = function (typeOrNames) { | ||
return _lodashWrap2.default.isFunction(typeOrNames) ? (0, _imitate2.default)(typeOrNames) : fakeConstructorFromNames(typeOrNames); | ||
return _lodash2.default.isFunction(typeOrNames) ? (0, _imitate2.default)(typeOrNames) : fakeConstructorFromNames(typeOrNames); | ||
}; | ||
var fakeConstructorFromNames = function fakeConstructorFromNames(funcNames) { | ||
return _lodashWrap2.default.tap((0, _function2.default)('(unnamed constructor)'), function (fakeConstructor) { | ||
return _lodash2.default.tap((0, _function2.default)('(unnamed constructor)'), function (fakeConstructor) { | ||
fakeConstructor.prototype.toString = function () { | ||
@@ -33,3 +33,3 @@ return '[test double instance of constructor]'; | ||
_lodashWrap2.default.each(funcNames, function (funcName) { | ||
_lodash2.default.each(funcNames, function (funcName) { | ||
fakeConstructor.prototype[funcName] = (0, _function2.default)('#' + funcName); | ||
@@ -36,0 +36,0 @@ }); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -61,3 +61,3 @@ var _calls = require('./store/calls'); | ||
var stubbingDescription = function stubbingDescription(stubs) { | ||
return stubs.length > 0 ? _lodashWrap2.default.reduce(stubs, function (desc, stub) { | ||
return stubs.length > 0 ? _lodash2.default.reduce(stubs, function (desc, stub) { | ||
return desc + ('\n - when called with `(' + (0, _arguments2.default)(stub.args) + ')`, then ' + planFor(stub) + ' ' + argsFor(stub) + '.'); | ||
@@ -90,3 +90,3 @@ }, '\n\nStubbings:') : ''; | ||
var callDescription = function callDescription(calls) { | ||
return calls.length > 0 ? _lodashWrap2.default.reduce(calls, function (desc, call) { | ||
return calls.length > 0 ? _lodash2.default.reduce(calls, function (desc, call) { | ||
return desc + ('\n - called with `(' + (0, _arguments2.default)(call.args) + ')`.'); | ||
@@ -93,0 +93,0 @@ }, '\n\nInvocations:') : ''; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -31,7 +31,7 @@ var _calls = require('./store/calls'); | ||
exports.default = function (nameOrFunc, __optionalName) { | ||
return _lodashWrap2.default.isFunction(nameOrFunc) ? (0, _imitate2.default)(nameOrFunc) : createTestDoubleNamed(nameOrFunc || __optionalName); | ||
return _lodash2.default.isFunction(nameOrFunc) ? (0, _imitate2.default)(nameOrFunc) : createTestDoubleNamed(nameOrFunc || __optionalName); | ||
}; | ||
var createTestDoubleNamed = function createTestDoubleNamed(name) { | ||
return _lodashWrap2.default.tap(createTestDoubleFunction(), function (testDouble) { | ||
return _lodash2.default.tap(createTestDoubleFunction(), function (testDouble) { | ||
var entry = _store2.default.for(testDouble, true); | ||
@@ -38,0 +38,0 @@ if (name != null) { |
@@ -6,7 +6,4 @@ 'use strict'; | ||
}); | ||
exports.default = create; | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
var _double = require('../value/double'); | ||
@@ -16,38 +13,10 @@ | ||
var _callLog = require('../value/call-log'); | ||
var _generateFakeFunction = require('./generate-fake-function'); | ||
var _callLog2 = _interopRequireDefault(_callLog); | ||
var _generateFakeFunction2 = _interopRequireDefault(_generateFakeFunction); | ||
var _call = require('../value/call'); | ||
var _call2 = _interopRequireDefault(_call); | ||
var _stubbingRegister = require('../value/stubbing-register'); | ||
var _stubbingRegister2 = _interopRequireDefault(_stubbingRegister); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function (nameOrFunc) { | ||
var name = deriveName(nameOrFunc); | ||
var real = _lodash2.default.isFunction(nameOrFunc) ? nameOrFunc : null; | ||
var double = new _double2.default(name, real, _lodash2.default.tap(function testDouble() { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
var call = new _call2.default(this, args); | ||
_callLog2.default.instance.log(double, call); | ||
return _stubbingRegister2.default.instance.satisfy(double, call); | ||
}, function (fakeFunction) { | ||
fakeFunction.toString = function () { | ||
return double.fullName == null ? '[test double (unnamed)]' : '[test double for "' + double.fullName + '"]'; | ||
}; | ||
})); | ||
return double; | ||
}; | ||
var deriveName = function deriveName(nameOrFunc) { | ||
var name = _lodash2.default.isFunction(nameOrFunc) ? nameOrFunc.name : nameOrFunc; | ||
return _lodash2.default.isEmpty(name) ? null : name; | ||
}; | ||
function create(name, real, parent) { | ||
return _double2.default.create(name, real, parent, _generateFakeFunction2.default); | ||
} |
@@ -6,2 +6,3 @@ 'use strict'; | ||
}); | ||
exports.default = func; | ||
@@ -16,17 +17,10 @@ var _lodash = require('../wrap/lodash'); | ||
var _imitate = require('../imitate'); | ||
var _imitate2 = _interopRequireDefault(_imitate); | ||
var _remember = require('./remember'); | ||
var _remember2 = _interopRequireDefault(_remember); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function (nameOrFunc) { | ||
if (_lodash2.default.isFunction(nameOrFunc)) return (0, _imitate2.default)(nameOrFunc); | ||
var double = (0, _create2.default)(nameOrFunc); | ||
(0, _remember2.default)(double); | ||
return double.fake; | ||
}; | ||
function func(nameOrFunc) { | ||
if (_lodash2.default.isFunction(nameOrFunc)) { | ||
return (0, _create2.default)(_lodash2.default.isEmpty(nameOrFunc.name) ? null : nameOrFunc.name, nameOrFunc).fake; | ||
} else { | ||
return (0, _create2.default)(nameOrFunc, null).fake; | ||
} | ||
} |
@@ -28,2 +28,3 @@ 'use strict'; | ||
} else { | ||
// TODO: this will become src/function/create and include parent reference instead of name joining here | ||
return (0, _function2.default)(names.join('') || '(anonymous function)'); | ||
@@ -30,0 +31,0 @@ } |
@@ -18,6 +18,8 @@ 'use strict'; | ||
matches: function matches(matcherArgs, actual) { | ||
return true; | ||
}, | ||
afterSatisfaction: function afterSatisfaction(matcherArgs, actual) { | ||
captor.values = captor.values || []; | ||
captor.values.push(actual); | ||
captor.value = actual; | ||
return true; | ||
} | ||
@@ -24,0 +26,0 @@ }) |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../../util/lodash-wrap'); | ||
var _lodash = require('../../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -23,13 +23,13 @@ var _create = require('../create'); | ||
return _lodashWrap2.default.every(containings, function (containing) { | ||
if (_lodashWrap2.default.isArray(containing)) { | ||
return _lodashWrap2.default.some(actualArg, function (actualElement) { | ||
return _lodashWrap2.default.isEqual(actualElement, containing); | ||
return _lodash2.default.every(containings, function (containing) { | ||
if (_lodash2.default.isArray(containing)) { | ||
return _lodash2.default.some(actualArg, function (actualElement) { | ||
return _lodash2.default.isEqual(actualElement, containing); | ||
}); | ||
} else if (_lodashWrap2.default.isRegExp(containing)) { | ||
} else if (_lodash2.default.isRegExp(containing)) { | ||
return containing.test(actualArg); | ||
} else if (_lodashWrap2.default.isObjectLike(containing) && _lodashWrap2.default.isObjectLike(actualArg)) { | ||
} else if (_lodash2.default.isObjectLike(containing) && _lodash2.default.isObjectLike(actualArg)) { | ||
return containsAllSpecified(containing, actualArg); | ||
} else { | ||
return _lodashWrap2.default.includes(actualArg, containing); | ||
return _lodash2.default.includes(actualArg, containing); | ||
} | ||
@@ -42,5 +42,5 @@ }); | ||
var containsAllSpecified = function containsAllSpecified(containing, actual) { | ||
return actual != null && _lodashWrap2.default.every(containing, function (val, key) { | ||
return _lodashWrap2.default.isObjectLike(val) ? containsAllSpecified(val, actual[key]) : _lodashWrap2.default.isEqual(val, actual[key]); | ||
return actual != null && _lodash2.default.every(containing, function (val, key) { | ||
return _lodash2.default.isObjectLike(val) ? containsAllSpecified(val, actual[key]) : _lodash2.default.isEqual(val, actual[key]); | ||
}); | ||
}; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../../util/lodash-wrap'); | ||
var _lodash = require('../../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -24,3 +24,3 @@ var _create = require('../create'); | ||
name: function name(matcherArgs) { | ||
var desc = _lodashWrap2.default.get(matcherArgs[0], 'name') || (0, _arguments2.default)(matcherArgs); | ||
var desc = _lodash2.default.get(matcherArgs[0], 'name') || (0, _arguments2.default)(matcherArgs); | ||
return 'isA(' + desc + ')'; | ||
@@ -32,7 +32,7 @@ }, | ||
if (type === Number) { | ||
return _lodashWrap2.default.isNumber(actual); | ||
return _lodash2.default.isNumber(actual); | ||
} else if (type === String) { | ||
return _lodashWrap2.default.isString(actual); | ||
return _lodash2.default.isString(actual); | ||
} else if (type === Boolean) { | ||
return _lodashWrap2.default.isBoolean(actual); | ||
return _lodash2.default.isBoolean(actual); | ||
} else { | ||
@@ -39,0 +39,0 @@ return actual instanceof type; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../../util/lodash-wrap'); | ||
var _lodash = require('../../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -22,4 +22,4 @@ var _create = require('../create'); | ||
var expected = matcherArgs[0]; | ||
return !_lodashWrap2.default.isEqual(expected, actual); | ||
return !_lodash2.default.isEqual(expected, actual); | ||
} | ||
}); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -24,3 +24,3 @@ var _arguments = require('../stringify/arguments'); | ||
return _lodashWrap2.default.tap({ | ||
return _lodash2.default.tap({ | ||
__name: nameFor(config, matcherArgs), | ||
@@ -31,3 +31,6 @@ __matches: function __matches(actualArg) { | ||
}, function (matcherInstance) { | ||
return _lodashWrap2.default.invoke(config, 'onCreate', matcherInstance, matcherArgs); | ||
matcherInstance.__matches.afterSatisfaction = function (actualArg) { | ||
_lodash2.default.invoke(config, 'afterSatisfaction', matcherArgs, actualArg); | ||
}; | ||
_lodash2.default.invoke(config, 'onCreate', matcherInstance, matcherArgs); | ||
}); | ||
@@ -38,3 +41,3 @@ }; | ||
var nameFor = function nameFor(config, matcherArgs) { | ||
if (_lodashWrap2.default.isFunction(config.name)) { | ||
if (_lodash2.default.isFunction(config.name)) { | ||
return config.name(matcherArgs); | ||
@@ -41,0 +44,0 @@ } else if (config.name != null) { |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -29,3 +29,3 @@ var _log = require('./log'); | ||
exports.default = function (nameOrType, config) { | ||
return _lodashWrap2.default.tap(fakeObject(nameOrType, config), function (obj) { | ||
return _lodash2.default.tap(fakeObject(nameOrType, config), function (obj) { | ||
addToStringToDouble(obj, nameOrType); | ||
@@ -36,9 +36,9 @@ }); | ||
var fakeObject = function fakeObject(nameOrType, config) { | ||
if (_lodashWrap2.default.isArray(nameOrType)) { | ||
if (_lodash2.default.isArray(nameOrType)) { | ||
return createTestDoublesForFunctionNames(nameOrType); | ||
} else if (_lodashWrap2.default.isObjectLike(nameOrType)) { | ||
} else if (_lodash2.default.isObjectLike(nameOrType)) { | ||
return (0, _imitate2.default)(nameOrType); | ||
} else if (_lodashWrap2.default.isString(nameOrType) || nameOrType === undefined) { | ||
} else if (_lodash2.default.isString(nameOrType) || nameOrType === undefined) { | ||
return createTestDoubleViaProxy(nameOrType, withDefaults(config)); | ||
} else if (_lodashWrap2.default.isFunction(nameOrType)) { | ||
} else if (_lodash2.default.isFunction(nameOrType)) { | ||
ensureFunctionIsNotPassed(); | ||
@@ -51,3 +51,3 @@ } else { | ||
var createTestDoublesForFunctionNames = function createTestDoublesForFunctionNames(names) { | ||
return _lodashWrap2.default.transform(names, function (acc, funcName) { | ||
return _lodash2.default.transform(names, function (acc, funcName) { | ||
acc[funcName] = (0, _function2.default)('.' + funcName); | ||
@@ -62,3 +62,3 @@ }); | ||
get: function get(target, propKey, receiver) { | ||
if (!obj.hasOwnProperty(propKey) && !_lodashWrap2.default.includes(config.excludeMethods, propKey)) { | ||
if (!obj.hasOwnProperty(propKey) && !_lodash2.default.includes(config.excludeMethods, propKey)) { | ||
obj[propKey] = (0, _function2.default)(nameOf(name) + '.' + propKey); | ||
@@ -86,3 +86,3 @@ } | ||
var withDefaults = function withDefaults(config) { | ||
return _lodashWrap2.default.extend({}, DEFAULT_OPTIONS, config); | ||
return _lodash2.default.extend({}, DEFAULT_OPTIONS, config); | ||
}; | ||
@@ -98,3 +98,3 @@ | ||
var nameOf = function nameOf(nameOrType) { | ||
return _lodashWrap2.default.isString(nameOrType) ? nameOrType : ''; | ||
return _lodash2.default.isString(nameOrType) ? nameOrType : ''; | ||
}; |
@@ -8,3 +8,3 @@ 'use strict'; | ||
exports.default = function (target) { | ||
if (_lodashWrap2.default.isString(target)) { | ||
if (_lodash2.default.isString(target)) { | ||
return _module2.default.apply(undefined, arguments); | ||
@@ -16,5 +16,5 @@ } else { | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -21,0 +21,0 @@ var _quibble = require('quibble'); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -15,5 +15,5 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.default = function (thing) { | ||
return thing && thing.prototype && _lodashWrap2.default.some(Object.getOwnPropertyNames(thing.prototype), function (property) { | ||
return property !== 'constructor' && _lodashWrap2.default.isFunction(thing.prototype[property]); | ||
return thing && thing.prototype && _lodash2.default.some(Object.getOwnPropertyNames(thing.prototype), function (property) { | ||
return property !== 'constructor' && _lodash2.default.isFunction(thing.prototype[property]); | ||
}); | ||
}; |
@@ -15,3 +15,3 @@ 'use strict'; | ||
var realThing = object[property]; | ||
return _lodashWrap2.default.tap(getFake(isManual, property, manualReplacement, realThing), function (fakeThing) { | ||
return _lodash2.default.tap(getFake(isManual, property, manualReplacement, realThing), function (fakeThing) { | ||
object[property] = fakeThing; | ||
@@ -31,5 +31,5 @@ _reset2.default.onNextReset(function () { | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -67,4 +67,4 @@ var _imitate = require('../imitate'); | ||
if (realThing !== undefined && fakeType !== realType) { | ||
_log2.default.warn('td.replace', 'property "' + property + '" ' + (0, _anything2.default)(realThing) + ' (' + _lodashWrap2.default.capitalize(realType) + ') was replaced with ' + (0, _anything2.default)(fakeThing) + ', which has a different type (' + _lodashWrap2.default.capitalize(fakeType) + ').'); | ||
_log2.default.warn('td.replace', 'property "' + property + '" ' + (0, _anything2.default)(realThing) + ' (' + _lodash2.default.capitalize(realType) + ') was replaced with ' + (0, _anything2.default)(fakeThing) + ', which has a different type (' + _lodash2.default.capitalize(fakeType) + ').'); | ||
} | ||
}; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -24,6 +24,6 @@ var _quibble = require('quibble'); | ||
exports.default = _lodashWrap2.default.tap(function () { | ||
exports.default = _lodash2.default.tap(function () { | ||
_store2.default.reset(); | ||
_quibble2.default.reset(); | ||
_lodashWrap2.default.each(resetHandlers, function (resetHandler) { | ||
_lodash2.default.each(resetHandlers, function (resetHandler) { | ||
return resetHandler(); | ||
@@ -30,0 +30,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -6,16 +6,30 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = satisfy; | ||
// import _ from '../wrap/lodash' | ||
var _findLastStubbingMatch = require('./find-last-stubbing-match'); | ||
exports.default = function (call, stubbings) { | ||
// RTODO: dummy impl to drive create feature first | ||
return stubbings ? stubbings[0].outcomes[0] : undefined; | ||
var _findLastStubbingMatch2 = _interopRequireDefault(_findLastStubbingMatch); | ||
// 1. find the last matching stubbing (args+conditions match + has values left) | ||
// 2. six-way switch to execute the correct plan switching on the stubbing's `type` | ||
var _invokeCallbacks = require('./invoke-callbacks'); | ||
// see src/store/stubbings.isSatisfied for a full solution (arg matchers + multi-plan, etc) | ||
// const stubbing _.findLast(stubbings, (stubbing) => | ||
// stubbing.isSatisfiedBy(call) | ||
// ) | ||
}; | ||
var _invokeCallbacks2 = _interopRequireDefault(_invokeCallbacks); | ||
var _notifyAfterSatisfaction = require('../matchers/notify-after-satisfaction'); | ||
var _notifyAfterSatisfaction2 = _interopRequireDefault(_notifyAfterSatisfaction); | ||
var _deliverOutcome = require('./deliver-outcome'); | ||
var _deliverOutcome2 = _interopRequireDefault(_deliverOutcome); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function satisfy(double, call) { | ||
var stubbing = (0, _findLastStubbingMatch2.default)(double, call); | ||
if (stubbing) { | ||
stubbing.addSatisfyingCall(call); | ||
(0, _invokeCallbacks2.default)(stubbing, call); | ||
(0, _notifyAfterSatisfaction2.default)(stubbing.args, call.args); | ||
return (0, _deliverOutcome2.default)(stubbing, call); | ||
} | ||
} |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -33,3 +33,3 @@ var _argsMatch = require('../args-match'); | ||
pop: function pop() { | ||
return _lodashWrap2.default.tap(callHistory.pop(), function (call) { | ||
return _lodash2.default.tap(callHistory.pop(), function (call) { | ||
if (call != null) { | ||
@@ -49,3 +49,3 @@ _index2.default.for(call.testDouble).calls.pop(); | ||
where: function where(testDouble, args, config) { | ||
return _lodashWrap2.default.filter(_index2.default.for(testDouble).calls, function (call) { | ||
return _lodash2.default.filter(_index2.default.for(testDouble).calls, function (call) { | ||
return (0, _argsMatch2.default)(args, call.args, config); | ||
@@ -52,0 +52,0 @@ }); |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -30,7 +30,7 @@ var _events = require('events'); | ||
var entry = _lodashWrap2.default.find(globalStore, { testDouble: testDouble }); | ||
var entry = _lodash2.default.find(globalStore, { testDouble: testDouble }); | ||
if (entry) { | ||
return entry; | ||
} else if (createIfNew) { | ||
return _lodashWrap2.default.tap({ | ||
return _lodash2.default.tap({ | ||
testDouble: testDouble, | ||
@@ -37,0 +37,0 @@ stubbings: [], |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -16,6 +16,10 @@ var _argsMatch = require('../args-match'); | ||
var _callback = require('../callback'); | ||
var _isCallback = require('../matchers/is-callback'); | ||
var _callback2 = _interopRequireDefault(_callback); | ||
var _isCallback2 = _interopRequireDefault(_isCallback); | ||
var _notifyAfterSatisfaction = require('../matchers/notify-after-satisfaction'); | ||
var _notifyAfterSatisfaction2 = _interopRequireDefault(_notifyAfterSatisfaction); | ||
var _config = require('../config'); | ||
@@ -49,2 +53,3 @@ | ||
if (stubbing) { | ||
(0, _notifyAfterSatisfaction2.default)(stubbing.args, actualArgs); | ||
return executePlan(stubbing, actualArgs, actualContext); | ||
@@ -60,3 +65,3 @@ } | ||
var stubbingFor = function stubbingFor(testDouble, actualArgs) { | ||
return _lodashWrap2.default.findLast(_index2.default.for(testDouble).stubbings, function (stubbing) { | ||
return _lodash2.default.findLast(_index2.default.for(testDouble).stubbings, function (stubbing) { | ||
return isSatisfied(stubbing, actualArgs); | ||
@@ -85,5 +90,5 @@ }); | ||
var invokeCallbackFor = function invokeCallbackFor(stubbing, actualArgs) { | ||
if (_lodashWrap2.default.some(stubbing.args, _callback2.default.isCallback)) { | ||
_lodashWrap2.default.each(stubbing.args, function (expectedArg, i) { | ||
if (_callback2.default.isCallback(expectedArg)) { | ||
if (_lodash2.default.some(stubbing.args, _isCallback2.default)) { | ||
_lodash2.default.each(stubbing.args, function (expectedArg, i) { | ||
if ((0, _isCallback2.default)(expectedArg)) { | ||
callCallback(stubbing, actualArgs[i], callbackArgs(stubbing, expectedArg)); | ||
@@ -107,7 +112,7 @@ } | ||
if (stubbing.config.delay) { | ||
return _lodashWrap2.default.delay.apply(_lodashWrap2.default, [callback, stubbing.config.delay].concat(_toConsumableArray(args))); | ||
_lodash2.default.delay.apply(_lodash2.default, [callback, stubbing.config.delay].concat(_toConsumableArray(args))); | ||
} else if (stubbing.config.defer) { | ||
return _lodashWrap2.default.defer.apply(_lodashWrap2.default, [callback].concat(_toConsumableArray(args))); | ||
_lodash2.default.defer.apply(_lodash2.default, [callback].concat(_toConsumableArray(args))); | ||
} else { | ||
return callback.apply(undefined, _toConsumableArray(args)); // eslint-disable-line | ||
callback.apply(undefined, _toConsumableArray(args)); // eslint-disable-line | ||
} | ||
@@ -127,3 +132,3 @@ }; | ||
var stubbedValueFor = function stubbedValueFor(stubbing) { | ||
return stubbing.callCount < stubbing.stubbedValues.length ? stubbing.stubbedValues[stubbing.callCount] : _lodashWrap2.default.last(stubbing.stubbedValues); | ||
return stubbing.callCount < stubbing.stubbedValues.length ? stubbing.stubbedValues[stubbing.callCount] : _lodash2.default.last(stubbing.stubbedValues); | ||
}; | ||
@@ -130,0 +135,0 @@ |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -23,3 +23,3 @@ var _isMatcher = require('../matchers/is-matcher'); | ||
exports.default = function (anything) { | ||
if (_lodashWrap2.default.isString(anything)) { | ||
if (_lodash2.default.isString(anything)) { | ||
return stringifyString(anything); | ||
@@ -45,3 +45,3 @@ } else if ((0, _isMatcher2.default)(anything)) { | ||
var stringifyString = function stringifyString(string) { | ||
return _lodashWrap2.default.includes(string, '\n') ? '"""\n' + string + '\n"""' : '"' + string.replace(new RegExp('"', 'g'), '\\"') + '"'; | ||
return _lodash2.default.includes(string, '\n') ? '"""\n' + string + '\n"""' : '"' + string.replace(new RegExp('"', 'g'), '\\"') + '"'; | ||
}; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('../util/lodash-wrap'); | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -21,5 +21,5 @@ var _anything = require('./anything'); | ||
var wrapper = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : ''; | ||
return _lodashWrap2.default.map(args, function (arg) { | ||
return _lodash2.default.map(args, function (arg) { | ||
return '' + wrapper + (0, _anything2.default)(arg) + wrapper; | ||
}).join(joiner); | ||
}; |
@@ -18,3 +18,12 @@ 'use strict'; | ||
var Double = function () { | ||
function Double(name, real, fake) { | ||
_createClass(Double, null, [{ | ||
key: 'create', | ||
value: function create(name, real, parent, fakeCreator) { | ||
var double = new Double(name, real, parent); | ||
if (fakeCreator) double.fake = fakeCreator(double); | ||
return double; | ||
} | ||
}]); | ||
function Double(name, real, parent) { | ||
_classCallCheck(this, Double); | ||
@@ -24,5 +33,7 @@ | ||
this.real = real; | ||
this.fake = fake; | ||
this.parent = undefined; | ||
this.children = new Set(); | ||
if (parent) { | ||
this.parent = parent; | ||
parent.addChild(this); | ||
} | ||
} | ||
@@ -37,2 +48,7 @@ | ||
}, { | ||
key: 'toString', | ||
value: function toString() { | ||
return this.fullName == null ? '[test double (unnamed)]' : '[test double for "' + this.fullName + '"]'; | ||
} | ||
}, { | ||
key: 'fullName', | ||
@@ -39,0 +55,0 @@ get: function get() { |
@@ -13,6 +13,2 @@ 'use strict'; | ||
var _satisfy2 = require('../satisfy'); | ||
var _satisfy3 = _interopRequireDefault(_satisfy2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -55,7 +51,2 @@ | ||
}, { | ||
key: 'satisfy', | ||
value: function satisfy(double, call) { | ||
return (0, _satisfy3.default)(call, this.stubbings.get(double)); | ||
} | ||
}, { | ||
key: 'get', | ||
@@ -62,0 +53,0 @@ value: function get(double) { |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -9,2 +9,8 @@ Object.defineProperty(exports, "__esModule", { | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
@@ -22,15 +28,26 @@ | ||
this.options = options; | ||
this.satisfactionCount = 0; | ||
this.satisfyingCalls = new Set(); | ||
} | ||
_createClass(Stubbing, [{ | ||
key: "incrementSatisfactions", | ||
value: function incrementSatisfactions() { | ||
this.satisfactionCount++; | ||
key: 'addSatisfyingCall', | ||
value: function addSatisfyingCall(call) { | ||
this.satisfyingCalls.add(call); | ||
} | ||
}, { | ||
key: "timesSatisfied", | ||
key: 'hasTimesRemaining', | ||
get: function get() { | ||
return this.satisfactionCount; | ||
if (this.options.times == null) return true; | ||
return this.satisfyingCalls.size < this.options.times; | ||
} | ||
}, { | ||
key: 'currentOutcome', | ||
get: function get() { | ||
var outcomeIndex = Math.max(0, this.satisfyingCalls.size - 1); | ||
if (outcomeIndex < this.outcomes.length) { | ||
return this.outcomes[outcomeIndex]; | ||
} else { | ||
return _lodash2.default.last(this.outcomes); | ||
} | ||
} | ||
}]); | ||
@@ -37,0 +54,0 @@ |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -36,2 +36,6 @@ var _argsMatch = require('./args-match'); | ||
var _notifyAfterSatisfaction = require('./matchers/notify-after-satisfaction'); | ||
var _notifyAfterSatisfaction2 = _interopRequireDefault(_notifyAfterSatisfaction); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -45,3 +49,3 @@ | ||
if (_calls2.default.wasInvoked(last.testDouble, last.args, config)) { | ||
// Do nothing! We're verified! :-D | ||
notifyMatchers(last.testDouble, last.args, config); | ||
warnIfStubbed(last.testDouble, last.args); | ||
@@ -59,4 +63,10 @@ } else { | ||
var notifyMatchers = function notifyMatchers(testDouble, expectedArgs, config) { | ||
_lodash2.default.each(_calls2.default.where(testDouble, expectedArgs, config), function (invocation) { | ||
(0, _notifyAfterSatisfaction2.default)(expectedArgs, invocation.args); | ||
}); | ||
}; | ||
var warnIfStubbed = function warnIfStubbed(testDouble, actualArgs) { | ||
if (_lodashWrap2.default.some(_stubbings2.default.for(testDouble), function (stubbing) { | ||
if (_lodash2.default.some(_stubbings2.default.for(testDouble), function (stubbing) { | ||
return (0, _argsMatch2.default)(stubbing.args, actualArgs, stubbing.config); | ||
@@ -86,3 +96,3 @@ })) { | ||
} else { | ||
return _lodashWrap2.default.reduce(calls, function (desc, call) { | ||
return _lodash2.default.reduce(calls, function (desc, call) { | ||
return desc + ('\n - called with `(' + (0, _arguments2.default)(call.args) + ')`.'); | ||
@@ -100,3 +110,3 @@ }, '\n\n All calls of the test double, in order were:'); | ||
} else { | ||
return _lodashWrap2.default.reduce(_lodashWrap2.default.groupBy(calls, 'args'), function (desc, callsMatchingArgs, args) { | ||
return _lodash2.default.reduce(_lodash2.default.groupBy(calls, 'args'), function (desc, callsMatchingArgs, args) { | ||
return desc + ('\n - called ' + pluralize(callsMatchingArgs.length, 'time') + ' with `(' + (0, _arguments2.default)(callsMatchingArgs[0].args) + ')`.'); | ||
@@ -103,0 +113,0 @@ }, '\n\n ' + pluralize(calls.length, 'call') + ' that satisfied this verification:'); |
@@ -6,2 +6,2 @@ 'use strict'; | ||
}); | ||
exports.default = '3.2.6'; | ||
exports.default = '3.2.7'; |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _lodashWrap = require('./util/lodash-wrap'); | ||
var _lodash = require('./wrap/lodash'); | ||
var _lodashWrap2 = _interopRequireDefault(_lodashWrap); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
@@ -16,2 +16,6 @@ var _callback = require('./callback'); | ||
var _isCallback = require('./matchers/is-callback'); | ||
var _isCallback2 = _interopRequireDefault(_isCallback); | ||
var _calls = require('./store/calls'); | ||
@@ -90,3 +94,3 @@ | ||
ensureRehearsalOccurred(last); | ||
_lodashWrap2.default.assign(config, { plan: plan }); | ||
_lodash2.default.assign(config, { plan: plan }); | ||
_stubbings2.default.add(last.testDouble, concatImpliedCallback(last.args, config), stubbedValues, config); | ||
@@ -105,3 +109,3 @@ return last.testDouble; | ||
return args; | ||
} else if (!_lodashWrap2.default.some(args, _callback2.default.isCallback)) { | ||
} else if (!_lodash2.default.some(args, _isCallback2.default)) { | ||
return args.concat(_callback2.default); | ||
@@ -108,0 +112,0 @@ } else { |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -7,2 +7,22 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.default = function () {}; | ||
exports.default = function (type, args) { | ||
if (type === 'thenCallback' && !_lodash2.default.some(args, _isCallback2.default)) { | ||
return args.concat(_callback2.default); | ||
} else { | ||
return args; | ||
} | ||
}; | ||
var _lodash = require('../wrap/lodash'); | ||
var _lodash2 = _interopRequireDefault(_lodash); | ||
var _isCallback = require('../matchers/is-callback'); | ||
var _isCallback2 = _interopRequireDefault(_isCallback); | ||
var _callback = require('../callback'); | ||
var _callback2 = _interopRequireDefault(_callback); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -6,3 +6,65 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = chainStubbing; | ||
exports.default = function () {}; | ||
var _ensurePromise = require('../log/ensure-promise'); | ||
var _ensurePromise2 = _interopRequireDefault(_ensurePromise); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function chainStubbing(double, completeStubbing) { | ||
return { | ||
thenReturn: function thenReturn() { | ||
for (var _len = arguments.length, stubbedValues = Array(_len), _key = 0; _key < _len; _key++) { | ||
stubbedValues[_key] = arguments[_key]; | ||
} | ||
completeStubbing('thenReturn', stubbedValues); | ||
return double.fake; | ||
}, | ||
thenCallback: function thenCallback() { | ||
for (var _len2 = arguments.length, stubbedValues = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { | ||
stubbedValues[_key2] = arguments[_key2]; | ||
} | ||
completeStubbing('thenCallback', stubbedValues); | ||
return double.fake; | ||
}, | ||
thenDo: function thenDo() { | ||
for (var _len3 = arguments.length, stubbedActions = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { | ||
stubbedActions[_key3] = arguments[_key3]; | ||
} | ||
completeStubbing('thenDo', stubbedActions); | ||
return double.fake; | ||
}, | ||
thenThrow: function thenThrow() { | ||
for (var _len4 = arguments.length, stubbedErrors = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { | ||
stubbedErrors[_key4] = arguments[_key4]; | ||
} | ||
completeStubbing('thenThrow', stubbedErrors); | ||
return double.fake; | ||
}, | ||
thenResolve: function thenResolve() { | ||
(0, _ensurePromise2.default)('warn'); | ||
for (var _len5 = arguments.length, stubbedValues = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { | ||
stubbedValues[_key5] = arguments[_key5]; | ||
} | ||
completeStubbing('thenResolve', stubbedValues); | ||
return double.fake; | ||
}, | ||
thenReject: function thenReject() { | ||
(0, _ensurePromise2.default)('warn'); | ||
for (var _len6 = arguments.length, stubbedErrors = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) { | ||
stubbedErrors[_key6] = arguments[_key6]; | ||
} | ||
completeStubbing('thenReject', stubbedErrors); | ||
return double.fake; | ||
} | ||
}; | ||
} |
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -6,3 +6,14 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.default = ensureRehearsal; | ||
exports.default = function () {}; | ||
var _log = require('../log'); | ||
var _log2 = _interopRequireDefault(_log); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function ensureRehearsal(rehearsal) { | ||
if (!rehearsal) { | ||
_log2.default.error('td.when', 'No test double invocation call detected for `when()`.\n\n Usage:\n when(myTestDouble(\'foo\')).thenReturn(\'bar\')'); | ||
} | ||
} |
@@ -36,5 +36,5 @@ 'use strict'; | ||
(0, _ensureRehearsal2.default)(rehearsal); | ||
return (0, _chainStubbing2.default)(function (type, outcomes) { | ||
return (0, _chainStubbing2.default)(rehearsal.double, function (type, outcomes) { | ||
_stubbingRegister2.default.instance.add(rehearsal.double, new _stubbing2.default(type, (0, _addImpliedCallbackArgIfNecessary2.default)(type, rehearsal.call.args), outcomes, options)); | ||
}); | ||
}; |
{ | ||
"name": "testdouble", | ||
"version": "3.2.6", | ||
"version": "3.2.7", | ||
"description": "A minimal test double library for TDD with JavaScript", | ||
@@ -33,6 +33,6 @@ "homepage": "https://github.com/testdouble/testdouble.js", | ||
"test:typescript": "tsc --outDir generated/typescript -p regression/typescript && node generated/typescript/test.js", | ||
"test:example:webpack": "cd examples/webpack && yarn install && yarn test && cd ../..", | ||
"test:example:node": "cd examples/node && yarn install && yarn test && cd ../..", | ||
"test:example:lineman": "cd examples/lineman && yarn install && yarn test && cd ../..", | ||
"test:example:babel": "cd examples/babel && yarn install && yarn test && cd ../..", | ||
"test:example:webpack": "cd examples/webpack && npm it", | ||
"test:example:node": "cd examples/node && npm it", | ||
"test:example:lineman": "cd examples/lineman && yarn install && yarn test", | ||
"test:example:babel": "cd examples/babel && npm it", | ||
"test:example": "yarn run test:example:node && yarn run test:example:lineman && yarn run test:example:webpack && yarn run test:example:babel", | ||
@@ -99,3 +99,3 @@ "version:write": "echo \"export default '$npm_package_version'\" > src/version.js", | ||
"chai": "^3.2.0", | ||
"codeclimate-test-reporter": "^0.4.1", | ||
"codeclimate-test-reporter": "^0.5.0", | ||
"coffee-script": "^1.10.0", | ||
@@ -113,4 +113,4 @@ "coffeeify": "^2.1.0", | ||
"standard": "^10.0.2", | ||
"teenytest": "^5.0.2", | ||
"testdouble": "3.2.1", | ||
"teenytest": "^5.1.1", | ||
"testdouble": "3.2.6", | ||
"testem": "^1.18.0", | ||
@@ -117,0 +117,0 @@ "typescript": "^2.4.1" |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import isMatcher from './matchers/is-matcher' | ||
@@ -3,0 +3,0 @@ |
@@ -1,5 +0,5 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import create from './matchers/create' | ||
export default _.tap(create({ | ||
const callback = create({ | ||
name: 'callback', | ||
@@ -13,9 +13,8 @@ matches (matcherArgs, actual) { | ||
} | ||
}), (callback) => { | ||
// Make callback itself quack like a matcher for its non-invoked use case. | ||
callback.__name = 'callback' | ||
callback.__matches = _.isFunction | ||
}) | ||
callback.isCallback = obj => | ||
obj && (obj === callback || obj.__testdouble_callback === true) | ||
}) | ||
// Make callback itself quack like a matcher for its non-invoked use case. | ||
callback.__name = 'callback' | ||
callback.__matches = _.isFunction | ||
export default callback |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import log from './log' | ||
@@ -3,0 +3,0 @@ import stringifyAnything from './stringify/anything' |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import tdFunction from './function' | ||
@@ -3,0 +3,0 @@ import imitate from './imitate' |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import callsStore from './store/calls' | ||
@@ -3,0 +3,0 @@ import store from './store' |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import calls from './store/calls' | ||
@@ -3,0 +3,0 @@ import store from './store' |
@@ -1,25 +0,6 @@ | ||
import _ from '../wrap/lodash' | ||
import Double from '../value/double' | ||
import CallLog from '../value/call-log' | ||
import Call from '../value/call' | ||
import StubbingRegister from '../value/stubbing-register' | ||
import generateFakeFunction from './generate-fake-function' | ||
export default (nameOrFunc) => { | ||
const name = deriveName(nameOrFunc) | ||
const real = _.isFunction(nameOrFunc) ? nameOrFunc : null | ||
const double = new Double(name, real, _.tap(function testDouble (...args) { | ||
const call = new Call(this, args) | ||
CallLog.instance.log(double, call) | ||
return StubbingRegister.instance.satisfy(double, call) | ||
}, (fakeFunction) => { | ||
fakeFunction.toString = () => | ||
double.fullName == null ? '[test double (unnamed)]' : `[test double for "${double.fullName}"]` | ||
})) | ||
return double | ||
export default function create (name, real, parent) { | ||
return Double.create(name, real, parent, generateFakeFunction) | ||
} | ||
const deriveName = (nameOrFunc) => { | ||
const name = _.isFunction(nameOrFunc) ? nameOrFunc.name : nameOrFunc | ||
return _.isEmpty(name) ? null : name | ||
} |
import _ from '../wrap/lodash' | ||
import create from './create' | ||
import imitate from '../imitate' | ||
import remember from './remember' | ||
export default (nameOrFunc) => { | ||
if (_.isFunction(nameOrFunc)) return imitate(nameOrFunc) | ||
const double = create(nameOrFunc) | ||
remember(double) | ||
return double.fake | ||
export default function func (nameOrFunc) { | ||
if (_.isFunction(nameOrFunc)) { | ||
return create(_.isEmpty(nameOrFunc.name) ? null : nameOrFunc.name, nameOrFunc).fake | ||
} else { | ||
return create(nameOrFunc, null).fake | ||
} | ||
} |
@@ -13,2 +13,3 @@ import _ from '../wrap/lodash' | ||
} else { | ||
// TODO: this will become src/function/create and include parent reference instead of name joining here | ||
return tdFunction(names.join('') || '(anonymous function)') | ||
@@ -15,0 +16,0 @@ } |
@@ -8,6 +8,8 @@ import create from '../create' | ||
matches (matcherArgs, actual) { | ||
return true | ||
}, | ||
afterSatisfaction (matcherArgs, actual) { | ||
captor.values = captor.values || [] | ||
captor.values.push(actual) | ||
captor.value = actual | ||
return true | ||
} | ||
@@ -14,0 +16,0 @@ }) |
@@ -1,2 +0,2 @@ | ||
import _ from '../../util/lodash-wrap' | ||
import _ from '../../wrap/lodash' | ||
import create from '../create' | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
import _ from '../../util/lodash-wrap' | ||
import _ from '../../wrap/lodash' | ||
import create from '../create' | ||
@@ -3,0 +3,0 @@ import stringifyArguments from '../../stringify/arguments' |
@@ -1,2 +0,2 @@ | ||
import _ from '../../util/lodash-wrap' | ||
import _ from '../../wrap/lodash' | ||
import create from '../create' | ||
@@ -3,0 +3,0 @@ |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import stringifyArguments from '../stringify/arguments' | ||
@@ -11,5 +11,8 @@ | ||
} | ||
}, (matcherInstance) => | ||
}, (matcherInstance) => { | ||
matcherInstance.__matches.afterSatisfaction = (actualArg) => { | ||
_.invoke(config, 'afterSatisfaction', matcherArgs, actualArg) | ||
} | ||
_.invoke(config, 'onCreate', matcherInstance, matcherArgs) | ||
) | ||
}) | ||
@@ -16,0 +19,0 @@ var nameFor = (config, matcherArgs) => { |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import log from './log' | ||
@@ -3,0 +3,0 @@ import tdFunction from './function' |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import quibble from 'quibble' | ||
@@ -3,0 +3,0 @@ import replaceModule from './module' |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
@@ -3,0 +3,0 @@ export default (thing) => |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import imitate from '../imitate' | ||
@@ -3,0 +3,0 @@ import log from '../log' |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import quibble from 'quibble' | ||
@@ -3,0 +3,0 @@ import store from './store' |
@@ -1,14 +0,14 @@ | ||
// import _ from '../wrap/lodash' | ||
import findLastStubbingMatch from './find-last-stubbing-match' | ||
import invokeCallbacks from './invoke-callbacks' | ||
import notifyAfterSatisfaction from '../matchers/notify-after-satisfaction' | ||
import deliverOutcome from './deliver-outcome' | ||
export default (call, stubbings) => { | ||
// RTODO: dummy impl to drive create feature first | ||
return stubbings ? stubbings[0].outcomes[0] : undefined | ||
// 1. find the last matching stubbing (args+conditions match + has values left) | ||
// 2. six-way switch to execute the correct plan switching on the stubbing's `type` | ||
// see src/store/stubbings.isSatisfied for a full solution (arg matchers + multi-plan, etc) | ||
// const stubbing _.findLast(stubbings, (stubbing) => | ||
// stubbing.isSatisfiedBy(call) | ||
// ) | ||
export default function satisfy (double, call) { | ||
const stubbing = findLastStubbingMatch(double, call) | ||
if (stubbing) { | ||
stubbing.addSatisfyingCall(call) | ||
invokeCallbacks(stubbing, call) | ||
notifyAfterSatisfaction(stubbing.args, call.args) | ||
return deliverOutcome(stubbing, call) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import argsMatch from '../args-match' | ||
@@ -3,0 +3,0 @@ import store from './index' |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import { EventEmitter } from 'events' | ||
@@ -3,0 +3,0 @@ |
@@ -1,4 +0,5 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import argsMatch from '../args-match' | ||
import callback from '../callback' | ||
import isCallback from '../matchers/is-callback' | ||
import notifyAfterSatisfaction from '../matchers/notify-after-satisfaction' | ||
import config from '../config' | ||
@@ -21,2 +22,3 @@ import log from '../log' | ||
if (stubbing) { | ||
notifyAfterSatisfaction(stubbing.args, actualArgs) | ||
return executePlan(stubbing, actualArgs, actualContext) | ||
@@ -49,5 +51,5 @@ } | ||
var invokeCallbackFor = (stubbing, actualArgs) => { | ||
if (_.some(stubbing.args, callback.isCallback)) { | ||
if (_.some(stubbing.args, isCallback)) { | ||
_.each(stubbing.args, (expectedArg, i) => { | ||
if (callback.isCallback(expectedArg)) { | ||
if (isCallback(expectedArg)) { | ||
callCallback(stubbing, actualArgs[i], callbackArgs(stubbing, expectedArg)) | ||
@@ -71,7 +73,7 @@ } | ||
if (stubbing.config.delay) { | ||
return _.delay(callback, stubbing.config.delay, ...args) | ||
_.delay(callback, stubbing.config.delay, ...args) | ||
} else if (stubbing.config.defer) { | ||
return _.defer(callback, ...args) | ||
_.defer(callback, ...args) | ||
} else { | ||
return callback(...args) // eslint-disable-line | ||
callback(...args) // eslint-disable-line | ||
} | ||
@@ -78,0 +80,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import isMatcher from '../matchers/is-matcher' | ||
@@ -3,0 +3,0 @@ import stringifyObject from 'stringify-object-es5' |
@@ -1,2 +0,2 @@ | ||
import _ from '../util/lodash-wrap' | ||
import _ from '../wrap/lodash' | ||
import stringifyAnything from './anything' | ||
@@ -3,0 +3,0 @@ |
import _ from '../wrap/lodash' | ||
export default class Double { | ||
constructor (name, real, fake) { | ||
static create (name, real, parent, fakeCreator) { | ||
const double = new Double(name, real, parent) | ||
if (fakeCreator) double.fake = fakeCreator(double) | ||
return double | ||
} | ||
constructor (name, real, parent) { | ||
this.name = name | ||
this.real = real | ||
this.fake = fake | ||
this.parent = undefined | ||
this.children = new Set() | ||
if (parent) { | ||
this.parent = parent | ||
parent.addChild(this) | ||
} | ||
} | ||
@@ -28,2 +36,6 @@ | ||
} | ||
toString () { | ||
return this.fullName == null ? '[test double (unnamed)]' : `[test double for "${this.fullName}"]` | ||
} | ||
} |
import Map from 'es6-map' | ||
import satisfy from '../satisfy' | ||
let instance = null | ||
@@ -30,6 +28,2 @@ | ||
satisfy (double, call) { | ||
return satisfy(call, this.stubbings.get(double)) | ||
} | ||
get (double) { | ||
@@ -36,0 +30,0 @@ return this.stubbings.get(double) |
@@ -0,1 +1,3 @@ | ||
import _ from '../wrap/lodash' | ||
export default class Stubbing { | ||
@@ -7,12 +9,22 @@ constructor (type, args, outcomes, options = {}) { | ||
this.options = options | ||
this.satisfactionCount = 0 | ||
this.satisfyingCalls = new Set() | ||
} | ||
get timesSatisfied () { | ||
return this.satisfactionCount | ||
get hasTimesRemaining () { | ||
if (this.options.times == null) return true | ||
return this.satisfyingCalls.size < this.options.times | ||
} | ||
incrementSatisfactions () { | ||
this.satisfactionCount++ | ||
get currentOutcome () { | ||
const outcomeIndex = Math.max(0, this.satisfyingCalls.size - 1) | ||
if (outcomeIndex < this.outcomes.length) { | ||
return this.outcomes[outcomeIndex] | ||
} else { | ||
return _.last(this.outcomes) | ||
} | ||
} | ||
addSatisfyingCall (call) { | ||
this.satisfyingCalls.add(call) | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import argsMatch from './args-match' | ||
@@ -8,2 +8,3 @@ import callsStore from './store/calls' | ||
import stubbingsStore from './store/stubbings' | ||
import notifyAfterSatisfaction from './matchers/notify-after-satisfaction' | ||
@@ -14,3 +15,3 @@ export default (__userDoesRehearsalInvocationHere__, config = {}) => { | ||
if (callsStore.wasInvoked(last.testDouble, last.args, config)) { | ||
// Do nothing! We're verified! :-D | ||
notifyMatchers(last.testDouble, last.args, config) | ||
warnIfStubbed(last.testDouble, last.args) | ||
@@ -33,2 +34,8 @@ } else { | ||
const notifyMatchers = (testDouble, expectedArgs, config) => { | ||
_.each(callsStore.where(testDouble, expectedArgs, config), (invocation) => { | ||
notifyAfterSatisfaction(expectedArgs, invocation.args) | ||
}) | ||
} | ||
var warnIfStubbed = (testDouble, actualArgs) => { | ||
@@ -35,0 +42,0 @@ if (_.some(stubbingsStore.for(testDouble), (stubbing) => |
@@ -1,1 +0,1 @@ | ||
export default '3.2.6' | ||
export default '3.2.7' |
@@ -1,3 +0,4 @@ | ||
import _ from './util/lodash-wrap' | ||
import _ from './wrap/lodash' | ||
import callback from './callback' | ||
import isCallback from './matchers/is-callback' | ||
import calls from './store/calls' | ||
@@ -55,3 +56,3 @@ import log from './log' | ||
return args | ||
} else if (!_.some(args, callback.isCallback)) { | ||
} else if (!_.some(args, isCallback)) { | ||
return args.concat(callback) | ||
@@ -58,0 +59,0 @@ } else { |
@@ -1,1 +0,12 @@ | ||
export default () => {} | ||
import _ from '../wrap/lodash' | ||
import isCallback from '../matchers/is-callback' | ||
import callback from '../callback' | ||
export default function (type, args) { | ||
if (type === 'thenCallback' && !_.some(args, isCallback)) { | ||
return args.concat(callback) | ||
} else { | ||
return args | ||
} | ||
} |
@@ -1,1 +0,32 @@ | ||
export default () => {} | ||
import ensurePromise from '../log/ensure-promise' | ||
export default function chainStubbing (double, completeStubbing) { | ||
return { | ||
thenReturn (...stubbedValues) { | ||
completeStubbing('thenReturn', stubbedValues) | ||
return double.fake | ||
}, | ||
thenCallback (...stubbedValues) { | ||
completeStubbing('thenCallback', stubbedValues) | ||
return double.fake | ||
}, | ||
thenDo (...stubbedActions) { | ||
completeStubbing('thenDo', stubbedActions) | ||
return double.fake | ||
}, | ||
thenThrow (...stubbedErrors) { | ||
completeStubbing('thenThrow', stubbedErrors) | ||
return double.fake | ||
}, | ||
thenResolve (...stubbedValues) { | ||
ensurePromise('warn') | ||
completeStubbing('thenResolve', stubbedValues) | ||
return double.fake | ||
}, | ||
thenReject (...stubbedErrors) { | ||
ensurePromise('warn') | ||
completeStubbing('thenReject', stubbedErrors) | ||
return double.fake | ||
} | ||
} | ||
} |
@@ -1,1 +0,13 @@ | ||
export default () => {} | ||
import log from '../log' | ||
export default function ensureRehearsal (rehearsal) { | ||
if (!rehearsal) { | ||
log.error('td.when', `\ | ||
No test double invocation call detected for \`when()\`. | ||
Usage: | ||
when(myTestDouble('foo')).thenReturn('bar')\ | ||
` | ||
) | ||
} | ||
} |
@@ -11,3 +11,3 @@ import ensureRehearsal from './ensure-rehearsal' | ||
ensureRehearsal(rehearsal) | ||
return chainStubbing((type, outcomes) => { | ||
return chainStubbing(rehearsal.double, (type, outcomes) => { | ||
StubbingRegister.instance.add(rehearsal.double, new Stubbing( | ||
@@ -14,0 +14,0 @@ type, |
@@ -12,3 +12,5 @@ require('babel-core/register')({ | ||
module.exports = { | ||
beforeAll: function () {}, | ||
beforeAll: function () { | ||
require('./support/custom-assertions').default(assert) | ||
}, | ||
beforeEach: function () {}, | ||
@@ -15,0 +17,0 @@ afterEach: function () { |
@@ -1,67 +0,17 @@ | ||
import Double from '../../../src/value/double' | ||
import CallLog from '../../../src/value/call-log' | ||
import StubbingRegister from '../../../src/value/stubbing-register' | ||
import Stubbing from '../../../src/value/stubbing' | ||
import subject from '../../../src/function/create' | ||
let Double, generateFakeFunction, subject | ||
module.exports = { | ||
'passed a string name': () => { | ||
const result = subject('foo') | ||
beforeEach: () => { | ||
Double = td.replace('../../../src/value/double').default | ||
generateFakeFunction = td.replace('../../../src/function/generate-fake-function').default | ||
assert(result instanceof Double) | ||
assert.strictEqual(result.real, null) | ||
assert.equal(result.name, 'foo') | ||
assert.equal(typeof result.fake, 'function') | ||
assert.equal(result.fake.toString(), '[test double for "foo"]') | ||
subject = require('../../../src/function/create').default | ||
}, | ||
'passed a function with a name': () => { | ||
function bar () {} | ||
const result = subject(bar) | ||
'puts the lime in the coconut': () => { | ||
td.when(Double.create('a name', 'a real', 'a parent', generateFakeFunction)).thenReturn('yasss') | ||
assert.equal(result.real, bar) | ||
assert.equal(result.name, 'bar') | ||
assert.equal(result.fake.toString(), '[test double for "bar"]') | ||
}, | ||
'passed an unnamed function': () => { | ||
const result = subject(function () {}) | ||
const result = subject('a name', 'a real', 'a parent', generateFakeFunction) | ||
assert.strictEqual(result.name, null) | ||
assert.equal(result.fake.toString(), '[test double (unnamed)]') | ||
}, | ||
'passed nothing': () => { | ||
const result = subject() | ||
assert.equal(result, 'yasss') | ||
} | ||
assert.strictEqual(result.name, null) | ||
assert.strictEqual(result.real, null) | ||
assert.equal(result.fake.toString(), '[test double (unnamed)]') | ||
}, | ||
'the fake function itself': { | ||
'logs calls': () => { | ||
const double = subject() | ||
double.fake.call('fake this', 1, 2, 3) | ||
var calls = CallLog.instance.for(double) | ||
assert.equal(calls.length, 1) | ||
assert.equal(calls[0].context, 'fake this') | ||
assert.deepEqual(calls[0].args, [1, 2, 3]) | ||
}, | ||
'registers stubbing': () => { | ||
const double = subject() | ||
const stubbing = new Stubbing('return', ['a', 'b'], ['c']) | ||
StubbingRegister.instance.add(double, stubbing) | ||
const result = double.fake('a', 'b') | ||
assert.equal(result, 'c') | ||
} | ||
}, | ||
'toString supports mutation (necessary sometimes for td.replace() to depend on td.func()': () => { | ||
const double = subject() | ||
double.name = 'new name' | ||
assert.equal(double.name, 'new name') | ||
assert.equal(double.fake.toString(), '[test double for "new name"]') | ||
} | ||
} |
import Double from '../../../src/value/double' | ||
let create, imitate, remember, subject | ||
let create, subject | ||
module.exports = { | ||
beforeEach: () => { | ||
create = td.replace('../../../src/function/create').default | ||
imitate = td.replace('../../../src/imitate').default | ||
remember = td.replace('../../../src/function/remember').default | ||
@@ -13,13 +11,13 @@ subject = require('../../../src/function/index').default | ||
'pass in a name': () => { | ||
const double = new Double(null, null, 'fake thing') | ||
td.when(create('foo')).thenReturn(double) | ||
const double = Double.create(null, null, null, () => 'fake thing') | ||
td.when(create('foo', null)).thenReturn(double) | ||
const result = subject('foo') | ||
assert.equal(result, double.fake) | ||
td.verify(remember(double)) | ||
assert.equal(result, 'fake thing') | ||
}, | ||
'pass in a function': () => { | ||
'pass in a named function': () => { | ||
function bar () {} | ||
td.when(imitate(bar)).thenReturn('fake bar') | ||
const double = Double.create(null, null, null, () => 'fake bar') | ||
td.when(create('bar', bar)).thenReturn(double) | ||
@@ -29,3 +27,12 @@ const result = subject(bar) | ||
assert.equal(result, 'fake bar') | ||
}, | ||
'pass in an unnamed function': () => { | ||
const unnamedFunc = eval('(function () {})') //eslint-disable-line | ||
const double = Double.create(null, null, null, () => 'fake') | ||
td.when(create(null, unnamedFunc)).thenReturn(double) | ||
const result = subject(unnamedFunc) | ||
assert.equal(result, 'fake') | ||
} | ||
} |
@@ -15,3 +15,3 @@ import Double from '../../../src/value/double' | ||
'tracks calls (also resets)': () => { | ||
const double = new Double() | ||
const double = Double.create() | ||
const call = new Call() | ||
@@ -29,6 +29,6 @@ | ||
'can pop latest calls': () => { | ||
const double1 = new Double() | ||
const double1 = Double.create() | ||
const call1 = new Call() | ||
subject.log(double1, call1) | ||
const double2 = new Double() | ||
const double2 = Double.create() | ||
const call2 = new Call() | ||
@@ -35,0 +35,0 @@ subject.log(double2, call2) |
import Double from '../../../src/value/double' | ||
module.exports = { | ||
'basic instantiation': () => { | ||
const subject = new Double('name', 'real thing', 'fake thing') | ||
'public Double.create factory method': () => { | ||
const parent = Double.create('parent') | ||
const subject = Double.create('name', 'real thing', parent, (double) => `${double.name} fake`) | ||
assert.equal(subject.name, 'name') | ||
assert.equal(subject.fullName, 'name') | ||
assert.equal(subject.fullName, 'parent.name') | ||
assert.equal(subject.real, 'real thing') | ||
assert.equal(subject.fake, 'fake thing') | ||
assert.equal(subject.fake, 'name fake') | ||
assert.equal(subject.parent, parent) | ||
assert.deepEqualSet(parent.children, [subject]) | ||
}, | ||
'adding children - fullName computes parent names with dot joiner': () => { | ||
const grandparent = new Double('foo') | ||
const parent = new Double('bar') | ||
const child = new Double('baz') | ||
const grandparent = Double.create('foo') | ||
const parent = Double.create('bar') | ||
const child = Double.create('baz') | ||
grandparent.addChild(parent) | ||
@@ -27,4 +31,4 @@ parent.addChild(child) | ||
'fullName is null when parent and child names are null': () => { | ||
const parent = new Double() | ||
const child = new Double() | ||
const parent = Double.create() | ||
const child = Double.create() | ||
parent.addChild(child) | ||
@@ -36,5 +40,5 @@ | ||
'fullName is "parent.(unnamed)" when grandparent+child name is null': () => { | ||
const grandparent = new Double() | ||
const parent = new Double('parent') | ||
const child = new Double() | ||
const grandparent = Double.create() | ||
const parent = Double.create('parent') | ||
const child = Double.create() | ||
grandparent.addChild(parent) | ||
@@ -45,3 +49,23 @@ parent.addChild(child) | ||
assert.strictEqual(child.fullName, '(unnamed).parent.(unnamed)') | ||
}, | ||
'#toString': { | ||
'toString for unnamed double': () => { | ||
const double = Double.create() | ||
assert.equal(double.toString(), '[test double (unnamed)]') | ||
}, | ||
'toString for named double': () => { | ||
const double = Double.create('name', null, Double.create('full')) | ||
assert.equal(double.toString(), '[test double for "full.name"]') | ||
}, | ||
'toString supports mutation (necessary sometimes for td.replace() to depend on td.func())': () => { | ||
const double = Double.create('old name') | ||
double.name = 'new name' | ||
assert.equal(double.name, 'new name') | ||
assert.equal(double.toString(), '[test double for "new name"]') | ||
} | ||
} | ||
} |
import Double from '../../../src/value/double' | ||
import Call from '../../../src/value/call' | ||
import Stubbing from '../../../src/value/stubbing' | ||
@@ -15,3 +14,3 @@ import StubbingRegister from '../../../src/value/stubbing-register' | ||
'can add, retrieve a stubbing': () => { | ||
const double = new Double() | ||
const double = Double.create() | ||
const stubbing = new Stubbing() | ||
@@ -22,16 +21,3 @@ | ||
assert.deepEqual(subject.get(double), [stubbing]) | ||
}, | ||
'delegates to another thing to satisfy': () => { | ||
const double = new Double() | ||
const stubbing = new Stubbing() | ||
const call = new Call() | ||
const satisfy = td.replace('../../../src/satisfy').default | ||
td.when(satisfy(call, [stubbing])).thenReturn('pants') | ||
subject = require('../../../src/value/stubbing-register').default.instance | ||
subject.add(double, stubbing) | ||
const result = subject.satisfy(double, call) | ||
assert.equal(result, 'pants') | ||
} | ||
} |
@@ -0,15 +1,95 @@ | ||
import Call from '../../../src/value/call' | ||
import Stubbing from '../../../src/value/stubbing' | ||
module.exports = { | ||
'increments timesSatisfied (used for satisfaction-limits)': () => { | ||
const subject = new Stubbing() | ||
'.hasTimesRemaining': { | ||
'no option set': () => { | ||
const subject = new Stubbing() | ||
assert.equal(subject.timesSatisfied, 0) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
subject.incrementSatisfactions() | ||
assert.equal(subject.timesSatisfied, 1) | ||
subject.addSatisfyingCall(new Call()) | ||
subject.incrementSatisfactions() | ||
assert.equal(subject.timesSatisfied, 2) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
}, | ||
'times set to 0': () => { | ||
const subject = new Stubbing(null, null, null, {times: 0}) | ||
assert.equal(subject.hasTimesRemaining, false) | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.hasTimesRemaining, false) | ||
}, | ||
'times set to 1': () => { | ||
const subject = new Stubbing(null, null, null, {times: 1}) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.hasTimesRemaining, false) | ||
}, | ||
'times set to 2': () => { | ||
const subject = new Stubbing(null, null, null, {times: 2}) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.hasTimesRemaining, false) | ||
}, | ||
'guards against duplicate calls (only count once)': () => { | ||
const subject = new Stubbing(null, null, null, {times: 2}) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
const call = new Call() | ||
subject.addSatisfyingCall(call) | ||
subject.addSatisfyingCall(call) | ||
subject.addSatisfyingCall(call) | ||
assert.equal(subject.hasTimesRemaining, true) | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.hasTimesRemaining, false) | ||
} | ||
}, | ||
'.currentOutcome': { | ||
'one outcome set': () => { | ||
const subject = new Stubbing(null, null, ['pants']) | ||
assert.equal(subject.currentOutcome, 'pants') | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.currentOutcome, 'pants') | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.currentOutcome, 'pants') | ||
}, | ||
'two outcomes set': () => { | ||
const subject = new Stubbing(null, null, ['pants', 'hat']) | ||
assert.equal(subject.currentOutcome, 'pants') | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.currentOutcome, 'pants') | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.currentOutcome, 'hat') | ||
subject.addSatisfyingCall(new Call()) | ||
assert.equal(subject.currentOutcome, 'hat') | ||
} | ||
} | ||
} |
@@ -15,6 +15,6 @@ import Double from '../../../src/value/double' | ||
'adds a stubbing, returns the fake': () => { | ||
const double = new Double() | ||
const double = Double.create() | ||
const call = new Call(null, ['arg1', 'arg2']) | ||
CallLog.instance.log(double, call) | ||
td.when(chainStubbing(td.callback('a type', ['a stub']))).thenReturn('chained methods') | ||
td.when(chainStubbing(double, td.callback('a type', ['a stub']))).thenReturn('chained methods') | ||
td.when(addImpliedCallbackArgIfNecessary('a type', ['arg1', 'arg2'])).thenReturn('good args') | ||
@@ -21,0 +21,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
270
1553544
30932
23
16