@c9up/helix 0.1.3 → 0.1.5

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.
Files changed (235) hide show
  1. package/dist/cli/coverage/aggregate.d.ts +24 -0
  2. package/dist/cli/coverage/aggregate.d.ts.map +1 -0
  3. package/dist/cli/coverage/aggregate.js +215 -0
  4. package/dist/cli/coverage/aggregate.js.map +1 -0
  5. package/dist/cli/coverage/collect.d.ts +13 -0
  6. package/dist/cli/coverage/collect.d.ts.map +1 -0
  7. package/dist/cli/coverage/collect.js +66 -0
  8. package/dist/cli/coverage/collect.js.map +1 -0
  9. package/dist/cli/coverage/diff/base.d.ts +17 -0
  10. package/dist/cli/coverage/diff/base.d.ts.map +1 -0
  11. package/dist/cli/coverage/diff/base.js +44 -0
  12. package/dist/cli/coverage/diff/base.js.map +1 -0
  13. package/dist/cli/coverage/diff/index.d.ts +25 -0
  14. package/dist/cli/coverage/diff/index.d.ts.map +1 -0
  15. package/dist/cli/coverage/diff/index.js +119 -0
  16. package/dist/cli/coverage/diff/index.js.map +1 -0
  17. package/dist/cli/coverage/diff/overlay.d.ts +19 -0
  18. package/dist/cli/coverage/diff/overlay.d.ts.map +1 -0
  19. package/dist/cli/coverage/diff/overlay.js +58 -0
  20. package/dist/cli/coverage/diff/overlay.js.map +1 -0
  21. package/dist/cli/coverage/diff/parse.d.ts +27 -0
  22. package/dist/cli/coverage/diff/parse.d.ts.map +1 -0
  23. package/dist/cli/coverage/diff/parse.js +105 -0
  24. package/dist/cli/coverage/diff/parse.js.map +1 -0
  25. package/dist/cli/coverage/diff/reporters.d.ts +12 -0
  26. package/dist/cli/coverage/diff/reporters.d.ts.map +1 -0
  27. package/dist/cli/coverage/diff/reporters.js +59 -0
  28. package/dist/cli/coverage/diff/reporters.js.map +1 -0
  29. package/dist/cli/coverage/diff/types.d.ts +46 -0
  30. package/dist/cli/coverage/diff/types.d.ts.map +1 -0
  31. package/dist/cli/coverage/diff/types.js +15 -0
  32. package/dist/cli/coverage/diff/types.js.map +1 -0
  33. package/dist/cli/coverage/filter.d.ts +13 -0
  34. package/dist/cli/coverage/filter.d.ts.map +1 -0
  35. package/dist/cli/coverage/filter.js +60 -0
  36. package/dist/cli/coverage/filter.js.map +1 -0
  37. package/dist/cli/coverage/glob.d.ts +4 -0
  38. package/dist/cli/coverage/glob.d.ts.map +1 -0
  39. package/dist/cli/coverage/glob.js +0 -0
  40. package/dist/cli/coverage/glob.js.map +1 -0
  41. package/dist/cli/coverage/index.d.ts +40 -0
  42. package/dist/cli/coverage/index.d.ts.map +1 -0
  43. package/dist/cli/coverage/index.js +85 -0
  44. package/dist/cli/coverage/index.js.map +1 -0
  45. package/dist/cli/coverage/reporters/json.d.ts +13 -0
  46. package/dist/cli/coverage/reporters/json.d.ts.map +1 -0
  47. package/dist/cli/coverage/reporters/json.js +37 -0
  48. package/dist/cli/coverage/reporters/json.js.map +1 -0
  49. package/dist/cli/coverage/reporters/lcov.d.ts +13 -0
  50. package/dist/cli/coverage/reporters/lcov.d.ts.map +1 -0
  51. package/dist/cli/coverage/reporters/lcov.js +51 -0
  52. package/dist/cli/coverage/reporters/lcov.js.map +1 -0
  53. package/dist/cli/coverage/reporters/text.d.ts +8 -0
  54. package/dist/cli/coverage/reporters/text.d.ts.map +1 -0
  55. package/dist/cli/coverage/reporters/text.js +39 -0
  56. package/dist/cli/coverage/reporters/text.js.map +1 -0
  57. package/dist/cli/coverage/thresholds.d.ts +14 -0
  58. package/dist/cli/coverage/thresholds.d.ts.map +1 -0
  59. package/dist/cli/coverage/thresholds.js +58 -0
  60. package/dist/cli/coverage/thresholds.js.map +1 -0
  61. package/dist/cli/coverage/types.d.ts +118 -0
  62. package/dist/cli/coverage/types.d.ts.map +1 -0
  63. package/dist/cli/coverage/types.js +8 -0
  64. package/dist/cli/coverage/types.js.map +1 -0
  65. package/dist/cli/discover.d.ts +27 -0
  66. package/dist/cli/discover.d.ts.map +1 -0
  67. package/dist/cli/discover.js +142 -0
  68. package/dist/cli/discover.js.map +1 -0
  69. package/dist/cli/native.d.ts +43 -0
  70. package/dist/cli/native.d.ts.map +1 -0
  71. package/dist/cli/native.js +64 -0
  72. package/dist/cli/native.js.map +1 -0
  73. package/dist/cli/pool.d.ts +55 -0
  74. package/dist/cli/pool.d.ts.map +1 -0
  75. package/dist/cli/pool.js +404 -0
  76. package/dist/cli/pool.js.map +1 -0
  77. package/dist/cli/reporter.d.ts +51 -0
  78. package/dist/cli/reporter.d.ts.map +1 -0
  79. package/dist/cli/reporter.js +124 -0
  80. package/dist/cli/reporter.js.map +1 -0
  81. package/dist/cli/run.d.ts +61 -0
  82. package/dist/cli/run.d.ts.map +1 -0
  83. package/dist/cli/run.js +302 -0
  84. package/dist/cli/run.js.map +1 -0
  85. package/dist/cli/summary.d.ts +18 -0
  86. package/dist/cli/summary.d.ts.map +1 -0
  87. package/dist/cli/summary.js +20 -0
  88. package/dist/cli/summary.js.map +1 -0
  89. package/dist/cli/watch/loop.d.ts +26 -0
  90. package/dist/cli/watch/loop.d.ts.map +1 -0
  91. package/dist/cli/watch/loop.js +133 -0
  92. package/dist/cli/watch/loop.js.map +1 -0
  93. package/dist/cli/watch/types.d.ts +22 -0
  94. package/dist/cli/watch/types.d.ts.map +1 -0
  95. package/dist/cli/watch/types.js +6 -0
  96. package/dist/cli/watch/types.js.map +1 -0
  97. package/dist/cli/watch/watcher.d.ts +25 -0
  98. package/dist/cli/watch/watcher.d.ts.map +1 -0
  99. package/dist/cli/watch/watcher.js +122 -0
  100. package/dist/cli/watch/watcher.js.map +1 -0
  101. package/dist/container/index.d.ts +7 -0
  102. package/dist/container/index.d.ts.map +1 -0
  103. package/dist/container/index.js +6 -0
  104. package/dist/container/index.js.map +1 -0
  105. package/{src/container/override.ts → dist/container/override.d.ts} +6 -46
  106. package/dist/container/override.d.ts.map +1 -0
  107. package/dist/container/override.js +67 -0
  108. package/dist/container/override.js.map +1 -0
  109. package/{src/container/spy.ts → dist/container/spy.d.ts} +2 -6
  110. package/dist/container/spy.d.ts.map +1 -0
  111. package/dist/container/spy.js +23 -0
  112. package/dist/container/spy.js.map +1 -0
  113. package/dist/index.d.ts +20 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/{src/index.ts → dist/index.js} +2 -25
  116. package/dist/index.js.map +1 -0
  117. package/dist/runtime/assertion-error.d.ts +20 -0
  118. package/dist/runtime/assertion-error.d.ts.map +1 -0
  119. package/dist/runtime/assertion-error.js +23 -0
  120. package/dist/runtime/assertion-error.js.map +1 -0
  121. package/dist/runtime/cli-worker.d.ts +25 -0
  122. package/dist/runtime/cli-worker.d.ts.map +1 -0
  123. package/dist/runtime/cli-worker.js +128 -0
  124. package/dist/runtime/cli-worker.js.map +1 -0
  125. package/dist/runtime/equals.d.ts +25 -0
  126. package/dist/runtime/equals.d.ts.map +1 -0
  127. package/dist/runtime/equals.js +343 -0
  128. package/dist/runtime/equals.js.map +1 -0
  129. package/dist/runtime/expect.d.ts +32 -0
  130. package/dist/runtime/expect.d.ts.map +1 -0
  131. package/dist/runtime/expect.js +121 -0
  132. package/dist/runtime/expect.js.map +1 -0
  133. package/{src/runtime/index.ts → dist/runtime/index.d.ts} +5 -27
  134. package/dist/runtime/index.d.ts.map +1 -0
  135. package/dist/runtime/index.js +17 -0
  136. package/dist/runtime/index.js.map +1 -0
  137. package/{src/runtime/lifecycle.ts → dist/runtime/lifecycle.d.ts} +2 -8
  138. package/dist/runtime/lifecycle.d.ts.map +1 -0
  139. package/dist/runtime/lifecycle.js +10 -0
  140. package/dist/runtime/lifecycle.js.map +1 -0
  141. package/dist/runtime/matchers.d.ts +42 -0
  142. package/dist/runtime/matchers.d.ts.map +1 -0
  143. package/dist/runtime/matchers.js +375 -0
  144. package/dist/runtime/matchers.js.map +1 -0
  145. package/dist/runtime/run.d.ts +55 -0
  146. package/dist/runtime/run.d.ts.map +1 -0
  147. package/dist/runtime/run.js +456 -0
  148. package/dist/runtime/run.js.map +1 -0
  149. package/dist/runtime/suite.d.ts +91 -0
  150. package/dist/runtime/suite.d.ts.map +1 -0
  151. package/dist/runtime/suite.js +206 -0
  152. package/dist/runtime/suite.js.map +1 -0
  153. package/dist/runtime/test-context.d.ts +25 -0
  154. package/dist/runtime/test-context.d.ts.map +1 -0
  155. package/dist/runtime/test-context.js +52 -0
  156. package/dist/runtime/test-context.js.map +1 -0
  157. package/dist/runtime/vi/fake-timers.d.ts +48 -0
  158. package/dist/runtime/vi/fake-timers.d.ts.map +1 -0
  159. package/dist/runtime/vi/fake-timers.js +317 -0
  160. package/dist/runtime/vi/fake-timers.js.map +1 -0
  161. package/dist/runtime/vi/index.d.ts +70 -0
  162. package/dist/runtime/vi/index.d.ts.map +1 -0
  163. package/dist/runtime/vi/index.js +209 -0
  164. package/dist/runtime/vi/index.js.map +1 -0
  165. package/dist/runtime/vi/spy.d.ts +54 -0
  166. package/dist/runtime/vi/spy.d.ts.map +1 -0
  167. package/dist/runtime/vi/spy.js +159 -0
  168. package/dist/runtime/vi/spy.js.map +1 -0
  169. package/dist/runtime/vi/spyOn.d.ts +28 -0
  170. package/dist/runtime/vi/spyOn.d.ts.map +1 -0
  171. package/dist/runtime/vi/spyOn.js +121 -0
  172. package/dist/runtime/vi/spyOn.js.map +1 -0
  173. package/dist/runtime/vi/system-time.d.ts +30 -0
  174. package/dist/runtime/vi/system-time.d.ts.map +1 -0
  175. package/dist/runtime/vi/system-time.js +100 -0
  176. package/dist/runtime/vi/system-time.js.map +1 -0
  177. package/dist/runtime/worker.d.ts +26 -0
  178. package/dist/runtime/worker.d.ts.map +1 -0
  179. package/dist/runtime/worker.js +195 -0
  180. package/dist/runtime/worker.js.map +1 -0
  181. package/dist/time/freeze.d.ts +80 -0
  182. package/dist/time/freeze.d.ts.map +1 -0
  183. package/dist/time/freeze.js +184 -0
  184. package/dist/time/freeze.js.map +1 -0
  185. package/{src/time/index.ts → dist/time/index.d.ts} +1 -1
  186. package/dist/time/index.d.ts.map +1 -0
  187. package/dist/time/index.js +15 -0
  188. package/dist/time/index.js.map +1 -0
  189. package/index.darwin-arm64.node +0 -0
  190. package/index.darwin-x64.node +0 -0
  191. package/index.linux-arm64-gnu.node +0 -0
  192. package/index.linux-x64-gnu.node +0 -0
  193. package/index.win32-x64-msvc.node +0 -0
  194. package/package.json +2 -2
  195. package/src/cli/coverage/aggregate.ts +0 -231
  196. package/src/cli/coverage/collect.ts +0 -63
  197. package/src/cli/coverage/diff/base.ts +0 -46
  198. package/src/cli/coverage/diff/index.ts +0 -160
  199. package/src/cli/coverage/diff/overlay.ts +0 -62
  200. package/src/cli/coverage/diff/parse.ts +0 -121
  201. package/src/cli/coverage/diff/reporters.ts +0 -82
  202. package/src/cli/coverage/diff/types.ts +0 -46
  203. package/src/cli/coverage/filter.ts +0 -71
  204. package/src/cli/coverage/glob.ts +0 -0
  205. package/src/cli/coverage/index.ts +0 -126
  206. package/src/cli/coverage/reporters/json.ts +0 -40
  207. package/src/cli/coverage/reporters/lcov.ts +0 -54
  208. package/src/cli/coverage/reporters/text.ts +0 -48
  209. package/src/cli/coverage/thresholds.ts +0 -73
  210. package/src/cli/coverage/types.ts +0 -93
  211. package/src/cli/discover.ts +0 -174
  212. package/src/cli/native.ts +0 -104
  213. package/src/cli/pool.ts +0 -486
  214. package/src/cli/reporter.ts +0 -155
  215. package/src/cli/run.ts +0 -440
  216. package/src/cli/summary.ts +0 -42
  217. package/src/cli/watch/loop.ts +0 -159
  218. package/src/cli/watch/types.ts +0 -22
  219. package/src/cli/watch/watcher.ts +0 -145
  220. package/src/container/index.ts +0 -16
  221. package/src/runtime/assertion-error.ts +0 -38
  222. package/src/runtime/cli-worker.ts +0 -140
  223. package/src/runtime/equals.ts +0 -400
  224. package/src/runtime/expect.ts +0 -173
  225. package/src/runtime/matchers.ts +0 -452
  226. package/src/runtime/run.ts +0 -573
  227. package/src/runtime/suite.ts +0 -310
  228. package/src/runtime/test-context.ts +0 -59
  229. package/src/runtime/vi/fake-timers.ts +0 -410
  230. package/src/runtime/vi/index.ts +0 -254
  231. package/src/runtime/vi/spy.ts +0 -224
  232. package/src/runtime/vi/spyOn.ts +0 -155
  233. package/src/runtime/vi/system-time.ts +0 -121
  234. package/src/runtime/worker.ts +0 -239
  235. package/src/time/freeze.ts +0 -229
