@zudojs/testing 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -206,6 +206,14 @@ own, and `logger: createLogger({ name })` from `@zudojs/logger` prints.
206
206
  - `createStub()` hands back the same no-op for a given property every time,
207
207
  so `stub.handler === stub.handler` and a register/unregister pair written
208
208
  against a stub actually unregisters.
209
+ - The overrides passed to `createStub()` are the stub's own enumerable
210
+ properties, so `Object.keys(stub)`, `{ ...stub }` and
211
+ `expect.objectContaining({ send })` see them. The unstubbed no-ops are
212
+ answered on access only and are not own keys. `asymmetricMatch` is answered
213
+ with `undefined`, so Vitest's `equals` does not mistake a stub for a matcher.
214
+ - `createSpyMethod(...).restore()` only puts the original method back. The
215
+ recorded `calls`, `results` and `errors` are kept, so you can assert on them
216
+ after restoring. Calls made after `restore()` are not recorded.
209
217
  - `InMemoryTestStorage.set(key, value, 0)` means "already expired", not "no
210
218
  expiry"; only an omitted TTL (or `Infinity`) never expires, and a `NaN` TTL
211
219
  throws. `delete()` returns `false` for an entry that has already expired.
@@ -49,7 +49,11 @@ export interface SpyMethod<TObj, TMethod extends keyof TObj> {
49
49
  readonly results: readonly unknown[];
50
50
  readonly errors: readonly unknown[];
51
51
  readonly callCount: number;
52
- /** Reinstates the original method exactly as it was found. */
52
+ /**
53
+ * Reinstates the original method exactly as it was found. The recorded
54
+ * `calls`, `results` and `errors` are kept, so they can be asserted after
55
+ * restoring; calls made after `restore()` are not recorded.
56
+ */
53
57
  restore: () => void;
54
58
  }
55
59
  /**
@@ -69,6 +73,7 @@ export interface SpyMethod<TObj, TMethod extends keyof TObj> {
69
73
  * expect(spy.calls).toHaveLength(1);
70
74
  *
71
75
  * spy.restore();
76
+ * expect(spy.calls).toHaveLength(1); // still recorded after restore
72
77
  * ```
73
78
  */
74
79
  export declare function createSpyMethod<TObj, TMethod extends keyof TObj>(object: TObj, property: TMethod): SpyMethod<TObj, TMethod>;
@@ -77,6 +77,7 @@ export function createSpyFn(fn) {
77
77
  * expect(spy.calls).toHaveLength(1);
78
78
  *
79
79
  * spy.restore();
80
+ * expect(spy.calls).toHaveLength(1); // still recorded after restore
80
81
  * ```
81
82
  */
82
83
  export function createSpyMethod(object, property) {
@@ -120,9 +121,6 @@ export function createSpyMethod(object, property) {
120
121
  target[key] = original;
121
122
  else
122
123
  delete target[key];
123
- calls.length = 0;
124
- results.length = 0;
125
- errors.length = 0;
126
124
  },
127
125
  };
128
126
  }
@@ -7,7 +7,9 @@
7
7
  * Creates a stub object from an interface.
8
8
  *
9
9
  * All methods return undefined by default. Override specific methods
10
- * by passing an overrides object.
10
+ * by passing an overrides object. The overrides are the stub's own
11
+ * enumerable properties, so `Object.keys(stub)`, `{ ...stub }` and
12
+ * `expect.objectContaining` see them; unstubbed no-ops are not own keys.
11
13
  *
12
14
  * @typeParam T - The interface type to stub.
13
15
  * @param overrides - Optional method implementations.
@@ -8,12 +8,14 @@
8
8
  *
9
9
  * `then` is the important one: answering it makes the stub a thenable, so
10
10
  * `await stub` calls it expecting a promise callback. The fake never resolves,
11
- * and the test hangs until it times out with no indication why.
11
+ * and the test hangs until it times out with no indication why. Likewise
12
+ * `asymmetricMatch` makes Vitest's `equals` treat the stub as a matcher.
12
13
  */
13
14
  const NON_CALLABLE_KEYS = new Set([
14
15
  "then",
15
16
  "catch",
16
17
  "finally",
18
+ "asymmetricMatch",
17
19
  Symbol.toPrimitive,
18
20
  Symbol.iterator,
19
21
  Symbol.asyncIterator,
@@ -23,7 +25,9 @@ const NON_CALLABLE_KEYS = new Set([
23
25
  * Creates a stub object from an interface.
24
26
  *
25
27
  * All methods return undefined by default. Override specific methods
26
- * by passing an overrides object.
28
+ * by passing an overrides object. The overrides are the stub's own
29
+ * enumerable properties, so `Object.keys(stub)`, `{ ...stub }` and
30
+ * `expect.objectContaining` see them; unstubbed no-ops are not own keys.
27
31
  *
28
32
  * @typeParam T - The interface type to stub.
29
33
  * @param overrides - Optional method implementations.
@@ -69,6 +73,15 @@ export function createStub(overrides = {}) {
69
73
  has(_target, prop) {
70
74
  return !NON_CALLABLE_KEYS.has(prop);
71
75
  },
76
+ ownKeys() {
77
+ return Reflect.ownKeys(overrides);
78
+ },
79
+ getOwnPropertyDescriptor(_target, prop) {
80
+ const descriptor = Reflect.getOwnPropertyDescriptor(overrides, prop);
81
+ return descriptor === undefined
82
+ ? undefined
83
+ : { ...descriptor, configurable: true };
84
+ },
72
85
  });
73
86
  }
74
87
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zudojs/testing",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Test helpers, fixtures, mocks, and utilities for testing Zudojs applications.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,19 +19,19 @@
19
19
  "!dist/.tsbuildinfo"
20
20
  ],
21
21
  "dependencies": {
22
- "@zudojs/config": "1.3.0",
22
+ "@zudojs/config": "1.3.1",
23
23
  "@zudojs/constants": "1.1.2",
24
- "@zudojs/container": "1.2.0",
24
+ "@zudojs/container": "1.2.1",
25
25
  "@zudojs/errors": "1.3.0",
26
- "@zudojs/events": "1.3.0",
27
- "@zudojs/http": "1.4.0",
28
- "@zudojs/logger": "1.4.0",
29
- "@zudojs/messaging": "1.2.0",
26
+ "@zudojs/events": "1.3.1",
27
+ "@zudojs/http": "1.4.2",
28
+ "@zudojs/logger": "1.4.1",
29
+ "@zudojs/messaging": "1.2.1",
30
30
  "@zudojs/middleware": "1.1.0",
31
- "@zudojs/queue": "1.4.0",
32
- "@zudojs/security": "1.3.0",
33
- "@zudojs/serialization": "1.2.0",
34
- "@zudojs/storage": "1.2.0",
31
+ "@zudojs/queue": "1.4.1",
32
+ "@zudojs/security": "1.3.1",
33
+ "@zudojs/serialization": "1.2.1",
34
+ "@zudojs/storage": "1.2.1",
35
35
  "@zudojs/types": "1.2.0"
36
36
  },
37
37
  "devDependencies": {