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 4.0.0-beta.2 to 4.0.0-beta.3

dist/config.d.ts

28

package.json
{
"name": "spy4js",
"version": "4.0.0-beta.2",
"version": "4.0.0-beta.3",
"description": "Smart, compact and powerful spy test framework",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
"types": "dist/types/index.d.ts",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [

@@ -28,9 +28,5 @@ "dist"

"devDependencies": {
"@babel/core": "^7.23.7",
"@babel/preset-env": "^7.23.8",
"@babel/preset-typescript": "^7.23.3",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"@sucrase/jest-plugin": "^3.0.0",
"@testing-library/react": "^14.1.2",
"@types/bun": "^1.0.1",
"@types/jest": "^29.5.11",

@@ -41,4 +37,3 @@ "@types/node": "^20.11.0",

"@typescript-eslint/parser": "^6.18.1",
"@vitest/coverage-c8": "^0.33.0",
"@vitest/coverage-v8": "^1.1.3",
"@vitest/coverage-v8": "^1.2.0",
"coveralls": "^3.1.1",

@@ -50,12 +45,13 @@ "eslint": "^8.56.0",

"jest-environment-jsdom": "^29.7.0",
"prettier": "^3.1.1",
"prettier": "^3.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rollup": "^4.9.4",
"sucrase": "^3.35.0",
"typescript": "^5.3.3",
"vitest": "^1.1.3"
"vite": "^5.0.11",
"vitest": "^1.2.0"
},
"scripts": {
"dist": "rm -rf dist && rollup -c && tsc -p tsconfig.publish.json",
"dist": "vite build && pnpm dist:ts",
"dist:ts": "tsc -p tsconfig.publish.json",
"lint": "pnpm lint:es && pnpm lint:ts",

@@ -66,3 +62,3 @@ "lint:es": "eslint --ext .ts src/ test/ --max-warnings 0",

"test:jest": "jest --all --color",
"test:vi": "vitest run --coverage",
"test:vi": "VITE_CJS_IGNORE_WARNING=true vitest run --coverage",
"test:bun": "bun test",

@@ -69,0 +65,0 @@ "test:update": "jest -u",

@@ -10,9 +10,9 @@ [![GitHub license][license-image]][license-url]

- `TypeScript` support included
- Performance
- No foreign dependencies
- Optimized error messages
- Customizable
- Intuitive
- Used in production of large projects
- `TypeScript` support included
- Performance
- No foreign dependencies
- Optimized error messages
- Customizable
- Intuitive
- Used in production of large projects

@@ -24,4 +24,4 @@ ### Introduction

⚠️Disclaimer: You don't need this library as the frameworks already everything in order to achieve
everything without this library.
⚠️ Disclaimer: You don't need this library as the frameworks already include everything in order
to achieve everything without this library.

@@ -31,3 +31,3 @@ **spy4js** exports only one object called `Spy`. The spy instances

**Hint**:
**Hint**:
If you are using other frameworks you might not be able to benefit from all features of this library.

@@ -38,3 +38,4 @@ Since the test frameworks already include excellent spies themselves, you might ask yourself, why `spy4js`...

Advantages over Jest spies:
Advantages over Jest/Vitest spies:
- Very important for tests is their readability. This spy API is much easier to learn, and

@@ -50,8 +51,12 @@ the tests can be understood even without any previous knowledge.

### Installation
##### With yarn
```
```sh
yarn add --dev spy4js
```
##### With npm
```
```sh
npm install --save-dev spy4js

@@ -83,3 +88,7 @@ ```

// mock exported functions from other modules
// if your test runner executes with CJS
const myModuleMocksInJest = Spy.mock(require('./my-module'), 'useMe');
const myModuleMocksInJestTypeSafe = Spy.mock(require('./my-module') as typeof import('./my-module'), 'useMe');
// if your test runner supports ESM
vi.mock('./my-module', async () => ({ ...((await vi.importActual('./my-module')) as any) }));

@@ -89,3 +98,10 @@ const myModuleMocksInVitest = Spy.mock(await import('./my-module'), 'useMe');

// mock React components from other modules
// if your test runner executes with CJS
const mockedReactComponentsInJest = Spy.mockReactComponents(require('./my/fancy/Calculator'), 'Calculator');
const mockedReactComponentsInJestTypeSafe = Spy.mockReactComponents(
require('./my/fancy/Calculator') as typeof import('./my/fancy/Calculator'),
'Calculator'
);
// if your test runner supports ESM
vi.mock('./my/fancy/Calculator', async () => ({ ...((await vi.importActual('./my/fancy/Calculator')) as any) }));

@@ -96,3 +112,3 @@ const mockedReactComponentsInVitest = Spy.mockReactComponents(await import('./my/fancy/Calculator'), 'Calculator');

You may apply additional behavior to every spy. The valid operations here are:
- `configure` (allows to override some behavior of the spy)

@@ -109,3 +125,3 @@ - `calls` (does make the spy call the provided functions sequentially)

- `addSnapshotSerializer` (defines in `jest` snapshots how the spy will be serialized)
All those methods on a spy has been designed in a builder pattern. So you may chain any of

@@ -201,3 +217,3 @@ these configurations. Be aware some behaviors override existing behaviors.

- `getCallCount` (returns the number of made calls)
```ts

@@ -237,8 +253,11 @@ const spy = Spy();

### Constructor
```ts
Spy(spyName:string = 'the spy') => SpyInstance
```
The returned Spy instance has his own name-attribute (only) for debugging purpose.
### setup (static)
```ts

@@ -256,4 +275,6 @@ Spy.setup(config: {

```
This function should be ideally called in some setup-test file, but is required to be called to get all
benefits of `spy4js`.
- **afterEach**: The test runners `afterEach` hook (default: `global.afterEach`)

@@ -266,2 +287,3 @@ - **beforeEach**: The test runners `beforeEach` hook (default: `global.beforeEach`)

### configure (static)
```ts

@@ -275,6 +297,8 @@ Spy.configure(config: {

```
Using this function you may edit the default behavior `spy4js` itself.
- **useOwnEquals**: Applies for all spy instances. See [configure](#configure) for more details.
- **enforceOrder**: Opt-in to the [enforce-order mode](#enforce-order-mode).
- **useGenericReactMocks**: Lets you opt in into using generic react components for mocks
- **useGenericReactMocks**: Lets you opt in into using generic react components for mocks
created via [mockReactComponents](#mockreactcomponents-static).

@@ -284,8 +308,10 @@ - **afterEachCb**: Lets you override the default afterEach fuctionality.

### on (static)
```ts
Spy.on(object: object, methodName: string) => SpyInstance
```
Initializing a spy on an object, simply replaces the original function by a spy and
stores the necessary information to be able to restore the mocked method.
Initializing a spy on an object, simply replaces the original function by a spy and
stores the necessary information to be able to restore the mocked method.
If the attribute has already been spied or is not a function, the Spy will throw an exception

@@ -296,5 +322,7 @@ to avoid unexpected behavior. You never want to spy other attributes than functions and

### mock (static)
```ts
Spy.mock(object: object, ...methodNames: string[]) => Object (Mock)
```
Creating an object that references spies for all given methodNames.

@@ -305,6 +333,8 @@ Initialize as many spies as required for the same object. Only

### mockReactComponents (static)
```ts
Spy.mockReactComponents(object: object, ...methodNames: string[]) => Object (Mock)
```
Same as [mockModule](#mockModule-static) but designed for ReactJS components. The registered
Same as [mock](#mock-static) but designed for ReactJS components. The registered
spies return `null` instead of `undefined`. This makes minimal usable React components.

@@ -317,13 +347,17 @@ Even if in most cases the pure mocking is nice enough, you can even test the number

### initMocks (static)
```ts
Spy.initMocks(scope?: string) => void
```
Does initialize all global and scope-related mocks by applying spies. Mocks can be
created with [mock](#mock) or [mockModule](#mockModule). This function has not to
created with [mock](#mock-static) or [mockReactComponents](#mockreactcomponents-static). This function has not to
be called manually, if you rely on the default test suite hooks.
### restoreAll (static)
```ts
Spy.restoreAll() => void
```
Does restore all mocked objects to their original state. See [restore](#restore) for

@@ -334,5 +368,7 @@ further information. This function has not be called manually, if you rely on

### resetAll (static)
```ts
Spy.resetAll() => void
```
Does reset all existing spies. This applies even to persistent spies.

@@ -344,7 +380,10 @@ See [reset](#reset) for further information. This function has not to be

### IGNORE (static)
```ts
Spy.IGNORE = $Internal Symbol$
```
This object can be passed anywhere where you want the "[wasCalledWith](#wascalledwith-fact)"
or "[hasCallHistory](#hascallhistory-fact)" to ignore that object or value for comparison.
```ts

@@ -358,8 +397,11 @@ spy({prop: 'value', other: 13}, 12);

### COMPARE (static)
```ts
Spy.COMPARE(comparator: (arg: any) => boolean | void) => SpyComparator
```
This function can be called with a custom comparator and passed anywhere where you want the "[wasCalledWith](#wascalledwith-fact)"
or "[hasCallHistory](#hasCallHistory-fact)" to apply your custom comparison. Very useful if
or "[hasCallHistory](#hascallhistory-fact)" to apply your custom comparison. Very useful if
the spy gets called with functions that you want to test additionally.
```ts

@@ -375,10 +417,13 @@ spy(() => ({ prop: 'value', other: 13 }), 12);

### MAPPER (static)
```ts
Spy.MAPPER(from: any | any[], to: any) => SpyComparator
```
This function can be called in the same places like `Spy.COMPARE`. It is not that much
customizable but provides a nice way to evaluate mapper functions. Meaning pure
customizable but provides a nice way to evaluate mapper functions. Meaning pure
functions that return some output for given inputs. The function will be called exactly
once for each comparison, so you can even rely on site effects you might want to test,
if you want to use this for non-pure functions.
```ts

@@ -393,12 +438,14 @@ spy((value: number) => ({ prop: 'here', other: value }), 12);

### configure
```ts
spy.configure(config: { useOwnEquals?: boolean, persistent?: boolean }) => (this) SpyInstance
```
With `configure` the spy can be configured. One configuration possibility
is to ignore any `equals` methods while comparing objects. There might be libraries which
come with those methods, but do not support ES6 classes or anything else. By default, this
configuration has been set to favor own `equals` implementations while comparing objects.
configuration has been set to favor own `equals` implementations while comparing objects.
Another possible configuration is to make the spy persist while other spies have to restore
when ["restoreAll"](#restoreall) was called. This spy can ONLY RESTORE the mocked object when
when ["restoreAll"](#restoreall-static) was called. This spy can ONLY RESTORE the mocked object when
you configure it back to be NOT PERSISTENT. This configuration can only be applied to mocking

@@ -408,5 +455,7 @@ spies. For Spies created with `Spy()` this configuration will throw an exception.

### calls
```ts
spy.calls(...functions:Array<Function>) => (this) SpyInstance
```
The provided functions will be called sequentially in order when the spy will be called.

@@ -417,5 +466,7 @@ Meaning `spy.calls(func1, func2, func3)` will call first `func1` then `func2` and the rest

### returns
```ts
spy.returns(...args: Array<any>) => (this) SpyInstance
```
The provided arguments will be returned sequentially in order when the spy will be called.

@@ -426,5 +477,7 @@ Meaning `spy.returns(arg1, arg2, arg3)` will return first `arg1` then `arg2` and the rest

### resolves
```ts
spy.resolves(...args: Array<any>) => (this) SpyInstance
```
The provided arguments will be resolved sequentially in order when the spy will be called.

@@ -434,7 +487,8 @@ Meaning `spy.resolves(arg1, arg2, arg3)` will return first `Promise.resolve(arg1)` then `Promise.resolve(arg2)` and the rest

### rejects
### rejects
```ts
spy.rejects(...args: Array<?string | Error>) => (this) SpyInstance
```
The provided arguments will be rejected sequentially in order when the spy will be called.

@@ -446,5 +500,7 @@ Meaning `spy.rejects('foo', null, new Error('bar'))` will return first `Promise.reject(new Error('foo'))`

### throws
```ts
spy.throws(message: ?string | Error) => (this) SpyInstance
```
Perform this on a spy to make it throw an error when called. The error message can be

@@ -455,11 +511,15 @@ provided, but a default has also been implemented. If an Error instance will be passed,

### reset
```ts
spy.reset() => (this) SpyInstance
```
Does reset the registered calls on that spy.
### restore
```ts
spy.restore() => (this) SpyInstance
```
Restores the spied object, if existing, to its original state. The spy won't lose any

@@ -472,5 +532,7 @@ other information. So it is still aware of made calls, can be plugged anywhere else

### transparent
```ts
spy.transparent() => (this) SpyInstance
```
Can be useful with spies on objects. It does make the spy behave like not existing. So

@@ -481,5 +543,7 @@ the original function of the "mocked" object will be called, but the spy does remember

### transparentAfter
```ts
spy.transparentAfter(callCount:number) => (this) SpyInstance
```
Works like [transparent](#transparent) but the spy will get transparent after called as

@@ -490,11 +554,15 @@ often as specified. Meaning `spy.transparentAfter(num)` will not be transparent on the first

### addSnapshotSerializer
```ts
spy.addSnapshotSerializer(serialize: string | ((...args: any[]) => string)) => (this) SpyInstance
```
Determines the rendered output of `jest` snapshots when the certain spy would get rendered.
### wasCalled (fact)
```ts
spy.wasCalled(callCount: number = 0) => void
```
This call does display a fact. So if the spy is violating the fact, it is told to throw

@@ -504,5 +572,7 @@ an error. The provided argument does represent the registered calls on that spy.

### wasNotCalled (fact)
```ts
spy.wasNotCalled() => void
```
This fact displays that the spy has never been called. Directly after the spy was [reset](#reset)ed,

@@ -512,7 +582,9 @@ this fact will be given.

### wasCalledWith (fact)
```ts
spy.wasCalledWith(...args: Array<any>) => void
```
This fact displays that the spy has been called at least once with equal arguments.
This fact displays that the spy has been called at least once with equal arguments.
The equality check is a deep equality check, which (by default) does consider

@@ -522,6 +594,6 @@ own "equals" implementations.

By supplying `Spy.IGNORE` anywhere inside the expected call arguments, you
can avoid that the comparison will be further executed. See [Spy.IGNORE](#IGNORE) for further information and examples.
can avoid that the comparison will be further executed. See [Spy.IGNORE](#ignore-static) for further information and examples.
The deep equality check does also recursively iterate to the first difference found and is able
to return a string which contains valuable information about the first found difference.
to return a string which contains valuable information about the first found difference.

@@ -533,11 +605,15 @@ If any difference will be detected, the fact isn't true, and a helpful error message will be displayed.

### wasNotCalledWith (fact)
```ts
spy.wasNotCalledWith(...args: Array<any>) => void
```
This fact displays simply the opposite of [wasCalledWith](#wascalledwith-fact).
### hasCallHistory (fact)
```ts
spy.hasCallHistory(...callHistory: Array<Array<any> | any>) => void
```
Works similar to [wasCalledWith](#wascalledwith-fact) but instead matches each

@@ -550,5 +626,7 @@ call one by one in **correct order** and **correct call count**.

### hasProps (fact)
```ts
spy.hasProps(props: any) => void
```
This fact displays that the spy has currently the given props in React context of a mocked component.

@@ -559,5 +637,7 @@

### getAllCallArguments
```ts
spy.getAllCallArguments() => Array<any[]>
```
Returns the call arguments of all made calls to the spy.

@@ -567,5 +647,7 @@ Especially returning an empty array if the spy has never been called.

### getCallArguments
```ts
spy.getCallArguments(callNr: number = 0) => Array<any>
```
Returns the call arguments that were registered on the given call. Meaning

@@ -577,5 +659,7 @@ `spy.getCallArguments(num)` does return the (num + 1)'th call arguments.

### getCallArgument
```ts
spy.getCallArgument(callNr: number = 0, argNr: number = 0) => any
```
Same as [getCallArguments](#getcallarguments) but returns only a single entry out

@@ -586,11 +670,15 @@ of the array of arguments. Most useful in situations where exactly one call param is expected.

### getLatestCallArgument
```ts
spy.getLatestCallArgument(argNr: number = 0) => any
```
Same as [getCallArgument](#getcallargument) but uses only the latest call.
### getProps
```ts
spy.getProps() => any
```
Same as [getLatestCallArgument](#getlatestcallargument) but uses only the first arg. Can be useful in

@@ -600,13 +688,18 @@ combination with [mockReactComponents](#mockreactcomponents-static).

### getCallCount
```ts
spy.getCallCount() => number
```
This method simply returns the number of made calls on the spy.
### showCallArguments
```ts
spy.showCallArguments(additionalInformation: Array<string> = []) => string
```
This primarily internally used method is responsible for returning formatted informative debug
messages when facts aren't true. Let's do an example:
```ts

@@ -620,8 +713,12 @@ const spy = Spy('my awesome spy');

```
The following broken fact...
```ts
spy.wasCalledWith(42, 'test', {attr1: [1, 2, new Date(2017, 1, 20)], attr2: 1336});
```
...would produce the following error output:
```
```text
Error:

@@ -646,4 +743,5 @@

```
There you can see that the arguments of the fact (displayed above all others) does not
match any of the call arguments on the 5 made calls.
match any of the call arguments on the 5 made calls.

@@ -660,2 +758,3 @@ For each call we display additional error information (the first found difference).

different objects you could:
```ts

@@ -667,8 +766,12 @@ const callArgs = spy.getCallArguments(0/* for the 0'th call above*/);

## Enforce-Order Mode
You can opt-in to the enforce-order mode. Which might become the default in some
future version but will need first further evaluation and will always stay configurable.
```ts
Spy.configure({ enforceOrder: true });
```
This mode enforces that the "facts" will be called in the correct order.
```ts

@@ -687,3 +790,5 @@ // success

```
Be aware "facts" that you might need to get used to it, because the following would be valid, too.
```ts

@@ -700,4 +805,6 @@ // success

```
Nevertheless, this mode should make your tests more readable and clear, because you can avoid
checking the same things on and on again or resetting the spies in tests. Another example:
```ts

@@ -721,2 +828,30 @@ const mock_WS = Spy.mock(WS, 'fetchData', 'fetchFallback');

## Bun Support
[`bun`](https://bun.sh/) includes an alternative fast runtime to NodeJS.
In order to use this library with `bun test`, you need to add a `bunfig.toml` with
a preload script:
```toml
[test]
preload = "./bun-preload.ts"
```
And the preload script should implement missing test APIs. At the time of writing that would be
at least this:
```ts
// necessary until Bun has implemented them
expect.addSnapshotSerializer = () => null;
expect.getState = () => ({}) as any;
```
**⚠️ Disclaimers:**
- You cannot call `Spy.setup()` in a single place inside of the preload script as the `beforeEach` hook of
will be differently scoped, when you want/need to support scoped mocks. However, you can call the `Spy.setup`
again in the tests where you need scoped mocks and provide it a new `beforeEach` hook.
- Since `expect.getState` is not correctly implemented, you will not be prevented correctly from instantiating mocks
inside of test runs.
[license-image]: https://img.shields.io/badge/license-MIT-blue.svg

@@ -723,0 +858,0 @@ [license-url]: https://github.com/fdc-viktor-luft/spy4js/blob/master/LICENSE

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