testdouble
Advanced tools
Comparing version 3.16.1 to 3.16.2
# Change Log | ||
## 3.16.1 | ||
* Handle cases where deep-cloning arguments fails. If `cloneArgs` is specified | ||
on a stubbing or verification, the error will be propagated and thrown, | ||
otherwise it will be swallowed and td.explain will warn the user that clone | ||
failed (and therefore its log message may be inaccurate). See | ||
[#469](https://github.com/testdouble/testdouble.js/pull/469/files) | ||
## 3.16.0 | ||
@@ -4,0 +12,0 @@ |
@@ -0,1 +1,3 @@ | ||
export as namespace testdouble; | ||
// | ||
@@ -2,0 +4,0 @@ // types and interfaces |
@@ -9,2 +9,3 @@ "use strict"; | ||
const stubbings_1 = require("./store/stubbings"); | ||
const symbols_1 = require("./symbols"); | ||
function explain(testDouble) { | ||
@@ -102,3 +103,12 @@ if (lodash_1.default.isFunction(testDouble)) { | ||
return calls.length > 0 | ||
? lodash_1.default.reduce(calls, (desc, call) => desc + `\n - called with \`(${arguments_1.default(call.cloneArgs)})\`.`, '\n\nInvocations:') | ||
? lodash_1.default.reduce(calls, (desc, call) => { | ||
let argDescription; | ||
if (call.cloneArgs !== symbols_1.default.uncloneable) { | ||
argDescription = `\`(${arguments_1.default(call.cloneArgs)})\`.`; | ||
} | ||
else { | ||
argDescription = `\`(${arguments_1.default(call.args)})\` [Cloning argument values failed; displaying current references]`; | ||
} | ||
return desc + `\n - called with ${argDescription}`; | ||
}, '\n\nInvocations:') | ||
: ''; | ||
@@ -105,0 +115,0 @@ } |
@@ -20,3 +20,3 @@ "use strict"; | ||
More details here: | ||
https://github.com/testdouble/testdouble.js/blob/master/docs/4-creating-test-doubles.md#objectobjectname | ||
https://github.com/testdouble/testdouble.js/blob/main/docs/4-creating-test-doubles.md#objectobjectname | ||
@@ -23,0 +23,0 @@ Did you mean \`td.object(['${name}'])\`? |
@@ -5,2 +5,3 @@ "use strict"; | ||
const args_match_1 = require("../args-match"); | ||
const clone_deep_if_possible_1 = require("../clone-deep-if-possible"); | ||
const index_1 = require("./index"); | ||
@@ -11,3 +12,3 @@ let callHistory = []; // <-- remember this to pop our DSL of when(<call>)/verify(<call>) | ||
log(testDouble, args, context) { | ||
index_1.default.for(testDouble).calls.push({ args, context, cloneArgs: lodash_1.default.cloneDeep(args) }); | ||
index_1.default.for(testDouble).calls.push({ args, context, cloneArgs: clone_deep_if_possible_1.default(args) }); | ||
return callHistory.push({ testDouble, args, context }); | ||
@@ -14,0 +15,0 @@ }, |
@@ -11,5 +11,8 @@ "use strict"; | ||
const notify_after_satisfaction_1 = require("./matchers/notify-after-satisfaction"); | ||
const clone_deep_if_possible_1 = require("./clone-deep-if-possible"); | ||
const symbols_1 = require("./symbols"); | ||
exports.default = (__userDoesRehearsalInvocationHere__, config = {}) => { | ||
const last = calls_1.default.pop(); | ||
ensureRehearsalOccurred(last); | ||
ensureCloneableIfCloneArgs(last, config); | ||
if (calls_1.default.wasInvoked(last.testDouble, last.args, config)) { | ||
@@ -33,2 +36,9 @@ notifyMatchers(last.testDouble, last.args, config); | ||
}; | ||
function ensureCloneableIfCloneArgs(last, config) { | ||
if (config.cloneArgs && clone_deep_if_possible_1.default(last.args) === symbols_1.default.uncloneable) { | ||
return log_1.default.error('td.verify', `\ | ||
Failed to deep-clone arguments. Ensure lodash _.cloneDeep works on them | ||
`); | ||
} | ||
} | ||
const notifyMatchers = (testDouble, expectedArgs, config) => { | ||
@@ -41,3 +51,3 @@ lodash_1.default.each(calls_1.default.where(testDouble, expectedArgs, config), (invocation) => { | ||
if (lodash_1.default.some(stubbings_1.default.for(testDouble), (stubbing) => args_match_1.default(stubbing.args, actualArgs, stubbing.config))) { | ||
log_1.default.warn('td.verify', `test double${stringifyName(testDouble)} was both stubbed and verified with arguments (${arguments_1.default(actualArgs)}), which is redundant and probably unnecessary.`, 'https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with-a-test-double'); | ||
log_1.default.warn('td.verify', `test double${stringifyName(testDouble)} was both stubbed and verified with arguments (${arguments_1.default(actualArgs)}), which is redundant and probably unnecessary.`, 'https://github.com/testdouble/testdouble.js/blob/main/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with-a-test-double'); | ||
} | ||
@@ -44,0 +54,0 @@ }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = '3.16.1'; | ||
exports.default = '3.16.2'; |
@@ -10,2 +10,4 @@ "use strict"; | ||
const config_1 = require("./config"); | ||
const clone_deep_if_possible_1 = require("./clone-deep-if-possible"); | ||
const symbols_1 = require("./symbols"); | ||
function when(__userDoesRehearsalInvocationHere__, config = {}) { | ||
@@ -39,2 +41,3 @@ return ({ | ||
ensureRehearsalOccurred(last); | ||
ensureCloneableIfCloneArgs(last, config); | ||
lodash_1.default.assign(config, { plan }); | ||
@@ -54,2 +57,9 @@ stubbings_1.default.add(last.testDouble, concatImpliedCallback(last.args, config), stubbedValues, config); | ||
} | ||
function ensureCloneableIfCloneArgs(last, config) { | ||
if (config.cloneArgs && clone_deep_if_possible_1.default(last.args) === symbols_1.default.uncloneable) { | ||
return log_1.default.error('td.when', `\ | ||
Failed to deep-clone arguments. Ensure lodash _.cloneDeep works on them | ||
`); | ||
} | ||
} | ||
function concatImpliedCallback(args, config) { | ||
@@ -56,0 +66,0 @@ if (config.plan !== 'thenCallback') { |
{ | ||
"name": "testdouble", | ||
"version": "3.16.1", | ||
"version": "3.16.2", | ||
"description": "A minimal test double library for TDD with JavaScript", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/testdouble/testdouble.js", |
# testdouble.js (AKA td.js) | ||
[![Build Status](https://circleci.com/gh/testdouble/testdouble.js/tree/master.svg?style=svg)](https://circleci.com/gh/testdouble/testdouble.js/tree/master) | ||
[![Build Status](https://circleci.com/gh/testdouble/testdouble.js/tree/main.svg?style=svg)](https://circleci.com/gh/testdouble/testdouble.js/tree/main) | ||
[![npmjs](https://img.shields.io/badge/npm-testdouble-red.svg)](https://www.npmjs.com/package/testdouble) | ||
[![unpkg](https://img.shields.io/badge/unpkg-download-blue.svg)](https://unpkg.com/testdouble/dist/) | ||
[![Test Coverage](https://codeclimate.com/github/testdouble/testdouble.js/badges/coverage.svg)](https://codeclimate.com/github/testdouble/testdouble.js/coverage) | ||
@@ -11,3 +10,5 @@ Welcome! Are you writing JavaScript tests and in the market for a mocking | ||
carefully-designed test double library maintained by, oddly enough, a software | ||
agency that's also named [Test Double](http://testdouble.com). | ||
agency that's also named [Test Double](http://testdouble.com). (The term "test | ||
double" was coined by Gerard Meszaros in his book [xUnit Test | ||
Patterns](http://xunitpatterns.com/Test%20Double.html).) | ||
@@ -37,3 +38,10 @@ If you practice test-driven development, testdouble.js was designed to promote | ||
```js | ||
global.td = require('testdouble') // Node.js; `window.td` for browsers | ||
// ES import syntax | ||
import * as td from 'testdouble' | ||
// CommonJS modules (e.g. Node.js) | ||
global.td = require('testdouble') | ||
// Global set in our browser distribution | ||
window.td | ||
``` | ||
@@ -223,3 +231,3 @@ | ||
The library's [imitation | ||
feature](https://github.com/testdouble/testdouble.js/blob/master/src/imitate/index.js) | ||
feature](https://github.com/testdouble/testdouble.js/blob/main/src/imitate/index.js) | ||
is pretty sophisticated, but it's not perfect. It's also going to be pretty slow | ||
@@ -267,3 +275,3 @@ on large, complex objects. If you'd like to specify exactly what to replace a | ||
`name`, including a deep | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/master/src/imitate/index.js) | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/main/src/imitate/index.js) | ||
of all of its custom properties | ||
@@ -286,3 +294,3 @@ * **`td.func()`** - returns an anonymous test double function that can be used | ||
* **`td.object(realObject)`** - returns a deep | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/master/src/imitate/index.js) | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/main/src/imitate/index.js) | ||
of the passed object, where each function is replaced with a test double function | ||
@@ -314,3 +322,3 @@ named for the property path (e.g. If `realObject.invoices.send()` was a | ||
with test double functions using the same | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/master/src/imitate/index.js) | ||
[imitation](https://github.com/testdouble/testdouble.js/blob/main/src/imitate/index.js) | ||
mechanism as `td.func(realFunction)` and `td.object(realObject)` | ||
@@ -317,0 +325,0 @@ * **`td.constructor(['select', 'save'])`** - returns a constructor with `select` |
@@ -7,2 +7,3 @@ import _ from './wrap/lodash' | ||
import stubbingsStore from './store/stubbings' | ||
import symbols from './symbols' | ||
@@ -111,3 +112,11 @@ export default function explain (testDouble) { | ||
return calls.length > 0 | ||
? _.reduce(calls, (desc, call) => desc + `\n - called with \`(${stringifyArgs(call.cloneArgs)})\`.`, '\n\nInvocations:') | ||
? _.reduce(calls, (desc, call) => { | ||
let argDescription | ||
if (call.cloneArgs !== symbols.uncloneable) { | ||
argDescription = `\`(${stringifyArgs(call.cloneArgs)})\`.` | ||
} else { | ||
argDescription = `\`(${stringifyArgs(call.args)})\` [Cloning argument values failed; displaying current references]` | ||
} | ||
return desc + `\n - called with ${argDescription}` | ||
}, '\n\nInvocations:') | ||
: '' | ||
@@ -114,0 +123,0 @@ } |
@@ -19,3 +19,3 @@ import * as theredoc from 'theredoc' | ||
More details here: | ||
https://github.com/testdouble/testdouble.js/blob/master/docs/4-creating-test-doubles.md#objectobjectname | ||
https://github.com/testdouble/testdouble.js/blob/main/docs/4-creating-test-doubles.md#objectobjectname | ||
@@ -22,0 +22,0 @@ Did you mean \`td.object(['${name}'])\`? |
import _ from '../wrap/lodash' | ||
import argsMatch from '../args-match' | ||
import cloneDeepIfPossible from '../clone-deep-if-possible' | ||
import store from './index' | ||
@@ -10,3 +11,3 @@ | ||
log (testDouble, args, context) { | ||
store.for(testDouble).calls.push({ args, context, cloneArgs: _.cloneDeep(args) }) | ||
store.for(testDouble).calls.push({ args, context, cloneArgs: cloneDeepIfPossible(args) }) | ||
return callHistory.push({ testDouble, args, context }) | ||
@@ -13,0 +14,0 @@ }, |
@@ -9,2 +9,4 @@ import _ from './wrap/lodash' | ||
import notifyAfterSatisfaction from './matchers/notify-after-satisfaction' | ||
import cloneDeepIfPossible from './clone-deep-if-possible' | ||
import symbols from './symbols' | ||
@@ -14,2 +16,3 @@ export default (__userDoesRehearsalInvocationHere__, config = {}) => { | ||
ensureRehearsalOccurred(last) | ||
ensureCloneableIfCloneArgs(last, config) | ||
if (callsStore.wasInvoked(last.testDouble, last.args, config)) { | ||
@@ -34,2 +37,10 @@ notifyMatchers(last.testDouble, last.args, config) | ||
function ensureCloneableIfCloneArgs (last, config) { | ||
if (config.cloneArgs && cloneDeepIfPossible(last.args) === symbols.uncloneable) { | ||
return log.error('td.verify', `\ | ||
Failed to deep-clone arguments. Ensure lodash _.cloneDeep works on them | ||
`) | ||
} | ||
} | ||
const notifyMatchers = (testDouble, expectedArgs, config) => { | ||
@@ -47,3 +58,3 @@ _.each(callsStore.where(testDouble, expectedArgs, config), (invocation) => { | ||
`test double${stringifyName(testDouble)} was both stubbed and verified with arguments (${stringifyArgs(actualArgs)}), which is redundant and probably unnecessary.`, | ||
'https://github.com/testdouble/testdouble.js/blob/master/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with-a-test-double' | ||
'https://github.com/testdouble/testdouble.js/blob/main/docs/B-frequently-asked-questions.md#why-shouldnt-i-call-both-tdwhen-and-tdverify-for-a-single-interaction-with-a-test-double' | ||
) | ||
@@ -50,0 +61,0 @@ } |
@@ -1,1 +0,1 @@ | ||
export default '3.16.1' | ||
export default '3.16.2' |
@@ -8,2 +8,4 @@ import _ from './wrap/lodash' | ||
import tdConfig from './config' | ||
import cloneDeepIfPossible from './clone-deep-if-possible' | ||
import symbols from './symbols' | ||
@@ -38,2 +40,3 @@ export default function when (__userDoesRehearsalInvocationHere__, config = {}) { | ||
ensureRehearsalOccurred(last) | ||
ensureCloneableIfCloneArgs(last, config) | ||
_.assign(config, { plan }) | ||
@@ -56,2 +59,10 @@ stubbings.add(last.testDouble, concatImpliedCallback(last.args, config), stubbedValues, config) | ||
function ensureCloneableIfCloneArgs (last, config) { | ||
if (config.cloneArgs && cloneDeepIfPossible(last.args) === symbols.uncloneable) { | ||
return log.error('td.when', `\ | ||
Failed to deep-clone arguments. Ensure lodash _.cloneDeep works on them | ||
`) | ||
} | ||
} | ||
function concatImpliedCallback (args, config) { | ||
@@ -58,0 +69,0 @@ if (config.plan !== 'thenCallback') { |
Sorry, the diff of this file is too big to display
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
522845
167
12281
588