vitest-auto-spy 4.0.1 → 4.2.0

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/dist/angular.js CHANGED
@@ -6,16 +6,390 @@ import { isStandalone, Component, Injector, runInInjectionContext, NO_ERRORS_SCH
6
6
  import { By } from '@angular/platform-browser';
7
7
 
8
8
  // src/lib/use-vitest-adapter.ts
9
+
10
+ // src/lib/constants.ts
11
+ var SWEEP_SENTINEL = /* @__PURE__ */ Symbol.for("vitest-auto-spy.sweepSentinel");
12
+
13
+ // src/lib/dispose-symbol.ts
14
+ var NODE_DISPOSE_KEY = "nodejs.dispose";
15
+ function installDisposeSymbol(host) {
16
+ const existing = Reflect.get(host, "dispose");
17
+ if (typeof existing === "symbol") {
18
+ return existing;
19
+ }
20
+ const shim = Symbol.for(NODE_DISPOSE_KEY);
21
+ Object.defineProperty(host, "dispose", { value: shim, enumerable: false, configurable: true, writable: false });
22
+ return shim;
23
+ }
24
+ var DISPOSE = installDisposeSymbol(Symbol);
25
+
26
+ // src/lib/spy-probe.ts
27
+ var FAST_SPY_BRAND = /* @__PURE__ */ Symbol.for("vitest-auto-spy.fastSpy");
28
+ function isFastSpy(value) {
29
+ return typeof value === "function" && FAST_SPY_BRAND in value;
30
+ }
31
+ function isThenable(value) {
32
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
33
+ return false;
34
+ }
35
+ return typeof Reflect.get(value, "then") === "function";
36
+ }
37
+
38
+ // src/lib/fast-spy.ts
39
+ var clearEpoch = 0;
40
+ var resetEpoch = 0;
41
+ function clearAllFastSpies() {
42
+ clearEpoch += 1;
43
+ }
44
+ function resetAllFastSpies() {
45
+ clearEpoch += 1;
46
+ resetEpoch += 1;
47
+ }
48
+ var CONFIG = /* @__PURE__ */ Symbol("vitest-auto-spy.fastSpy.config");
49
+ var STATE = /* @__PURE__ */ Symbol("vitest-auto-spy.fastSpy.state");
50
+ var invocationCallCounter = 1;
51
+ var FastMockStateImpl = class {
52
+ constructor(owner) {
53
+ this.owner = owner;
54
+ this.recordedCalls = [];
55
+ this.recordedContexts = [];
56
+ this.recordedInstances = [];
57
+ this.recordedOrder = [];
58
+ this.recordedResults = [];
59
+ this.recordedSettledResults = [];
60
+ }
61
+ get calls() {
62
+ syncEpochs(this.owner);
63
+ return this.recordedCalls;
64
+ }
65
+ set calls(value) {
66
+ this.recordedCalls = value;
67
+ }
68
+ get contexts() {
69
+ syncEpochs(this.owner);
70
+ return this.recordedContexts;
71
+ }
72
+ set contexts(value) {
73
+ this.recordedContexts = value;
74
+ }
75
+ get instances() {
76
+ syncEpochs(this.owner);
77
+ return this.recordedInstances;
78
+ }
79
+ set instances(value) {
80
+ this.recordedInstances = value;
81
+ }
82
+ get invocationCallOrder() {
83
+ syncEpochs(this.owner);
84
+ return this.recordedOrder;
85
+ }
86
+ set invocationCallOrder(value) {
87
+ this.recordedOrder = value;
88
+ }
89
+ get results() {
90
+ syncEpochs(this.owner);
91
+ return this.recordedResults;
92
+ }
93
+ set results(value) {
94
+ this.recordedResults = value;
95
+ }
96
+ get settledResults() {
97
+ syncEpochs(this.owner);
98
+ return this.recordedSettledResults;
99
+ }
100
+ set settledResults(value) {
101
+ this.recordedSettledResults = value;
102
+ }
103
+ get lastCall() {
104
+ const calls = this.calls;
105
+ return calls[calls.length - 1];
106
+ }
107
+ /** Drop everything recorded, keeping the object identity a spec may be holding. */
108
+ empty() {
109
+ this.recordedCalls = [];
110
+ this.recordedContexts = [];
111
+ this.recordedInstances = [];
112
+ this.recordedOrder = [];
113
+ this.recordedResults = [];
114
+ this.recordedSettledResults = [];
115
+ }
116
+ };
117
+ function syncEpochs(spy) {
118
+ const config = spy[CONFIG];
119
+ if (config.resetSeen !== resetEpoch) {
120
+ config.resetSeen = resetEpoch;
121
+ config.implementation = config.original;
122
+ config.onceImplementations = [];
123
+ }
124
+ if (config.clearSeen !== clearEpoch) {
125
+ config.clearSeen = clearEpoch;
126
+ spy[STATE]?.empty();
127
+ }
128
+ }
129
+ function configOf(spy) {
130
+ syncEpochs(spy);
131
+ return spy[CONFIG];
132
+ }
133
+ function stateOf(spy) {
134
+ const existing = spy[STATE];
135
+ if (existing) {
136
+ return existing;
137
+ }
138
+ const created = new FastMockStateImpl(spy);
139
+ spy[STATE] = created;
140
+ return created;
141
+ }
142
+ function throwConstructorError(shorthand) {
143
+ throw new TypeError(
144
+ `Cannot use \`${shorthand}\` when called with \`new\`. Use \`mockImplementation\` with a \`class\` keyword instead. See https://vitest.dev/api/mock#class-support for more information.`
145
+ );
146
+ }
147
+ function self(value) {
148
+ return value;
149
+ }
150
+ var FAST_SPY_PROTOTYPE = Object.create(Function.prototype);
151
+ function definePrototypeMember(key, value) {
152
+ Object.defineProperty(FAST_SPY_PROTOTYPE, key, { value, writable: true, configurable: true, enumerable: false });
153
+ }
154
+ definePrototypeMember(FAST_SPY_BRAND, true);
155
+ definePrototypeMember("_isMockFunction", true);
156
+ Object.defineProperty(FAST_SPY_PROTOTYPE, "mock", {
157
+ get() {
158
+ const spy = self(this);
159
+ syncEpochs(spy);
160
+ return stateOf(spy);
161
+ },
162
+ configurable: true,
163
+ enumerable: true
164
+ });
165
+ definePrototypeMember("getMockImplementation", function getMockImplementation() {
166
+ const config = configOf(self(this));
167
+ return config.onceImplementations[0] ?? config.implementation;
168
+ });
169
+ definePrototypeMember("mockImplementation", function mockImplementation(implementation) {
170
+ configOf(self(this)).implementation = implementation;
171
+ return this;
172
+ });
173
+ definePrototypeMember("mockImplementationOnce", function mockImplementationOnce(implementation) {
174
+ configOf(self(this)).onceImplementations.push(implementation);
175
+ return this;
176
+ });
177
+ definePrototypeMember(
178
+ "withImplementation",
179
+ function withImplementation(implementation, callback) {
180
+ const spy = self(this);
181
+ const config = configOf(spy);
182
+ const previousImplementation = config.implementation;
183
+ const previousOnce = config.onceImplementations;
184
+ const restore = () => {
185
+ config.implementation = previousImplementation;
186
+ config.onceImplementations = previousOnce;
187
+ };
188
+ config.implementation = implementation;
189
+ config.onceImplementations = [];
190
+ const returned = callback();
191
+ if (isThenable(returned)) {
192
+ return returned.then(() => {
193
+ restore();
194
+ return spy;
195
+ });
196
+ }
197
+ restore();
198
+ return spy;
199
+ }
200
+ );
201
+ definePrototypeMember("mockReturnThis", function mockReturnThis() {
202
+ configOf(self(this)).implementation = function returnThis() {
203
+ return this;
204
+ };
205
+ return this;
206
+ });
207
+ definePrototypeMember("mockReturnValue", function mockReturnValue(value) {
208
+ configOf(self(this)).implementation = function returnValue() {
209
+ if (new.target) {
210
+ throwConstructorError("mockReturnValue");
211
+ }
212
+ return value;
213
+ };
214
+ return this;
215
+ });
216
+ definePrototypeMember("mockReturnValueOnce", function mockReturnValueOnce(value) {
217
+ configOf(self(this)).onceImplementations.push(function returnValueOnce() {
218
+ if (new.target) {
219
+ throwConstructorError("mockReturnValueOnce");
220
+ }
221
+ return value;
222
+ });
223
+ return this;
224
+ });
225
+ definePrototypeMember("mockThrow", function mockThrow(value) {
226
+ configOf(self(this)).implementation = function throwValue() {
227
+ throw value;
228
+ };
229
+ return this;
230
+ });
231
+ definePrototypeMember("mockThrowOnce", function mockThrowOnce(value) {
232
+ configOf(self(this)).onceImplementations.push(function throwValueOnce() {
233
+ throw value;
234
+ });
235
+ return this;
236
+ });
237
+ definePrototypeMember("mockResolvedValue", function mockResolvedValue(value) {
238
+ configOf(self(this)).implementation = function resolvedValue() {
239
+ if (new.target) {
240
+ throwConstructorError("mockResolvedValue");
241
+ }
242
+ return Promise.resolve(value);
243
+ };
244
+ return this;
245
+ });
246
+ definePrototypeMember("mockResolvedValueOnce", function mockResolvedValueOnce(value) {
247
+ configOf(self(this)).onceImplementations.push(function resolvedValueOnce() {
248
+ if (new.target) {
249
+ throwConstructorError("mockResolvedValueOnce");
250
+ }
251
+ return Promise.resolve(value);
252
+ });
253
+ return this;
254
+ });
255
+ definePrototypeMember("mockRejectedValue", function mockRejectedValue(value) {
256
+ configOf(self(this)).implementation = function rejectedValue() {
257
+ if (new.target) {
258
+ throwConstructorError("mockRejectedValue");
259
+ }
260
+ return Promise.reject(value);
261
+ };
262
+ return this;
263
+ });
264
+ definePrototypeMember("mockRejectedValueOnce", function mockRejectedValueOnce(value) {
265
+ configOf(self(this)).onceImplementations.push(function rejectedValueOnce() {
266
+ if (new.target) {
267
+ throwConstructorError("mockRejectedValueOnce");
268
+ }
269
+ return Promise.reject(value);
270
+ });
271
+ return this;
272
+ });
273
+ function clearSpy(spy) {
274
+ syncEpochs(spy);
275
+ spy[STATE]?.empty();
276
+ }
277
+ function resetSpy(spy) {
278
+ const config = configOf(spy);
279
+ spy[STATE]?.empty();
280
+ config.implementation = config.original;
281
+ config.onceImplementations = [];
282
+ }
283
+ definePrototypeMember("mockClear", function mockClear() {
284
+ clearSpy(self(this));
285
+ return this;
286
+ });
287
+ definePrototypeMember("mockReset", function mockReset() {
288
+ resetSpy(self(this));
289
+ return this;
290
+ });
291
+ definePrototypeMember("mockRestore", function mockRestore() {
292
+ resetSpy(self(this));
293
+ return void 0;
294
+ });
295
+ definePrototypeMember("mockName", function mockName(name) {
296
+ if (typeof name === "string") {
297
+ self(this)[CONFIG].name = name;
298
+ }
299
+ return this;
300
+ });
301
+ definePrototypeMember("getMockName", function getMockName() {
302
+ return self(this)[CONFIG].name || "vi.fn()";
303
+ });
304
+ definePrototypeMember(DISPOSE, function dispose() {
305
+ resetSpy(self(this));
306
+ });
307
+ function settleInto(settled, returned) {
308
+ if (isThenable(returned)) {
309
+ returned.then(
310
+ (value) => {
311
+ settled.type = "fulfilled";
312
+ settled.value = value;
313
+ },
314
+ (reason) => {
315
+ settled.type = "rejected";
316
+ settled.value = reason;
317
+ }
318
+ );
319
+ return;
320
+ }
321
+ settled.type = "fulfilled";
322
+ settled.value = returned;
323
+ }
324
+ function invoke(spy, thisArg, args, newTarget) {
325
+ const config = spy[CONFIG];
326
+ if (config.clearSeen !== clearEpoch || config.resetSeen !== resetEpoch) {
327
+ syncEpochs(spy);
328
+ }
329
+ const state = spy[STATE] ?? stateOf(spy);
330
+ const result = { type: "incomplete", value: void 0 };
331
+ const settled = { type: "incomplete", value: void 0 };
332
+ const context = newTarget ? void 0 : thisArg;
333
+ state.recordedCalls.push(args);
334
+ state.recordedOrder.push(invocationCallCounter++);
335
+ state.recordedResults.push(result);
336
+ state.recordedSettledResults.push(settled);
337
+ state.recordedContexts.push(context);
338
+ state.recordedInstances.push(context);
339
+ const implementation = config.onceImplementations.shift() ?? config.implementation;
340
+ let returned;
341
+ try {
342
+ returned = newTarget ? Reflect.construct(implementation ?? Object, args, newTarget) : implementation?.apply(thisArg, args);
343
+ } catch (error) {
344
+ result.type = "throw";
345
+ result.value = error;
346
+ settled.type = "rejected";
347
+ settled.value = error;
348
+ throw error;
349
+ }
350
+ result.type = "return";
351
+ result.value = returned;
352
+ if (newTarget) {
353
+ state.recordedContexts[state.recordedContexts.length - 1] = returned;
354
+ state.recordedInstances[state.recordedInstances.length - 1] = returned;
355
+ }
356
+ settleInto(settled, returned);
357
+ return returned;
358
+ }
359
+ function createFastSpy(implementation, name) {
360
+ const config = {
361
+ implementation,
362
+ onceImplementations: [],
363
+ name: name ?? "",
364
+ original: implementation,
365
+ clearSeen: clearEpoch,
366
+ resetSeen: resetEpoch
367
+ };
368
+ const callable = function Mock(...args) {
369
+ return invoke(spy, this, args, new.target);
370
+ };
371
+ const spy = callable;
372
+ Object.setPrototypeOf(spy, FAST_SPY_PROTOTYPE);
373
+ spy[CONFIG] = config;
374
+ spy[STATE] = void 0;
375
+ return spy;
376
+ }
9
377
  function asVitestMock(mock) {
10
378
  return mock;
11
379
  }
