Socket
Socket
Sign inDemoInstall

spy4js

Package Overview
Dependencies
1
Maintainers
1
Versions
75
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.4.0 to 3.4.1

dist/types/env.d.ts

2

dist/cjs/index.js

@@ -759,3 +759,3 @@ 'use strict';

if (!diff) return;
throw new Error(`\n\n${this[Symbols.name]} was expected` + ' to have the following props:\n\n' + ` --> ${serialize(props)}\n\n` + 'But the current props are:\n\n' + serialize(currentProps));
throw new Error(`\n\n${this[Symbols.name]} was expected` + ' to have the following props:\n\n' + ` --> ${serialize(props)}\n\n` + 'But the current props are:\n\n' + ` ${serialize(currentProps)}\n` + ` ${diff}`);
},

@@ -762,0 +762,0 @@

@@ -755,3 +755,3 @@ import { Serializer } from 'serialize-as-code';

if (!diff) return;
throw new Error(`\n\n${this[Symbols.name]} was expected` + ' to have the following props:\n\n' + ` --> ${serialize(props)}\n\n` + 'But the current props are:\n\n' + serialize(currentProps));
throw new Error(`\n\n${this[Symbols.name]} was expected` + ' to have the following props:\n\n' + ` --> ${serialize(props)}\n\n` + 'But the current props are:\n\n' + ` ${serialize(currentProps)}\n` + ` ${diff}`);
},

@@ -758,0 +758,0 @@