@@ -1,400 +0,0 @@
1
- /**
2
- * Deep structural equality — Vitest-compatible semantics.
3
- *
4
- * Handles: primitives (Object.is for NaN; ±0 treated equal in non-strict toEqual),
5
- * Date, RegExp, Map, Set, Array, Buffer, typed arrays, DataView, boxed primitives
6
- * (Number/String/Boolean), Error instances, circular refs, Symbol-keyed props.
7
- * Ignores prototypes for plain objects (matches Jest/Vitest `toEqual`).
8
- *
9
- * `toStrictEqual` semantics (checks prototype + undefined-vs-missing keys)
10
- * are supported via the `strict` option.
11
- */
12
-
13
- export interface EqualsOptions {
14
- /** `toStrictEqual` semantics — prototypes matched, undefined keys distinguished from missing. */
15
- strict?: boolean;
16
- }
17
-
18
- type Seen = WeakMap<object, WeakSet<object>>;
19
-
20
- export function equals(
21
- a: unknown,
22
- b: unknown,
23
- options: EqualsOptions = {},
24
- ): boolean {
25
- return eq(a, b, options, new WeakMap());
26
- }
27
-
28
- /**
29
- * Record a pair as "in progress" in BOTH directions so a later visit to the
30
- * mirrored pair (b,a) is detected as a cycle too.
31
- */
32
- function markSeen(seen: Seen, a: object, b: object): void {
33
- let setA = seen.get(a);
34
- if (!setA) {
35
- setA = new WeakSet();
36
- seen.set(a, setA);
37
- }
38
- setA.add(b);
39
- let setB = seen.get(b);
40
- if (!setB) {
41
- setB = new WeakSet();
42
- seen.set(b, setB);
43
- }
44
- setB.add(a);
45
- }
46
-
47
- function seenPair(seen: Seen, a: object, b: object): boolean {
48
- return seen.get(a)?.has(b) ?? false;
49
- }
50
-
51
- /**
52
- * A structural comparator for one object "kind". Returns `true`/`false` when it
53
- * recognises the pair as its kind (and decides equality), or `undefined` to
54
- * mean "not my kind — let the next comparator try". This keeps `eq` a flat
55
- * dispatch loop instead of a 150-line `instanceof` ladder.
56
- */
57
- type Comparator = (
58
- a: object,
59
- b: object,
60
- opts: EqualsOptions,
61
- seen: Seen,
62
- ) => boolean | undefined;
63
-
64
- function isBoxedPrimitive(v: object): boolean {
65
- return v instanceof Number || v instanceof String || v instanceof Boolean;
66
- }
67
-
68
- // Boxed primitives — unwrap so `new Number(1)` vs `new Number(2)` differ
69
- // properly; a box compared against anything not the same box type is unequal.
70
- function compareBoxed(a: object, b: object): boolean | undefined {
71
- if (a instanceof Number && b instanceof Number)
72
- return Object.is(a.valueOf(), b.valueOf());
73
- if (a instanceof String && b instanceof String)
74
- return Object.is(a.valueOf(), b.valueOf());
75
- if (a instanceof Boolean && b instanceof Boolean)
76
- return Object.is(a.valueOf(), b.valueOf());
77
- if (isBoxedPrimitive(a) || isBoxedPrimitive(b)) return false;
78
- return undefined;
79
- }
80
-
81
- function compareDate(a: object, b: object): boolean | undefined {
82
- if (!(a instanceof Date) && !(b instanceof Date)) return undefined;
83
- return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
84
- }
85
-
86
- function compareRegExp(a: object, b: object): boolean | undefined {
87
- if (!(a instanceof RegExp) && !(b instanceof RegExp)) return undefined;
88
- return (
89
- a instanceof RegExp &&
90
- b instanceof RegExp &&
91
- a.source === b.source &&
92
- a.flags === b.flags
93
- );
94
- }
95
-
96
- // Error instances — compare name + message + own enumerable keys. The built-in
97
- // fields are non-enumerable so plain-keys comparison alone would report any two
98
- // Errors as equal.
99
- function compareError(
100
- a: object,
101
- b: object,
102
- opts: EqualsOptions,
103
- seen: Seen,
104
- ): boolean | undefined {
105
- if (!(a instanceof Error) && !(b instanceof Error)) return undefined;
106
- if (!(a instanceof Error && b instanceof Error)) return false;
107
- if (a.name !== b.name) return false;
108
- if (a.message !== b.message) return false;
109
- return compareOwnKeys(a, b, opts, seen);
110
- }
111
-
112
- // DataView — compare by byteLength + getUint8 byte-for-byte.
113
- function compareDataView(a: object, b: object): boolean | undefined {
114
- if (!(a instanceof DataView) && !(b instanceof DataView)) return undefined;
115
- if (!(a instanceof DataView && b instanceof DataView)) return false;
116
- if (a.byteLength !== b.byteLength) return false;
117
- for (let i = 0; i < a.byteLength; i += 1) {
118
- if (a.getUint8(i) !== b.getUint8(i)) return false;
119
- }
120
- return true;
121
- }
122
-
123
- // Buffer — shortcut via Buffer.equals when both are Buffers. When only one is a
124
- // Buffer, return `undefined` so the typed-array comparator handles it (a Buffer
125
- // is a Uint8Array): a constructor mismatch there yields the correct inequality.
126
- function compareBuffer(a: object, b: object): boolean | undefined {
127
- if (typeof Buffer === "undefined") return undefined;
128
- if (Buffer.isBuffer(a) && Buffer.isBuffer(b)) return a.equals(b);
129
- return undefined;
130
- }
131
-
132
- // Typed arrays (Uint8Array, Int16Array, Float64Array, BigInt64Array, …).
133
- // Require matching constructor so Uint8Array !== Int8Array even when values coincide.
134
- function compareTypedArray(
135
- a: object,
136
- b: object,
137
- opts: EqualsOptions,
138
- ): boolean | undefined {
139
- const viewA = asNumericTypedArray(a);
140
- const viewB = asNumericTypedArray(b);
141
- if (!viewA && !viewB) return undefined;
142
- if (!viewA || !viewB) return false;
143
- if (a.constructor !== b.constructor) return false;
144
- if (viewA.length !== viewB.length) return false;
145
- for (let i = 0; i < viewA.length; i += 1) {
146
- const av = viewA[i];
147
- const bv = viewB[i];
148
- // Object.is so NaN === NaN inside Float32/64Array.
149
- if (Object.is(av, bv)) continue;
150
- if (opts.strict) return false;
151
- if (av !== bv) return false; // non-strict: ±0 already caught by `===`.
152
- }
153
- return true;
154
- }
155
-
156
- function compareArray(
157
- a: object,
158
- b: object,
159
- opts: EqualsOptions,
160
- seen: Seen,
161
- ): boolean | undefined {
162
- if (!Array.isArray(a) && !Array.isArray(b)) return undefined;
163
- if (!(Array.isArray(a) && Array.isArray(b))) return false;
164
- if (a.length !== b.length) return false;
165
- for (let i = 0; i < a.length; i += 1) {
166
- if (!eq(a[i], b[i], opts, seen)) return false;
167
- }
168
- return true;
169
- }
170
-
171
- // Maps — structural key comparison supporting object keys.
172
- function compareMap(
173
- a: object,
174
- b: object,
175
- opts: EqualsOptions,
176
- seen: Seen,
177
- ): boolean | undefined {
178
- if (!(a instanceof Map) && !(b instanceof Map)) return undefined;
179
- if (!(a instanceof Map && b instanceof Map)) return false;
180
- if (a.size !== b.size) return false;
181
- for (const [kA, vA] of a) {
182
- // Fast path: identity/primitive key hit.
183
- if (b.has(kA) && eq(vA, b.get(kA), opts, seen)) continue;
184
- // Structural search across remaining entries.
185
- let matched = false;
186
- for (const [kB, vB] of b) {
187
- if (eq(kA, kB, opts, seen) && eq(vA, vB, opts, seen)) {
188
- matched = true;
189
- break;
190
- }
191
- }
192
- if (!matched) return false;
193
- }
194
- return true;
195
- }
196
-
197
- // Sets — deep structural. Use a fresh WeakMap per inner comparison so an
198
- // earlier failed candidate does not poison the next one via cycle cache.
199
- function compareSet(
200
- a: object,
201
- b: object,
202
- opts: EqualsOptions,
203
- ): boolean | undefined {
204
- if (!(a instanceof Set) && !(b instanceof Set)) return undefined;
205
- if (!(a instanceof Set && b instanceof Set)) return false;
206
- if (a.size !== b.size) return false;
207
- for (const v of a) {
208
- let found = false;
209
- for (const w of b) {
210
- if (eq(v, w, opts, new WeakMap())) {
211
- found = true;
212
- break;
213
- }
214
- }
215
- if (!found) return false;
216
- }
217
- return true;
218
- }
219
-
220
- // Order matters — mirrors the original `instanceof` ladder. Buffer sits before
221
- // typed arrays so the both-Buffer fast path wins before the generic view check.
222
- const STRUCTURAL_COMPARATORS: readonly Comparator[] = [
223
- compareDate,
224
- compareRegExp,
225
- compareError,
226
- compareDataView,
227
- compareBuffer,
228
- compareTypedArray,
229
- compareArray,
230
- compareMap,
231
- compareSet,
232
- ];
233
-
234
- function eq(a: unknown, b: unknown, opts: EqualsOptions, seen: Seen): boolean {
235
- // Identity / NaN (Object.is). In non-strict mode, ±0 are also equal.
236
- if (Object.is(a, b)) return true;
237
- if (!opts.strict && a === b) return true;
238
- if (a === null || b === null) return false;
239
- if (typeof a !== typeof b) return false;
240
- if (typeof a !== "object") return false;
241
-
242
- const objA = a as object;
243
- const objB = b as object;
244
-
245
- if (seenPair(seen, objA, objB)) return true;
246
- markSeen(seen, objA, objB);
247
-
248
- const boxed = compareBoxed(objA, objB);
249
- if (boxed !== undefined) return boxed;
250
-
251
- // Strict: differing prototypes → not equal (plain `{}` vs class instance).
252
- if (
253
- opts.strict &&
254
- Object.getPrototypeOf(objA) !== Object.getPrototypeOf(objB)
255
- ) {
256
- return false;
257
- }
258
-
259
- for (const compare of STRUCTURAL_COMPARATORS) {
260
- const result = compare(objA, objB, opts, seen);
261
- if (result !== undefined) return result;
262
- }
263
-
264
- return compareOwnKeys(objA, objB, opts, seen);
265
- }
266
-
267
- function getProp(obj: object, key: PropertyKey): unknown {
268
- return Reflect.get(obj, key);
269
- }
270
-
271
- type NumericTypedArray =
272
- | Int8Array
273
- | Uint8Array
274
- | Uint8ClampedArray
275
- | Int16Array
276
- | Uint16Array
277
- | Int32Array
278
- | Uint32Array
279
- | Float32Array
280
- | Float64Array
281
- | BigInt64Array
282
- | BigUint64Array;
283
-
284
- function asNumericTypedArray(v: object): NumericTypedArray | undefined {
285
- if (
286
- v instanceof Int8Array ||
287
- v instanceof Uint8Array ||
288
- v instanceof Uint8ClampedArray ||
289
- v instanceof Int16Array ||
290
- v instanceof Uint16Array ||
291
- v instanceof Int32Array ||
292
- v instanceof Uint32Array ||
293
- v instanceof Float32Array ||
294
- v instanceof Float64Array ||
295
- v instanceof BigInt64Array ||
296
- v instanceof BigUint64Array
297
- ) {
298
- return v;
299
- }
300
- return undefined;
301
- }
302
-
303
- function compareOwnKeys(
304
- objA: object,
305
- objB: object,
306
- opts: EqualsOptions,
307
- seen: Seen,
308
- ): boolean {
309
- const keysA = ownEnumerableKeys(objA);
310
- const keysB = ownEnumerableKeys(objB);
311
-
312
- if (opts.strict) {
313
- if (keysA.length !== keysB.length) return false;
314
- for (const k of keysA) {
315
- if (!Object.prototype.propertyIsEnumerable.call(objB, k)) return false;
316
- if (!eq(getProp(objA, k), getProp(objB, k), opts, seen)) return false;
317
- }
318
- return true;
319
- }
320
-
321
- // Non-strict: undefined value ≡ missing key.
322
- const union = new Set<string | symbol>([...keysA, ...keysB]);
323
- for (const k of union) {
324
- const va = getProp(objA, k);
325
- const vb = getProp(objB, k);
326
- if (va === undefined && vb === undefined) continue;
327
- if (!eq(va, vb, opts, seen)) return false;
328
- }
329
- return true;
330
- }
331
-
332
- function ownEnumerableKeys(obj: object): Array<string | symbol> {
333
- const strings = Object.keys(obj);
334
- const symbols = Object.getOwnPropertySymbols(obj).filter((s) =>
335
- Object.prototype.propertyIsEnumerable.call(obj, s),
336
- );
337
- return [...strings, ...symbols];
338
- }
339
-
340
- /**
341
- * Partial match — every key/element in `expected` must match in `actual`.
342
- * Extra keys in `actual` are allowed for plain objects.
343
- * Arrays must have the same length (Vitest v1+ semantics, not Jest).
344
- * Date / RegExp / Error / Map / Set / TypedArray / Buffer / DataView delegate
345
- * to `equals` — "partial" is ill-defined for them.
346
- */
347
- export function partialEquals(actual: unknown, expected: unknown): boolean {
348
- return partial(actual, expected, new WeakMap());
349
- }
350
-
351
- function partial(actual: unknown, expected: unknown, seen: Seen): boolean {
352
- if (Object.is(actual, expected)) return true;
353
- if (expected === null || expected === undefined) {
354
- return actual === expected;
355
- }
356
- if (typeof expected !== "object") {
357
- return equals(actual, expected);
358
- }
359
- if (typeof actual !== "object" || actual === null) return false;
360
-
361
- // Both narrowed to object by the guards above — no cast needed.
362
- const objE: object = expected;
363
- const objA: object = actual;
364
-
365
- if (seenPair(seen, objA, objE)) return true;
366
- markSeen(seen, objA, objE);
367
-
368
- // Types with no "partial" semantics — fall through to full equality.
369
- if (lacksPartialSemantics(objE)) {
370
- return equals(actual, expected);
371
- }
372
-
373
- if (Array.isArray(expected)) {
374
- if (!Array.isArray(actual)) return false;
375
- if (actual.length !== expected.length) return false;
376
- for (let i = 0; i < expected.length; i += 1) {
377
- if (!partial(actual[i], expected[i], seen)) return false;
378
- }
379
- return true;
380
- }
381
-
382
- for (const key of ownEnumerableKeys(objE)) {
383
- if (!partial(getProp(objA, key), getProp(objE, key), seen)) return false;
384
- }
385
- return true;
386
- }
387
-
388
- /** Object kinds for which "partial" is ill-defined → fall back to full equals. */
389
- function lacksPartialSemantics(value: object): boolean {
390
- return (
391
- value instanceof Date ||
392
- value instanceof RegExp ||
393
- value instanceof Error ||
394
- value instanceof Map ||
395
- value instanceof Set ||
396
- value instanceof DataView ||
397
- (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) ||
398
- (ArrayBuffer.isView(value) && !(value instanceof DataView))
399
- );
400
- }
@@ -1,173 +0,0 @@
1
- /**
2
- * `expect(value)` engine — chainable assertion API compatible with Vitest.
3
- *
4
- * Supports:
5
- * - All matchers in `./matchers.ts`
6
- * - `.not.<matcher>()` — inverts pass/fail
7
- * - `.resolves.<matcher>()` / `.rejects.<matcher>()` — async awaits on received
8
- * - All four combinations: `.resolves.not`, `.rejects.not`, `.not.resolves`, `.not.rejects`
9
- */
10
-
11
- import { AssertionError } from "./assertion-error.js";
12
- import { type MatcherName, matchers } from "./matchers.js";
13
-
14
- type MatcherArgs<Name extends MatcherName> = (typeof matchers)[Name] extends (
15
- received: unknown,
16
- ...args: infer A
17
- ) => unknown
18
- ? A
19
- : never;
20
-
21
- type SyncChain = {
22
- [K in MatcherName]: (...args: MatcherArgs<K>) => void;
23
- };
24
-
25
- type AsyncChain = {
26
- [K in MatcherName]: (...args: MatcherArgs<K>) => Promise<void>;
27
- };
28
-
29
- export type Assertion = SyncChain & {
30
- not: SyncChain & {
31
- resolves: AsyncChain;
32
- rejects: AsyncChain;
33
- };
34
- resolves: AsyncChain & { not: AsyncChain };
35
- rejects: AsyncChain & { not: AsyncChain };
36
- };
37
-
38
- interface EvalContext {
39
- received: unknown;
40
- negate: boolean;
41
- }
42
-
43
- type MatcherInvoker = (
44
- received: unknown,
45
- ...rest: unknown[]
46
- ) => {
47
- pass: boolean;
48
- message(): string;
49
- };
50
-
51
- function evaluate(ctx: EvalContext, name: MatcherName, args: unknown[]): void {
52
- const matcher = matchers[name] as MatcherInvoker;
53
- let result: { pass: boolean; message(): string };
54
- try {
55
- result = matcher(ctx.received, ...args);
56
- } catch (err) {
57
- // A matcher threw unexpectedly (e.g. a user-supplied constructor with
58
- // a throwing `Symbol.hasInstance`). Surface it as a normal assertion
59
- // failure so reporters can render it uniformly.
60
- const why = err instanceof Error ? err.message : String(err);
61
- throw new AssertionError({
62
- message: `matcher ${name} threw: ${why}`,
63
- actual: ctx.received,
64
- expected: args.length === 1 ? args[0] : args,
65
- operator: ctx.negate ? `not.${name}` : name,
66
- });
67
- }
68
- const pass = ctx.negate ? !result.pass : result.pass;
69
- if (pass) return;
70
- const prefix = ctx.negate ? "expected NOT: " : "";
71
- throw new AssertionError({
72
- message: `${prefix}${result.message()}`,
73
- actual: ctx.received,
74
- expected: args,
75
- operator: ctx.negate ? `not.${name}` : name,
76
- });
77
- }
78
-
79
- const matcherNames = Object.keys(matchers) as MatcherName[];
80
-
81
- function buildSync(received: unknown, negate: boolean): SyncChain {
82
- const api = {} as SyncChain;
83
- for (const name of matcherNames) {
84
- const fn = (...args: unknown[]) =>
85
- evaluate({ received, negate }, name, args);
86
- Reflect.set(api, name, fn);
87
- }
88
- return api;
89
- }
90
-
91
- type PromiseMode = "resolves" | "rejects";
92
-
93
- function buildAsync(
94
- received: unknown,
95
- mode: PromiseMode,
96
- negate: boolean,
97
- ): AsyncChain {
98
- const api = {} as AsyncChain;
99
- for (const name of matcherNames) {
100
- const fn = async (...args: unknown[]) => {
101
- if (
102
- !received ||
103
- typeof (received as { then?: unknown }).then !== "function"
104
- ) {
105
- throw new AssertionError({
106
- message: `expected a Promise (for .${mode}), got ${typeof received}`,
107
- operator: `${mode}.${name}`,
108
- });
109
- }
110
- let resolved: unknown;
111
- let rejected: unknown;
112
- let didReject = false;
113
- try {
114
- resolved = await (received as PromiseLike<unknown>);
115
- } catch (err) {
116
- rejected = err;
117
- didReject = true;
118
- }
119
- if (mode === "resolves") {
120
- if (didReject) {
121
- throw new AssertionError({
122
- message: `expected promise to resolve, but it rejected with ${String(rejected)}`,
123
- operator: `resolves.${name}`,
124
- });
125
- }
126
- evaluate({ received: resolved, negate }, name, args);
127
- return;
128
- }
129
- if (!didReject) {
130
- throw new AssertionError({
131
- message: `expected promise to reject, but it resolved with ${String(resolved)}`,
132
- operator: `rejects.${name}`,
133
- });
134
- }
135
- // `.rejects.toThrow(...)` feeds the rejection into toThrow's
136
- // function-scoped contract by wrapping it in a rethrowing thunk.
137
- const target =
138
- name === "toThrow"
139
- ? () => {
140
- throw rejected;
141
- }
142
- : rejected;
143
- evaluate({ received: target, negate }, name, args);
144
- };
145
- Reflect.set(api, name, fn);
146
- }
147
- return api;
148
- }
149
-
150
- export function expect(received: unknown): Assertion {
151
- const base = buildSync(received, false);
152
-
153
- // `.not` returns a chain that negates every matcher. It also exposes
154
- // `.resolves` / `.rejects` so `expect(p).not.resolves.toBe(x)` works, matching
155
- // Vitest's full surface.
156
- const notSync = Object.assign(buildSync(received, true), {
157
- resolves: buildAsync(received, "resolves", true),
158
- rejects: buildAsync(received, "rejects", true),
159
- });
160
-
161
- const resolves = Object.assign(buildAsync(received, "resolves", false), {
162
- not: buildAsync(received, "resolves", true),
163
- });
164
- const rejects = Object.assign(buildAsync(received, "rejects", false), {
165
- not: buildAsync(received, "rejects", true),
166
- });
167
-
168
- return Object.assign(base, {
169
- not: notSync,
170
- resolves,
171
- rejects,
172
- });
173
- }