380
+ var sweepSentinel = vi.fn();
381
+ Object.defineProperty(sweepSentinel, SWEEP_SENTINEL, { value: true, enumerable: false, configurable: true });
382
+ sweepSentinel.mockClear = function clearAllMocksSweep() {
383
+ clearAllFastSpies();
384
+ return sweepSentinel;
385
+ };
386
+ sweepSentinel.mockReset = function resetAllMocksSweep() {
387
+ resetAllFastSpies();
388
+ return sweepSentinel;
389
+ };
12
390
  var vitestMockAdapter = guardAccessorSpies({
13
391
  createMockFn(implementation, name) {
14
- const mock = implementation ? vi.fn(implementation) : vi.fn();
15
- if (name !== void 0) {
16
- mock.mockName(name);
17
- }
18
- return mock;
392
+ return createFastSpy(implementation, name) ;
19
393
  },
20
394
  spyOnGetter(target, property) {
21
395
  return vi.spyOn(target, property, "get");
@@ -42,19 +416,6 @@ function useVitestAdapter() {
42
416
  registerMockAdapter(vitestMockAdapter);
43
417
  }
44
418
 
45
- // src/lib/dispose-symbol.ts
46
- var NODE_DISPOSE_KEY = "nodejs.dispose";
47
- function installDisposeSymbol(host) {
48
- const existing = Reflect.get(host, "dispose");
49
- if (typeof existing === "symbol") {
50
- return existing;
51
- }
52
- const shim = Symbol.for(NODE_DISPOSE_KEY);
53
- Object.defineProperty(host, "dispose", { value: shim, enumerable: false, configurable: true, writable: false });
54
- return shim;
55
- }
56
- var DISPOSE = installDisposeSymbol(Symbol);
57
-
58
419
  // src/lib/docs-links.ts
59
420
  var DOCS = "https://asdalexey.github.io/vitest-auto-spy";
60
421
  var DOCS_LINKS = {
@@ -169,6 +530,17 @@ function serializeValue(value) {
169
530
  }
170
531
 
171
532
  // src/lib/args-map.ts
533
+ function isSinglePrimitiveArgs(args) {
534
+ if (args.length !== 1) {
535
+ return false;
536
+ }
537
+ const [argument] = args;
538
+ const kind = typeof argument;
539
+ if (kind === "object" || kind === "function" || kind === "symbol") {
540
+ return argument === null;
541
+ }
542
+ return !Object.is(argument, -0);
543
+ }
172
544
  function isAsymmetricMatcher(value) {
173
545
  return typeof value === "object" && value !== null && "asymmetricMatch" in value && typeof value.asymmetricMatch === "function";
174
546
  }
@@ -203,6 +575,21 @@ var ArgsMap = class {
203
575
  // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
204
576
  // build a key that provably cannot match, and throws it away one line later.
205
577
  #arities = /* @__PURE__ */ new Set();
578
+ /**
579
+ * The configs of exactly one primitive argument, keyed by the argument itself.
580
+ *
581
+ * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
582
+ * **every call** of that spy. Through the string map that costs a rendered key per call — an array
583
+ * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
584
+ * do on the value with no allocation at all. The configs live in both maps: the string map still
585
+ * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
586
+ * changes.
587
+ *
588
+ * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
589
+ * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
590
+ * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
591
+ */
592
+ #exactSinglePrimitive = /* @__PURE__ */ new Map();
206
593
  set(key, value) {
207
594
  if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
208
595
  this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
@@ -210,6 +597,9 @@ var ArgsMap = class {
210
597
  }
211
598
  if (Array.isArray(key)) {
212
599
  this.#arities.add(key.length);
600
+ if (isSinglePrimitiveArgs(key)) {
601
+ this.#exactSinglePrimitive.set(key[0], value);
602
+ }
213
603
  }
214
604
  this.#map[this.#serialize(key)] = value;
215
605
  }
@@ -217,6 +607,10 @@ var ArgsMap = class {
217
607
  if (Array.isArray(key) && !this.#arities.has(key.length)) {
218
608
  return this.#findByMatcher(key);
219
609
  }
610
+ if (Array.isArray(key) && isSinglePrimitiveArgs(key)) {
611
+ const hit = this.#exactSinglePrimitive.get(key[0]);
612
+ return hit === void 0 ? this.#findByMatcher(key) : hit;
613
+ }
220
614
  const serialized = this.#serialize(key);
221
615
  if (serialized in this.#map) {
222
616
  return this.#map[serialized];
@@ -431,16 +825,12 @@ function addPromiseHelpersToCalledWithObject(calledWithObject, calledWithArgs) {
431
825
 
432
826
  // src/lib/settled-results.ts
433
827
  var NATIVE_RECORDER = {
434
- record: (returned) => returned,
435
828
  clear: () => void 0
436
829
  };
437
- function isThenable(value) {
438
- if (typeof value !== "object" && typeof value !== "function" || value === null) {
439
- return false;
440
- }
441
- return typeof Reflect.get(value, "then") === "function";
442
- }
443
830
  function installSettledResultsPolyfill(mockFn) {
831
+ if (isFastSpy(mockFn)) {
832
+ return NATIVE_RECORDER;
833
+ }
444
834
  const state = Reflect.get(mockFn, "mock");
445
835
  if (typeof state !== "object" || state === null || "settledResults" in state) {
446
836
  return NATIVE_RECORDER;
@@ -636,8 +1026,8 @@ var FunctionSpyInternals = class {
636
1026
  this.recorder.clear();
637
1027
  }
638
1028
  };
639
- function internalsOf(self, helper) {
640
- const mark = typeof self === "function" || typeof self === "object" && self !== null ? Reflect.get(self, AUTO_SPY_MARK) : void 0;
1029
+ function internalsOf(self2, helper) {
1030
+ const mark = typeof self2 === "function" || typeof self2 === "object" && self2 !== null ? Reflect.get(self2, AUTO_SPY_MARK) : void 0;
641
1031
  if (mark instanceof FunctionSpyInternals) {
642
1032
  return mark;
643
1033
  }
@@ -646,8 +1036,8 @@ function internalsOf(self, helper) {
646
1036
  var SPY_HELPERS = /* @__PURE__ */ Object.assign(
647
1037
  // The inner call carries its own mark: a pure annotation covers the call it precedes, not its
648
1038
  // arguments, and an unmarked argument call is evaluated — and everything it reaches kept.
649
- /* @__PURE__ */ promiseHelpers((self, container, helper) => {
650
- storePromiseConfig(internalsOf(self, helper).valueContainer, container);
1039
+ /* @__PURE__ */ promiseHelpers((self2, container, helper) => {
1040
+ storePromiseConfig(internalsOf(self2, helper).valueContainer, container);
651
1041
  }),
652
1042
  {
653
1043
  failWith(error) {
@@ -674,11 +1064,11 @@ function createFunctionSpy(name, unstubbed) {
674
1064
  let settledResultsRecorder = void 0;
675
1065
  const dispatch = (...actualArgs) => {
676
1066
  const returned = returnTheCorrectFakeValue(state, actualArgs, name, unstubbed);
677
- return settledResultsRecorder ? settledResultsRecorder.record(returned) : returned;
1067
+ return settledResultsRecorder ? settledResultsRecorder(returned) : returned;
678
1068
  };
679
1069
  const functionSpy = getMockAdapter().createMockFn(dispatch, name);
680
1070
  const recorder = installSettledResultsPolyfill(functionSpy);
681
- settledResultsRecorder = recorder;
1071
+ settledResultsRecorder = recorder.record;
682
1072
  const internals = new FunctionSpyInternals(state, valueContainer, functionSpy, dispatch, recorder);
683
1073
  const spy = decorate(functionSpy, SPY_HELPERS);
684
1074
  internals.observable = getObservableSupport()?.addToFunctionSpy(spy, valueContainer);
@@ -1,14 +1,14 @@
1
1
  import { flushEffects } from './chunk-5BPM3BLI.js';
2
2
  export { flushEffects, stable } from './chunk-5BPM3BLI.js';
3
3
  import './chunk-Y4YG7UOK.js';
4
- import { createSpyForToken } from './chunk-6EGUFU73.js';
4
+ import { createSpyForToken } from './chunk-KEKKEIRG.js';
5
5
  import './chunk-NQXXUJPS.js';
6
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-M3XZL5NF.js';
6
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-5URFSYDT.js';
7
7
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-DSIYS6Y5.js';
8
- import { createSpyFromClass } from './chunk-N4PT3JYE.js';
9
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-N4PT3JYE.js';
8
+ import { createSpyFromClass } from './chunk-4KCYFAJX.js';
9
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4KCYFAJX.js';
10
+ export { createFunctionSpy, errorHandler } from './chunk-4KK3ES4P.js';
10
11
  import './chunk-PC3FAZT3.js';
11
- export { createFunctionSpy, errorHandler } from './chunk-3QJUFL2N.js';
12
12
  import { isAutoSpyLike } from './chunk-XRVVZXOM.js';
13
13
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';
14
14
  import '@angular/compiler';
package/dist/bun.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import './chunk-Y4YG7UOK.js';
2
2
  import './chunk-NQXXUJPS.js';
3
- export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-M3XZL5NF.js';
3
+ export { asInstance, asInstances, asSpy, assertMocked, captureArg, createFixture, createFixtureFactory, createMock, createSpyClass, describeDuplicateCopies, expectCompletion, expectEmission, expectEmissions, expectError, expectNoEmission, flushEventLoop, flushEventLoopUntil, getPackageCopies, mockConstructor, mockDeep, moduleNamespace, narrow, setEmissionTimeout, settleDynamicImport, stubConstructor, withOverrides } from './chunk-5URFSYDT.js';
4
4
  export { countMockedProps, mockAccessorsProp, mockReadonlyProp, mockReadonlyPropGetter, mockValueProp, restoreMockedProps } from './chunk-DSIYS6Y5.js';
5
- export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-N4PT3JYE.js';
5
+ export { autoMocked, clearAutoSpy, createAutoMock, createSpyFromClass, resetAutoSpy } from './chunk-4KCYFAJX.js';
6
+ export { createFunctionSpy, errorHandler } from './chunk-4KK3ES4P.js';
6
7
  import './chunk-PC3FAZT3.js';
7
- export { createFunctionSpy, errorHandler } from './chunk-3QJUFL2N.js';
8
8
  import './chunk-XRVVZXOM.js';
9
9
  import './chunk-B45HLBA4.js';
@@ -1,4 +1,4 @@
1
- import { vitestMockAdapter } from './chunk-MG5EAMZR.js';
1
+ import { vitestMockAdapter } from './chunk-WQZ2RKS7.js';
2
2
  import { registerMockAdapter } from './shared-state.js';
3
3
 
4
4
  function useVitestAdapter() {
@@ -1,5 +1,5 @@
1
+ import { resolveUnstubbedGuard, createFunctionSpy } from './chunk-4KK3ES4P.js';
1
2
  import { DISPOSE } from './chunk-PC3FAZT3.js';
2
- import { resolveUnstubbedGuard, createFunctionSpy } from './chunk-3QJUFL2N.js';
3
3
  import { runClearHook, runConfigReset, AUTO_SPY_MARK, isMarkedMock, readDeepChildren, markAsMock } from './chunk-XRVVZXOM.js';
4
4
  import { withDocs, DOCS_LINKS } from './chunk-B45HLBA4.js';
5
5
  import { getMockAdapter, requireObservableSupport, getJasmineSupport } from './shared-state.js';
@@ -148,6 +148,17 @@ Actual: ${actualCall(functionName, actualArgs)}`;
148
148
  };
149
149
 
150
150
  // src/lib/args-map.ts
151
+ function isSinglePrimitiveArgs(args) {
152
+ if (args.length !== 1) {
153
+ return false;
154
+ }
155
+ const [argument] = args;
156
+ const kind = typeof argument;
157
+ if (kind === "object" || kind === "function" || kind === "symbol") {
158
+ return argument === null;
159
+ }
160
+ return !Object.is(argument, -0);
161
+ }
151
162
  function isAsymmetricMatcher(value) {
152
163
  return typeof value === "object" && value !== null && "asymmetricMatch" in value && typeof value.asymmetricMatch === "function";
153
164
  }
@@ -182,6 +193,21 @@ var ArgsMap = class {
182
193
  // on a spy configured with `calledWith(1)` walks and stringifies the whole component graph to
183
194
  // build a key that provably cannot match, and throws it away one line later.
184
195
  #arities = /* @__PURE__ */ new Set();
196
+ /**
197
+ * The configs of exactly one primitive argument, keyed by the argument itself.
198
+ *
199
+ * `calledWith(1)` / `calledWith('id')` is what nearly every spec writes, and it is looked up on
200
+ * **every call** of that spy. Through the string map that costs a rendered key per call — an array
201
+ * from `map`, a string per argument, a joined string, then a hash — for a lookup that a `Map` can
202
+ * do on the value with no allocation at all. The configs live in both maps: the string map still
203
+ * owns `configured()` and the arity set, so nothing about the failure messages or the miss check
204
+ * changes.
205
+ *
206
+ * Only shapes where the two agree go in here. A symbol renders by description, so two distinct
207
+ * symbols that share one are the same key in the string map and different keys in a `Map`; `-0`
208
+ * renders apart from `0` and is the same key under `SameValueZero`. Both stay on the string path.
209
+ */
210
+ #exactSinglePrimitive = /* @__PURE__ */ new Map();
185
211
  set(key, value) {
186
212
  if (Array.isArray(key) && hasAsymmetricMatcher(key)) {
187
213
  this.#setMatcherConfig(this.#buildMatcherConfig(key, value));
@@ -189,6 +215,9 @@ var ArgsMap = class {
189
215
  }
190
216
  if (Array.isArray(key)) {
191
217
  this.#arities.add(key.length);
218
+ if (isSinglePrimitiveArgs(key)) {
219
+ this.#exactSinglePrimitive.set(key[0], value);
220
+ }
192
221
  }
193
222
  this.#map[this.#serialize(key)] = value;
194
223
  }
@@ -196,6 +225,10 @@ var ArgsMap = class {
196
225
  if (Array.isArray(key) && !this.#arities.has(key.length)) {
197
226
  return this.#findByMatcher(key);
198
227
  }
228
+ if (Array.isArray(key) && isSinglePrimitiveArgs(key)) {
229
+ const hit = this.#exactSinglePrimitive.get(key[0]);
230
+ return hit === void 0 ? this.#findByMatcher(key) : hit;
231
+ }
199
232
  const serialized = this.#serialize(key);
200
233
  if (serialized in this.#map) {
201
234
  return this.#map[serialized];
@@ -336,18 +369,26 @@ function addPromiseHelpersToCalledWithObject(calledWithObject, calledWithArgs) {
336
369
  );
337
370
  }
338
371
 
339
- // src/lib/settled-results.ts
340
- var NATIVE_RECORDER = {
341
- record: (returned) => returned,
342
- clear: () => void 0
343
- };
372
+ // src/lib/spy-probe.ts
373
+ var FAST_SPY_BRAND = /* @__PURE__ */ Symbol.for("vitest-auto-spy.fastSpy");
374
+ function isFastSpy(value) {
375
+ return typeof value === "function" && FAST_SPY_BRAND in value;
376
+ }
344
377
  function isThenable(value) {
345
378
  if (typeof value !== "object" && typeof value !== "function" || value === null) {
346
379
  return false;
347
380
  }
348
381
  return typeof Reflect.get(value, "then") === "function";
349
382
  }
383
+
384
+ // src/lib/settled-results.ts
385
+ var NATIVE_RECORDER = {
386
+ clear: () => void 0
387
+ };
350
388
  function installSettledResultsPolyfill(mockFn) {
389
+ if (isFastSpy(mockFn)) {
390
+ return NATIVE_RECORDER;
391
+ }
351
392
  const state = Reflect.get(mockFn, "mock");
352
393
  if (typeof state !== "object" || state === null || "settledResults" in state) {
353
394
  return NATIVE_RECORDER;
@@ -544,11 +585,11 @@ function createFunctionSpy(name, unstubbed) {
544
585
  let settledResultsRecorder = void 0;
545
586
  const dispatch = (...actualArgs) => {
546
587
  const returned = returnTheCorrectFakeValue(state, actualArgs, name, unstubbed);
547
- return settledResultsRecorder ? settledResultsRecorder.record(returned) : returned;
588
+ return settledResultsRecorder ? settledResultsRecorder(returned) : returned;
548
589
  };
549
590
  const functionSpy = getMockAdapter().createMockFn(dispatch, name);
550
591
  const recorder = installSettledResultsPolyfill(functionSpy);
551
- settledResultsRecorder = recorder;
592
+ settledResultsRecorder = recorder.record;
552
593
  const internals = new FunctionSpyInternals(state, valueContainer, functionSpy, dispatch, recorder);
553
594
  const spy = decorate(functionSpy, SPY_HELPERS);
554
595
  internals.observable = getObservableSupport()?.addToFunctionSpy(spy, valueContainer);
@@ -565,4 +606,4 @@ function exposeAsSpy(spy) {
565
606
  return spy;
566
607
  }
567
608
 
568
- export { createFunctionSpy, defineHelper, errorHandler, resolveUnstubbedGuard, serializeValue, setDefaultStrictMode };
609
+ export { FAST_SPY_BRAND, createFunctionSpy, defineHelper, errorHandler, isThenable, resolveUnstubbedGuard, serializeValue, setDefaultStrictMode };