{
"name": "spy4js",
"version": "3.4.0",
"version": "3.4.1",
"description": "Smart, compact and powerful spy test framework",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "index.d.ts",
"types": "dist/types/index.d.ts",
"files": [
"dist/cjs",
"dist/esm",
"src",
"index.d.ts"
"dist"
],

@@ -31,29 +28,31 @@ "repository": {

"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/core": "^7.17.12",
"@babel/eslint-parser": "^7.17.0",
"@babel/plugin-proposal-class-properties": "^7.16.7",
"@babel/preset-env": "^7.16.11",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@babel/plugin-proposal-class-properties": "^7.17.12",
"@babel/preset-env": "^7.17.12",
"@babel/preset-react": "^7.17.12",
"@babel/preset-typescript": "^7.17.12",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-node-resolve": "^13.1.3",
"@sucrase/jest-plugin": "^2.2.0",
"@testing-library/react": "^13.0.0-alpha.6",
"@types/jest": "^27.4.1",
"@types/react": "^17.0.43",
"@typescript-eslint/eslint-plugin": "^5.17.0",
"@typescript-eslint/parser": "^5.17.0",
"@rollup/plugin-node-resolve": "^13.3.0",
"@sucrase/jest-plugin": "^2.2.1",
"@testing-library/react": "^13.2.0",
"@types/jest": "^27.5.1",
"@types/node": "^17.0.34",
"@types/react": "^18.0.9",
"@typescript-eslint/eslint-plugin": "^5.25.0",
"@typescript-eslint/parser": "^5.25.0",
"coveralls": "^3.1.1",
"eslint": "^8.12.0",
"eslint": "^8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^27.5.1",
"prettier": "^2.6.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"rollup": "^2.70.1",
"typescript": "^4.6.3"
"jest": "^28.1.0",
"jest-environment-jsdom": "^28.1.0",
"prettier": "^2.6.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"rollup": "^2.73.0",
"typescript": "^4.6.4"
},
"scripts": {
"dist": "rm -rf dist && rollup -c && cp index.ts index.d.ts",
"dist": "rm -rf dist && rollup -c && tsc -p tsconfig.publish.json",
"lint": "pnpm lint:es && pnpm lint:ts",

@@ -66,4 +65,3 @@ "lint:es": "eslint --ext .ts src/ test/",

"coveralls": "cat ./coverage/lcov.info | coveralls"
},
"readme": "[![GitHub license][license-image]][license-url]\n[![npm package][npm-image]][npm-url] \n[![Travis][build-image]][build-url]\n[![Coverage Status][coveralls-image]][coveralls-url]\n[![styled with prettier][prettier-image]][prettier-url]\n\n# ![spy4js logo](spy-logo.svg?sanitize=true) spy4js\n\n### Benefits\n\n - `TypeScript` support included\n - Performance\n - No foreign dependencies\n - Optimized error messages\n - Customizable\n - Intuitive\n - Used in production of large projects\n\n### Introduction\n\n**spy4js** provides a stand-alone spy framework. It is decoupled by any dependencies\nand other assertion frameworks.\n\n**spy4js** exports only one object called `Spy`. The spy instances\ncome with a lot of useful features. See below for more.\n\n**Hint**:\nMy favorite test framework is [Jest](https://jestjs.io/). If you are using other\nframeworks you might get issues related to automatically applied test suite hooks.\nTo overcome this default behavior see [here](#configure-static). Since Jest already\nincludes excellent spies itself, you might ask yourself, why `spy4js`. Because it's better.\n\nAdvantages over Jest spies:\n- Very important for tests is their readability. This spy API is much easier to learn, and\n the tests can be understood even without any previous knowledge.\n- Error messages should be extremely helpful, because development time is very valuable.\n In error cases made comparisons will be printed with detailed information.\n- The used serialization for objects can be directly copied into your test code, which increases\n your speed while writing tests.\n- Last but not least there are several nice features Jest doesn't provide out-of-the-box, and you\n could even combine both spy sorts.\n\n### Installation\n##### With yarn\n```\nyarn add --dev spy4js\n```\n##### With npm\n```\nnpm install --save-dev spy4js\n```\n\n### Interface\n\nA spy instance can be initialized differently.\n\n```ts\nimport { Spy } from 'spy4js';\n\n// initialize directly\nconst spy1 = Spy();\n\n// initialize directly and supply an identifier for debugging purpose (default: 'the spy')\nconst spy2 = Spy('special spy for me');\n\n// initialize by mocking another objects attribute (usually this attribute is a function)\nconst someObject1 = new Date(2017, 1, 15);\nconst spy3 = Spy.on(someObject1, 'toJSON');\n// (spy name will be accordingly: \"the spy on 'toJSON'\")\n\n// initialize many by mocking another objects attributes\nconst someObject2 = new Date(2017, 1, 15);\nconst someObject2$Mock = Spy.mock(someObject2, 'toJSON', 'toString', 'getDate');\n\n// mock exported functions from other modules\nconst myModuleMocks = Spy.mockModule('./my-module', 'useMe');\n\n// mock React components from other modules\nconst { Calculator } = Spy.mockModule('./my/fancy/Calculator', 'Calculator');\n```\n\nYou may apply additional behavior to every spy. The valid operations here are:\n \n - `configure` (some external libraries may use own \"equals\" implementations unexpectedly)\n - `calls` (does make the spy call the provided functions sequentially)\n - `returns` (does make the spy return the provided params sequentially)\n - `throws` (does make the spy throw an error when called)\n - `resolves` (does make the spy resolve the provided params sequentially) #Promise\n - `rejects` (does make the spy reject an error when called) #Promise\n - `transparent` (does make the spy call the original method of a mocked object)\n - `transparentAfter` (does make the spy call the original method of a mocked object after a certain amount of made calls)\n - `reset` (resets the registered calls which were already made)\n - `restore` (does make the spy restore the mocked object)\n - `addSnapshotSerializer` (defines in `jest` snapshots how the spy will be serialized)\n \nAll those methods on a spy has been designed in a builder pattern. So you may chain any of\nthese configurations. Be aware some behaviors override existing behaviors.\n\n```ts\nconst spy = Spy.on(someObject, 'someMethod');\n\n// configure it to use NOT own \"equals\" implementations\nspy.configure({ useOwnEquals: false });\n\n// make it call any functions\nspy.calls(func1, func2, func3);\nsomeObject.someMethod(arg); // returns func1(arg)\nsomeObject.someMethod(arg1, arg2); // returns func2(arg1, arg2)\nsomeObject.someMethod(arg); // returns func3(arg)\nsomeObject.someMethod(arg1, arg2, arg3); // returns func3(arg1, arg2, arg3) // sticks to the last\n\n// make it return any values\nspy.returns(value1, value2);\nsomeObject.someMethod(arg); // returns value1\nsomeObject.someMethod(arg1, arg2); // returns value2\nsomeObject.someMethod(arg); // returns value2 // sticks to the last\n\n// make it throw any message (the message is optional)\nspy.throws('throw this');\nsomeObject.someMethod(arg); // throws new Error('throw this')\n\n// make it return always the current date and transparentAfter 2 calls\nspy.calls(() => new Date()).transparentAfter(2);\nsomeObject.someMethod(arg); // returns new Date()\nsomeObject.someMethod(arg1, arg2); // returns new(er) Date()\nsomeObject.someMethod(arg); // returns someObject.someMethod(arg) // sticks to this behavior\n\n// make it immediatly transparent\nspy.transparent();\n\n// make it reset\nspy.reset();\n\n// make it restore\nspy.restore(); // other than \"transparent\" does not control input and output of the mocked function anymore\n```\n\nEven as important are the \"facts\", we want to display:\n\n - `wasCalled` (does display that the spy has been called a specifiable amount of times)\n - `wasNotCalled` (does display that the spy has never been called)\n - `wasCalledWith` (does display that the spy has been called at least once like with the provided params)\n - `wasNotCalledWith` (does display that the spy was never like with the provided params)\n - `hasCallHistory` (does display that the spy has been called with the following params in the given order)\n - `hasProps` (does display that the spy has been called with the given argument on the last invocation. In the\n context of React: The spy being a mocked React component has currently the given props.)\n\nThose methods on a spy display facts. Facts have to be true, otherwise they\nwill throw an Exception, which displays in a formatted debug message why the\ngiven fact was a lie. By writing those facts in your tests, a big refactoring\nloses its scare.\n\n```ts\nconst spy = Spy();\n\nspy.wasNotCalled();\n\nspy([1, 'test', {attr: [4]}]);\n\nspy.wasCalled(); // called at least once\nspy.wasCalled(1); // called exactly once\n\nspy('with this text');\n\nspy.wasCalled(2); // called exactly 2 times\n\n// the spy was called at least once with equal params\nspy.wasCalledWith([1, 'test', {attr: [4]}]);\n\n// the spy was not called with those params\nspy.wasNotCalledWith([1, 'test', {attr: [3]}]);\n\n// the spy was called twice with the following params and in same order\nspy.hasCallHistory([ [1, 'test', {attr: [4]}] ], 'with this text');\n```\n\nThere is one static method that does restore all existing spies in all tests.\nThis is extremely useful to clean up all still existing mocks. By default, this is\nautomatically done after every test run (this is done by default).\n \n - `restoreAll` (does restore every existing spy)\n\n```ts\nSpy.restoreAll();\n```\n\nSometimes it is necessary to have access to some call arguments with\nwhich the spy had been called.\n\n - `getAllCallArguments` (returns all call arguments for all calls in an array containing arrays)\n - `getCallArguments` (returns all call arguments for a specified call in an array)\n - `getCallArgument` (same as getCallArguments, but returns only a single element of the array)\n - `getLatestCallArgument` (same as getCallArgument, but for the latest call)\n - `getProps` (same as getLatestCallArgument, but only for the first param. Can be useful for mocked React components)\n - `getCallCount` (returns the number of made calls)\n \n```ts\nconst spy = Spy();\n\n// make some calls\nspy('string', 1);\nspy([1, 2, 3]);\nspy();\nspy(null);\n\nspy.getAllCallArguments(); // returns [['string', 1], [[1, 2, 3]], [], [null]]\nspy.getCallCount(); // returns 4\nspy.getCallArguments(/* default = 0 */); // returns ['string', 1]\nspy.getCallArgument(/* defaults = (0, 0) */); // returns 'string'\nspy.getCallArgument(0, 1); // returns 1\n\nspy.getCallArguments(1); // returns [[1, 2, 3]]\nspy.getCallArgument(1); // returns [1, 2, 3]\n\nspy.getCallArguments(2); // returns []\nspy.getCallArgument(2); // returns undefined\n\nspy.getCallArguments(3); // returns [null]\nspy.getCallArgument(3); // returns null\n\nspy.getCallArguments(4); // throws Exception because less calls were made\nspy.getCallArgument(4); // throws same Exception\n```\n\nThe last method is `showCallArguments`. It is mostly used internally to improve the\ndebugging messages, but can be while you are in a console.log-mania.\n\n## Method-Details\n\n### Constructor\n```ts\nSpy(spyName:string = 'the spy') => SpyInstance\n```\nThe returned Spy instance has his own name-attribute (only) for debugging purpose.\n\n### configure (static)\n```ts\nSpy.configure(config: {\n useOwnEquals?: boolean,\n enforceOrder?: boolean,\n useGenericReactMocks?: boolean,\n beforeEach?: (scope: string) => void,\n afterEach?: (scope: string) => void,\n}) => void\n```\nUsing this function you may edit the default behavior spy4js itself.\nThe scope param will contain the test-suite name, which was provided as first parameter\nof the `describe` function. Please make sure that every scope name is unique per test file.\nThe configuration possibility are:\n- **useOwnEquals**: Applies for all spy instances. See [configure](#configure) for more details.\n- **enforceOrder**: Opt-in to the [enforce-order mode](#enforce-order-mode).\n- **useGenericReactMocks**: Lets you opt in into using generic react components for mocks \n created via [mockReactComponents](#mockreactcomponents-static).\n- **beforeEach**: Lets you override the default beforeEach test suite hook.\n- **afterEach**: Lets you override the default afterEach test suite hook.\n\n### on (static)\n```ts\nSpy.on(object: object, methodName: string) => SpyInstance\n```\nInitializing a spy on an object, simply replaces the original function by a spy and \nstores the necessary information to be able to restore the mocked method. \n\nIf the attribute has already been spied or is not a function, the Spy will throw an exception\nto avoid unexpected behavior. You never want to spy other attributes than functions and\nfor no purpose a spy should ever be spied.\n\n### mock (static)\n```ts\nSpy.mock(object: object, ...methodNames: string[]) => Object (Mock)\n```\nCreating an object that references spies for all given methodNames.\nInitialize as many spies as required for the same object. Only\nafter `Spy.initMocks` gets called, the created mock does affect the given object.\n\n### mockModule (static)\n```ts\nSpy.mockModule(moduleName: string, ...methodNames: string[]) => Object (Mock)\n```\nSame as [mock](#mock-static) but only necessary if you want to mock exported functions.\n\n### mockReactComponents (static)\n```ts\nSpy.mockReactComponents(moduleName: string, ...methodNames: string[]) => Object (Mock)\n```\nSame as [mockModule](#mockModule-static) but designed for ReactJS components. The registered\nspies return `null` instead of `undefined`. This makes minimal usable React components.\nEven if in most cases the pure mocking is nice enough, you can even test the number\nof rerender cycles and the provided props of the mocked component. Works perfectly\nwith [enzyme](https://www.npmjs.com/package/enzyme) and\n[@testing-library/react](https://testing-library.com/docs/react-testing-library/intro).\n\n### initMocks (static)\n```ts\nSpy.initMocks(scope?: string) => void\n```\nDoes initialize all global and scope-related mocks by applying spies. Mocks can be\ncreated with [mock](#mock) or [mockModule](#mockModule). This function has not to \nbe called manually, if you rely on the default test suite hooks.\n\n### restoreAll (static)\n```ts\nSpy.restoreAll() => void\n```\nDoes restore all mocked objects to their original state. See [restore](#restore) for\nfurther information. This function has not be called manually, if you rely on\nthe default test suite hooks.\n\n### resetAll (static)\n```ts\nSpy.resetAll() => void\n```\nDoes reset all existing spies. This applies even to persistent spies.\nSee [reset](#reset) for further information. This function has not to be\ncalled manually in between different tests, if you rely on the default\ntest suite hooks.\n\n### IGNORE (static)\n```ts\nSpy.IGNORE = $Internal Symbol$\n```\nThis object can be passed anywhere where you want the \"[wasCalledWith](#wascalledwith-fact)\"\nor \"[hasCallHistory](#hascallhistory-fact)\" to ignore that object or value for comparison.\n```ts\nspy({prop: 'value', other: 13}, 12);\n\nspy.wasCalledWith(Spy.IGNORE, 12);\nspy.wasCalledWith({prop: Spy.IGNORE, other: 13}, 12);\n```\n\n### COMPARE (static)\n```ts\nSpy.COMPARE(comparator: (arg: any) => boolean | void) => SpyComparator\n```\nThis function can be called with a custom comparator and passed anywhere where you want the \"[wasCalledWith](#wascalledwith-fact)\"\nor \"[hasCallHistory](#hasCallHistory-fact)\" to apply your custom comparison. Very useful if\nthe spy gets called with functions that you want to test additionally.\n```ts\nspy(() => ({ prop: 'value', other: 13 }), 12);\n\nspy.wasCalledWith(Spy.COMPARE(fn => fn().prop === 'value'), 12);\nspy.wasCalledWith(Spy.COMPARE(fn => {\n expect(fn()).toEqual({ prop: 'value', other: 13 });\n}), 12);\n```\n\n### MAPPER (static)\n```ts\nSpy.MAPPER(from: any | any[], to: any) => SpyComparator\n```\nThis function can be called in the same places like `Spy.COMPARE`. It is not that much\ncustomizable but provides a nice way to evaluate mapper functions. Meaning pure \nfunctions that return some output for given inputs. The function will be called exactly\nonce for each comparison, so you can even rely on site effects you might want to test,\nif you want to use this for non-pure functions.\n```ts\nspy((value: number) => ({ prop: 'here', other: value }), 12);\nspy((value: number, num: number) => ({ prop: 'here', value, num }), 12);\n\nspy.wasCalledWith(Spy.MAPPER('foo', { prop: 'here', other: 'foo' }), 12);\nspy.wasCalledWith(Spy.MAPPER(['foo', 44], { prop: 'here', value: 'foo', num: 44 }), 12);\n```\n\n### configure\n```ts\nspy.configure(config: { useOwnEquals?: boolean, persistent?: boolean }) => (this) SpyInstance\n```\nWith `configure` the spy can be configured. One configuration possibility\nis to ignore any `equals` methods while comparing objects. There might be libraries which\ncome with those methods, but do not support ES6 classes or anything else. By default, this\nconfiguration has been set to favor own `equals` implementations while comparing objects. \n\nAnother possible configuration is to make the spy persist while other spies have to restore\nwhen [\"restoreAll\"](#restoreall) was called. This spy can ONLY RESTORE the mocked object when\nyou configure it back to be NOT PERSISTENT. This configuration can only be applied to mocking\nspies. For Spies created with `Spy()` this configuration will throw an exception.\n\n### calls\n```ts\nspy.calls(...functions:Array<Function>) => (this) SpyInstance\n```\nThe provided functions will be called sequentially in order when the spy will be called.\nMeaning `spy.calls(func1, func2, func3)` will call first `func1` then `func2` and the rest\nof the time `func3`.\n\n### returns\n```ts\nspy.returns(...args: Array<any>) => (this) SpyInstance\n```\nThe provided arguments will be returned sequentially in order when the spy will be called.\nMeaning `spy.returns(arg1, arg2, arg3)` will return first `arg1` then `arg2` and the rest\nof the time `arg3`.\n\n### resolves\n```ts\nspy.resolves(...args: Array<any>) => (this) SpyInstance\n```\nThe provided arguments will be resolved sequentially in order when the spy will be called.\nMeaning `spy.resolves(arg1, arg2, arg3)` will return first `Promise.resolve(arg1)` then `Promise.resolve(arg2)` and the rest\nof the time `Promise.resolve(arg3)`.\n\n\n### rejects\n```ts\nspy.rejects(...args: Array<?string | Error>) => (this) SpyInstance\n```\nThe provided arguments will be rejected sequentially in order when the spy will be called.\nMeaning `spy.rejects('foo', null, new Error('bar'))` will return first `Promise.reject(new Error('foo'))`\nthen `Promise.reject(new Error('<SPY_NAME> was requested to throw'))` and the rest\nof the time `Promise.reject(new Error('bar'))`.\n\n### throws\n```ts\nspy.throws(message: ?string | Error) => (this) SpyInstance\n```\nPerform this on a spy to make it throw an error when called. The error message can be\nprovided, but a default has also been implemented. If an Error instance will be passed,\nexactly this one will be thrown.\n\n### reset\n```ts\nspy.reset() => (this) SpyInstance\n```\nDoes reset the registered calls on that spy.\n\n### restore\n```ts\nspy.restore() => (this) SpyInstance\n```\nRestores the spied object, if existing, to its original state. The spy won't lose any\nother information. So it is still aware of made calls, can be plugged anywhere else\nand can still be called anywhere else, but it loses all references to the spied object.\n\nIf the spy has been configured persistent this method will throw an error.\n\n### transparent\n```ts\nspy.transparent() => (this) SpyInstance\n```\nCan be useful with spies on objects. It does make the spy behave like not existing. So\nthe original function of the \"mocked\" object will be called, but the spy does remember\nthe call information.\n\n### transparentAfter\n```ts\nspy.transparentAfter(callCount:number) => (this) SpyInstance\n```\nWorks like [transparent](#transparent) but the spy will get transparent after called as\noften as specified. Meaning `spy.transparentAfter(num)` will not be transparent on the first\n`num` calls.\n\n### addSnapshotSerializer\n```ts\nspy.addSnapshotSerializer(serialize: string | ((...args: any[]) => string)) => (this) SpyInstance\n```\nDetermines the rendered output of `jest` snapshots when the certain spy would get rendered.\n\n### wasCalled (fact)\n```ts\nspy.wasCalled(callCount: number = 0) => void\n```\nThis call does display a fact. So if the spy is violating the fact, it is told to throw\nan error. The provided argument does represent the registered calls on that spy.\n\n### wasNotCalled (fact)\n```ts\nspy.wasNotCalled() => void\n```\nThis fact displays that the spy has never been called. Directly after the spy was [reset](#reset)ed,\nthis fact will be given.\n\n### wasCalledWith (fact)\n```ts\nspy.wasCalledWith(...args: Array<any>) => void\n```\nThis fact displays that the spy has been called at least once with equal arguments. \n\nThe equality check is a deep equality check, which (by default) does consider\nown \"equals\" implementations.\n\nBy supplying `Spy.IGNORE` anywhere inside the expected call arguments, you\ncan avoid that the comparison will be further executed. See [Spy.IGNORE](#IGNORE) for further information and examples.\n\nThe deep equality check does also recursively iterate to the first difference found and is able\nto return a string which contains valuable information about the first found difference. \n\nIf any difference will be detected, the fact isn't true, and a helpful error message will be displayed.\nIf using monospaced consoles for the output which do support new lines, there will be really\nneat output. For examples see [showCallArguments](#showcallarguments).\n\n### wasNotCalledWith (fact)\n```ts\nspy.wasNotCalledWith(...args: Array<any>) => void\n```\nThis fact displays simply the opposite of [wasCalledWith](#wascalledwith-fact).\n\n### hasCallHistory (fact)\n```ts\nspy.hasCallHistory(...callHistory: Array<Array<any> | any>) => void\n```\nWorks similar to [wasCalledWith](#wascalledwith-fact) but instead matches each\ncall one by one in **correct order** and **correct call count**.\nATTENTION: single argument calls can be provided without wrapping into an array. E.g. if\nthe single argument is an array itself, then you have to warp it also yourself. (Inspired by jest\ndata providers)\n\n### hasProps (fact)\n```ts\nspy.hasProps(props: any) => void\n```\nThis fact displays that the spy has currently the given props in React context of a mocked component.\n\nThis is the corresponding fact for [getProps](#getprops) using the spy diffing.\n\n### getAllCallArguments\n```ts\nspy.getAllCallArguments() => Array<any[]>\n```\nReturns the call arguments of all made calls to the spy.\nEspecially returning an empty array if the spy has never been called.\n\n### getCallArguments\n```ts\nspy.getCallArguments(callNr: number = 0) => Array<any>\n```\nReturns the call arguments that were registered on the given call. Meaning\n`spy.getCallArguments(num)` does return the (num + 1)'th call arguments.\n\nThrows an exception if the provided (`callNr` - 1) is bigger than the made calls.\n\n### getCallArgument\n```ts\nspy.getCallArgument(callNr: number = 0, argNr: number = 0) => any\n```\nSame as [getCallArguments](#getcallarguments) but returns only a single entry out\nof the array of arguments. Most useful in situations where exactly one call param is expected.\nIf `argNr` is given, it returns the (argNr + 1)'th argument of the call.\n\n### getLatestCallArgument\n```ts\nspy.getLatestCallArgument(argNr: number = 0) => any\n```\nSame as [getCallArgument](#getcallargument) but uses only the latest call.\n\n### getProps\n```ts\nspy.getProps() => any\n```\nSame as [getLatestCallArgument](#getlatestcallargument) but uses only the first arg. Can be useful in\ncombination with [mockReactComponents](#mockreactcomponents-static).\n\n### getCallCount\n```ts\nspy.getCallCount() => number\n```\nThis method simply returns the number of made calls on the spy.\n\n### showCallArguments\n```ts\nspy.showCallArguments(additionalInformation: Array<string> = []) => string\n```\nThis primarily internally used method is responsible for returning formatted informative debug\nmessages when facts aren't true. Let's do an example:\n```ts\nconst spy = Spy('my awesome spy');\nspy(42, 'test', { attr1: [1, 2, new Date(2017, 1, 20)], attr2: 1337 });\nspy(42, 'test', { attr1: [0, 2, new Date(2017, 1, 20)], attr2: 1336 });\nspy(42, 'test', { attr1: [1, 2, new Date(2017, 1, 21)], attr2: 1336 });\nspy(42, 'tes', { attr1: [1, 2, new Date(2017, 1, 20)], attr2: 1336 });\nspy(42, 'test');\n```\nThe following broken fact...\n```ts\nspy.wasCalledWith(42, 'test', {attr1: [1, 2, new Date(2017, 1, 20)], attr2: 1336});\n```\n...would produce the following error output:\n```\nError: \n\nmy awesome spy was expected to be called with the following arguments:\n\n --> [42, 'test', {attr1: [1, 2, new Date(1487545200000)], attr2: 1336}]\n\nActually there were:\n\ncall 0: [42, 'test', {attr1: [1, 2, new Date(1487545200000)], attr2: 1337}]\n --> 2 / attr2 / different number [1337 != 1336]\ncall 1: [42, 'test', {attr1: [0, 2, new Date(1487545200000)], attr2: 1336}]\n --> 2 / attr1 / 0 / different number [0 != 1]\ncall 2: [42, 'test', {attr1: [1, 2, new Date(1487631600000)], attr2: 1336}]\n --> 2 / attr1 / 2 / different date [new Date(1487631600000) != new Date(1487545200000)]\ncall 3: [42, 'tes', {attr1: [1, 2, new Date(1487545200000)], attr2: 1336}]\n --> 1 / different string ['tes' != 'test']\ncall 4: [42, 'test']\n --> 2 / one was undefined [undefined != {attr1: [1, 2, new Date(1487545200000)], attr2: 1336}]\n```\nThere you can see that the arguments of the fact (displayed above all others) does not\nmatch any of the call arguments on the 5 made calls. \n\nFor each call we display additional error information (the first found difference).\nIf the additional information begins with a `-->` there was made a deep equality.\nIf you would travers with the displayed keys you would be directed to those objects which differ.\n\nIn this example the arguments differ for `call 0` in `-->` the third argument (`2`) and\nits attribute `attr2` because there was a different number.\n\nWhile recursively traversing down in the deep equality check, the object keys will be reported.\nMeaning that `2` is representing the index of the array. So for example if you want to grep the\ndifferent objects you could:\n```ts\nconst callArgs = spy.getCallArguments(0/* for the 0'th call above*/);\nconst differentNumber = callArgs[2]['attr2'];\n```\n\n## Enforce-Order Mode\nYou can opt-in to the enforce-order mode. Which might become the default in some\nfuture version but will need first further evaluation and will always stay configurable.\n```ts\nSpy.configure({ enforceOrder: true });\n```\nThis mode enforces that the \"facts\" will be called in the correct order.\n```ts\n// success\nspy1();\nspy2();\nspy1.wasCalled();\nspy2.wasCalled();\n\n// error\nspy1();\nspy2();\nspy2.wasCalled();\nspy1.wasCalled(); // would fail here because spy1 wasn't called after spy2 was called\n```\nBe aware \"facts\" that you might need to get used to it, because the following would be valid, too.\n```ts\n// success\nspy();\nspy.wasCalled();\nspy.wasNotCalled();\n\n// error\nspy();\nspy.wasCalled();\nspy.wasCalled(); // would fail here because we already checked that the spy was called\n```\nNevertheless, this mode should make your tests more readable and clear, because you can avoid\nchecking the same things on and on again or resetting the spies in tests. Another example:\n```ts\nconst mock_WS = Spy.mock(WS, 'fetchData', 'fetchFallback');\n\nit('fetches fallback data if fetching data does not work', async () => {\n // given\n const dummyData = Symbol('dummyData'); \n mock_WS.fetchData.rejects('ups');\n mock_WS.fetchFallback.resolves(dummyData);\n\n // when\n expect(await MyService.fetchAppData({ filtered: true })).toBe(dummyData);\n\n // then\n mock_WS.fetchData.hasCallHistory({ filtered: true }, { filtered: true, retry: true });\n mock_WS.fetchFallback.wasCalledWith({ filtered: true, reason: 'ups' });\n});\n```\n\n[license-image]: https://img.shields.io/badge/license-MIT-blue.svg\n[license-url]: https://github.com/fdc-viktor-luft/form4react/blob/master/LICENSE\n[build-image]: https://img.shields.io/travis/fdc-viktor-luft/spy4js/master.svg?style=flat-square\n[build-url]: https://app.travis-ci.com/github/fdc-viktor-luft/spy4js\n[npm-image]: https://img.shields.io/npm/v/spy4js.svg?style=flat-square\n[npm-url]: https://www.npmjs.org/package/spy4js\n[coveralls-image]: https://coveralls.io/repos/github/fdc-viktor-luft/spy4js/badge.svg?branch=master\n[coveralls-url]: https://coveralls.io/github/fdc-viktor-luft/spy4js?branch=master\n[prettier-image]: https://img.shields.io/badge/styled_with-prettier-ff69b4.svg\n[prettier-url]: https://github.com/prettier/prettier\n"
}
}
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc