@plugjs/expect5 0.4.4 → 0.4.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 (90) hide show
  1. package/dist/cli.mjs +2 -2
  2. package/dist/cli.mjs.map +1 -1
  3. package/dist/execution/executor.cjs.map +1 -1
  4. package/dist/execution/executor.d.ts +1 -1
  5. package/dist/execution/executor.mjs +1 -1
  6. package/dist/execution/executor.mjs.map +1 -1
  7. package/dist/execution/setup.cjs.map +1 -1
  8. package/dist/execution/setup.d.ts +1 -1
  9. package/dist/execution/setup.mjs +1 -1
  10. package/dist/execution/setup.mjs.map +1 -1
  11. package/dist/expectation/async.cjs +58 -45
  12. package/dist/expectation/async.cjs.map +1 -1
  13. package/dist/expectation/async.d.ts +53 -52
  14. package/dist/expectation/async.mjs +59 -42
  15. package/dist/expectation/async.mjs.map +1 -1
  16. package/dist/expectation/diff.cjs.map +1 -1
  17. package/dist/expectation/diff.mjs +6 -1
  18. package/dist/expectation/diff.mjs.map +1 -1
  19. package/dist/expectation/expect.cjs +11 -165
  20. package/dist/expectation/expect.cjs.map +2 -2
  21. package/dist/expectation/expect.d.ts +10 -112
  22. package/dist/expectation/expect.mjs +12 -207
  23. package/dist/expectation/expect.mjs.map +2 -2
  24. package/dist/expectation/expectations.cjs +549 -0
  25. package/dist/expectation/expectations.cjs.map +6 -0
  26. package/dist/expectation/expectations.d.ts +454 -0
  27. package/dist/expectation/expectations.mjs +530 -0
  28. package/dist/expectation/expectations.mjs.map +6 -0
  29. package/dist/expectation/include.cjs +43 -41
  30. package/dist/expectation/include.cjs.map +1 -1
  31. package/dist/expectation/include.d.ts +3 -19
  32. package/dist/expectation/include.mjs +43 -41
  33. package/dist/expectation/include.mjs.map +1 -1
  34. package/dist/expectation/matchers.cjs +350 -0
  35. package/dist/expectation/matchers.cjs.map +6 -0
  36. package/dist/expectation/matchers.d.ts +375 -0
  37. package/dist/expectation/matchers.mjs +328 -0
  38. package/dist/expectation/matchers.mjs.map +6 -0
  39. package/dist/expectation/print.cjs.map +1 -1
  40. package/dist/expectation/print.d.ts +2 -2
  41. package/dist/expectation/print.mjs.map +1 -1
  42. package/dist/expectation/types.cjs +17 -23
  43. package/dist/expectation/types.cjs.map +1 -1
  44. package/dist/expectation/types.d.ts +7 -51
  45. package/dist/expectation/types.mjs +17 -22
  46. package/dist/expectation/types.mjs.map +1 -1
  47. package/dist/globals.d.ts +2 -2
  48. package/dist/index.cjs +5 -5
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.ts +3 -4
  51. package/dist/index.mjs +11 -12
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/test.cjs +34 -5
  54. package/dist/test.cjs.map +1 -1
  55. package/dist/test.d.ts +2 -2
  56. package/dist/test.mjs +35 -6
  57. package/dist/test.mjs.map +1 -1
  58. package/package.json +2 -2
  59. package/src/cli.mts +1 -1
  60. package/src/execution/executor.ts +1 -3
  61. package/src/execution/setup.ts +1 -3
  62. package/src/expectation/async.ts +116 -145
  63. package/src/expectation/diff.ts +7 -3
  64. package/src/expectation/expect.ts +22 -362
  65. package/src/expectation/expectations.ts +971 -0
  66. package/src/expectation/include.ts +59 -75
  67. package/src/expectation/matchers.ts +698 -0
  68. package/src/expectation/print.ts +8 -4
  69. package/src/expectation/types.ts +22 -94
  70. package/src/globals.ts +2 -2
  71. package/src/index.ts +17 -10
  72. package/src/test.ts +34 -10
  73. package/dist/expectation/basic.cjs +0 -188
  74. package/dist/expectation/basic.cjs.map +0 -6
  75. package/dist/expectation/basic.d.ts +0 -90
  76. package/dist/expectation/basic.mjs +0 -156
  77. package/dist/expectation/basic.mjs.map +0 -6
  78. package/dist/expectation/throwing.cjs +0 -58
  79. package/dist/expectation/throwing.cjs.map +0 -6
  80. package/dist/expectation/throwing.d.ts +0 -36
  81. package/dist/expectation/throwing.mjs +0 -32
  82. package/dist/expectation/throwing.mjs.map +0 -6
  83. package/dist/expectation/trivial.cjs +0 -96
  84. package/dist/expectation/trivial.cjs.map +0 -6
  85. package/dist/expectation/trivial.d.ts +0 -13
  86. package/dist/expectation/trivial.mjs +0 -61
  87. package/dist/expectation/trivial.mjs.map +0 -6
  88. package/src/expectation/basic.ts +0 -413
  89. package/src/expectation/throwing.ts +0 -106
  90. package/src/expectation/trivial.ts +0 -107
@@ -1,372 +1,32 @@
1
- import {
2
- toBeRejected,
3
- toBeRejectedWithError,
4
- toBeResolved,
5
- } from './async'
6
- import {
7
- toBeA,
8
- toBeCloseTo,
9
- toBeError,
10
- toBeGreaterThan,
11
- toBeGreaterThanOrEqual,
12
- toBeInstanceOf,
13
- toBeLessThan,
14
- toBeLessThanOrEqual,
15
- toBeWithinRange,
16
- toEqual,
17
- toHaveLength,
18
- toHaveProperty,
19
- toHaveSize,
20
- toMatch,
21
- toStrictlyEqual,
22
- } from './basic'
23
- import {
24
- toInclude,
25
- toMatchContents,
26
- } from './include'
27
- import {
28
- toThrow,
29
- toThrowError,
30
- } from './throwing'
31
- import {
32
- toBeDefined,
33
- toBeFalse,
34
- toBeFalsy,
35
- toBeNaN,
36
- toBeNegativeInfinity,
37
- toBeNull,
38
- toBeNullable,
39
- toBePositiveInfinity,
40
- toBeTrue,
41
- toBeTruthy,
42
- toBeUndefined,
43
- } from './trivial'
44
- import {
45
- ExpectationError,
46
- matcherMarker,
47
- } from './types'
1
+ import { AsyncExpectations } from './async'
2
+ import { Matchers } from './matchers'
48
3
 
49
- import type {
50
- ExpectationsContext,
51
- ExpectationsParent,
52
- } from './types'
53
-
54
- /* ========================================================================== *
55
- * IMPORT AND PREPARE EXTERNAL EXPECTATIONS *
56
- * ========================================================================== */
57
-
58
- const asyncExpectations = {
59
- toBeResolved,
60
- toBeRejected,
61
- toBeRejectedWithError,
62
- } as const
63
-
64
- type AsyncExpectations = typeof asyncExpectations
65
-
66
- const syncExpectations = {
67
- // basic
68
- toBeA,
69
- toBeCloseTo,
70
- toBeError,
71
- toBeGreaterThan,
72
- toBeGreaterThanOrEqual,
73
- toBeInstanceOf,
74
- toBeLessThan,
75
- toBeLessThanOrEqual,
76
- toBeWithinRange,
77
- toEqual,
78
- toHaveLength,
79
- toHaveProperty,
80
- toHaveSize,
81
- toMatch,
82
- toStrictlyEqual,
83
-
84
- // include
85
- toInclude,
86
- toMatchContents,
87
-
88
- // throwing
89
- toThrow,
90
- toThrowError,
91
-
92
- // trivial
93
- toBeDefined,
94
- toBeFalse,
95
- toBeFalsy,
96
- toBeNaN,
97
- toBeNegativeInfinity,
98
- toBeNull,
99
- toBeNullable,
100
- toBePositiveInfinity,
101
- toBeTrue,
102
- toBeTruthy,
103
- toBeUndefined,
104
- } as const
105
-
106
- type SyncExpectations = typeof syncExpectations
107
-
108
- const allExpectations = {
109
- ...asyncExpectations,
110
- ...syncExpectations,
111
- }
112
-
113
- type AllExpectations = SyncExpectations & AsyncExpectations
114
-
115
- /* ========================================================================== *
116
- * OVERLOADED FUNCTIONS TYPES *
117
- * ========================================================================== */
118
-
119
- /** Combine the arguments of a number of overloads (tuples) */
120
- type OverloadArguments<T> =
121
- T extends readonly [ infer T, ...infer Rest ] ?
122
- [ T, ...OverloadArguments<Rest> ] :
123
- T extends readonly [] ? [] :
124
- T extends readonly (infer T)[] ?
125
- unknown extends T ? never :
126
- T extends undefined ? [] :
127
- [ T ] :
128
- never
129
-
130
- /**
131
- * Remap `Functions` (a record of functions) inferring arguments and forcing
132
- * return type to `Result`
133
- */
134
- type OverloadFunctions<Functions, Result> = {
135
- [ k in keyof Functions ]:
136
- Functions[k] extends {
137
- (...args: infer A0): any
138
- (...args: infer A1): any
139
- (...args: infer A2): any
140
- (...args: infer A3): any
141
- (...args: infer A4): any
142
- (...args: infer A5): any
143
- } ? (...args: OverloadArguments<A0 | A1 | A2 | A3 | A4 | A5>) => Result :
144
- Functions[k] extends {
145
- (...args: infer A0): any
146
- (...args: infer A1): any
147
- (...args: infer A2): any
148
- (...args: infer A3): any
149
- (...args: infer A4): any
150
- } ? (...args: OverloadArguments<A0 | A1 | A2 | A3 | A4>) => Result :
151
- Functions[k] extends {
152
- (...args: infer A0): any
153
- (...args: infer A1): any
154
- (...args: infer A2): any
155
- (...args: infer A3): any
156
- } ? (...args: OverloadArguments<A0 | A1 | A2 | A3>) => Result :
157
- Functions[k] extends {
158
- (...args: infer A0): any
159
- (...args: infer A1): any
160
- (...args: infer A2): any
161
- } ? (...args: OverloadArguments<A0 | A1 | A2>) => Result :
162
- Functions[k] extends {
163
- (...args: infer A0): any
164
- (...args: infer A1): any
165
- } ? (...args: OverloadArguments<A0 | A1>) => Result :
166
- Functions[k] extends {
167
- (...args: infer A0): any
168
- } ? (...args: OverloadArguments<A0>) => Result :
169
- never
170
- }
171
-
172
- /* ========================================================================== *
173
- * EXPECTATIONS DEFINITION *
174
- * ========================================================================== */
175
-
176
- /**
177
- * Expectation functions simply check a _value_, but do not alter the type
178
- * returned by each expectation.
179
- */
180
- export interface ExpectationFunctions<T> extends
181
- OverloadFunctions<AsyncExpectations, Promise<Expectations<PromiseLike<T>>>>,
182
- OverloadFunctions<SyncExpectations, Expectations<T>> {
183
- // empty interface, specifically without `value` or `not` so that
184
- // in no way this can be confused with the full `Expectations<T>`.
185
- }
186
-
187
- /**
188
- * An interface describing all expectations returned by `expect(...)`.
189
- *
190
- * Each function, upon checking, might return an expectation bound to a
191
- * different _type_ (for example `.toBeNull()` returns always
192
- * `Expectations<null>`, inferring that `value` is indeed `null`).
193
- */
194
- export interface Expectations<T = unknown> extends AllExpectations {
195
- /** The value this {@link Expectations} instance operates on */
196
- readonly value: T
197
- /** The _negated_ expectations of _this_ {@link Expectations} instance. */
198
- readonly not: ExpectationFunctions<T>
199
- }
200
-
201
- /* ========================================================================== *
202
- * EXPECTATIONS IMPLEMENTATION *
203
- * ========================================================================== */
204
-
205
- class ExpectationsContextImpl<T = unknown> implements ExpectationsContext<T> {
206
- constructor(
207
- readonly value: T,
208
- readonly negative: boolean,
209
- readonly expects: Expectations<T>,
210
- readonly negated: ExpectationFunctions<T>,
211
- readonly parent?: ExpectationsParent,
212
- ) {}
213
-
214
- forValue<V>(value: V): Expectations<V> {
215
- return new ExpectationsImpl(value)
216
- }
217
-
218
- forProperty(prop: string | number | symbol): Expectations<unknown> {
219
- this.expects.toBeDefined()
220
-
221
- const value = (this.value as any)[prop]
222
- const parent = { context: this, prop }
223
- return new ExpectationsImpl(value, parent)
224
- }
225
- }
226
-
227
- /** Empty interface: the `class` below won't complain about missing stuff */
228
- interface ExpectationsImpl<T = unknown> extends Expectations<T> {}
229
-
230
- /** Implementation of our {@link Expectations} interface */
231
- class ExpectationsImpl<T = unknown> implements Expectations<T> {
232
- private readonly _context: ExpectationsContext<T>
233
-
234
- readonly value: T
235
- readonly not: ExpectationFunctions<T>
236
-
237
- constructor(
238
- value: T,
239
- parent?: ExpectationsParent,
240
- positives?: Expectations<T>,
241
- ) {
242
- this.value = value
243
-
244
- if (positives) {
245
- this.not = positives as ExpectationFunctions<any>
246
- this._context = new ExpectationsContextImpl(
247
- value,
248
- true,
249
- positives,
250
- this as ExpectationFunctions<any>,
251
- parent)
252
- } else {
253
- this._context = new ExpectationsContextImpl(
254
- value,
255
- false,
256
- this,
257
- this as ExpectationFunctions<any>,
258
- parent)
259
- this.not = new ExpectationsImpl(value, parent, this) as ExpectationFunctions<any>
260
- }
261
- }
262
-
263
- /* == STATIC INITALIZER =================================================== */
264
-
265
- static {
266
- for (const [ key, value ] of Object.entries(allExpectations)) {
267
- const expectation = value as (this: ExpectationsContext, ...args: any[]) => any
268
-
269
- const fn = function(this: ExpectationsImpl, ...args: any[]): any {
270
- try {
271
- return expectation.call(this._context, ...args)
272
- } catch (error) {
273
- if (error instanceof ExpectationError) Error.captureStackTrace(error, fn)
274
- throw error
275
- }
276
- }
277
-
278
- Object.defineProperty(fn, 'name', { value: key })
279
- Object.defineProperty(this.prototype, key, { value: fn })
280
- }
281
- }
282
- }
283
-
284
- /* ========================================================================== *
285
- * EXPECTATIONS MATCHERS *
286
- * ========================================================================== */
287
-
288
- /** An interface describing all expectations returned by `expect(...)` */
289
- export interface Matchers extends OverloadFunctions<SyncExpectations, Matchers> {
290
- not: Matchers
291
- /* The assertion here will trigger */
292
- expect(value: unknown): void
293
- }
294
-
295
- interface MatcherImpl extends Matchers {}
296
-
297
- class MatcherImpl {
298
- private readonly _matchers: readonly [ string, boolean, any[] ][]
299
- private readonly _positiveBuilder: MatcherImpl
300
- private readonly _negativeBuilder: MatcherImpl
301
- private readonly _negative: boolean
302
-
303
- constructor(
304
- _matchers: readonly [ string, boolean, any[] ][],
305
- _positiveBuilder?: MatcherImpl,
306
- ) {
307
- this._matchers = _matchers
308
- if (_positiveBuilder) {
309
- this._negative = true
310
- this._positiveBuilder = _positiveBuilder
311
- this._negativeBuilder = this
312
- } else {
313
- this._negative = false
314
- this._positiveBuilder = this
315
- this._negativeBuilder = new MatcherImpl(this._matchers, this)
316
- }
317
- }
318
-
319
- get not(): MatcherImpl {
320
- return this._negative ? this._positiveBuilder : this._negativeBuilder
321
- }
322
-
323
- expect(value: unknown): void {
324
- const expectations = expect(value)
325
- for (const [ expectation, negative, args ] of this._matchers) {
326
- const expect = negative ? expectations.not as any : expectations as any
327
- expect[expectation](...args)
328
- }
329
- }
330
-
331
- /* == STATIC INITALIZER =================================================== */
332
-
333
- static {
334
- // for "isMatcher(...)" used by "diff(...)"
335
- Object.defineProperty(this.prototype, matcherMarker, { value: matcherMarker })
336
-
337
- // all our matchers
338
- for (const key in syncExpectations) {
339
- Object.defineProperty(this.prototype, key, {
340
- value: function(this: MatcherImpl, ...args: any[]): any {
341
- return new MatcherImpl([
342
- ...this._matchers, [ key, this._negative, args ],
343
- ])
344
- },
345
- })
346
- }
347
- }
348
- }
4
+ export type { AsyncExpectations } from './async'
5
+ export type { Expectations, NegativeExpectations } from './expectations'
6
+ export type { Matchers, NegativeMatchers } from './matchers'
349
7
 
350
8
  /* ========================================================================== *
351
9
  * EXPECT FUNCTION *
352
10
  * ========================================================================== */
353
11
 
354
12
  /** The `expect` function exposing expectations and matchers */
355
- export const expect = (<T = unknown>(value: T): Expectations<T> => {
356
- return new ExpectationsImpl(value)
357
- }) as Matchers & (<T = unknown>(value: T) => Expectations<T>)
13
+ export type Expect = {
14
+ <T = unknown>(value: T, remarks?: string): AsyncExpectations<T>
15
+ } & Omit<Matchers, 'expect'>
358
16
 
359
- // Instrument a getter for negative matchers
360
- Object.defineProperty(expect, 'not', {
361
- get: () => new MatcherImpl([]).not,
362
- })
17
+ /** The `expect` function exposing expectations and matchers */
18
+ export const expect: Expect = ((value: any, remarks?: string) => {
19
+ return new AsyncExpectations(value, remarks)
20
+ }) as Expect
21
+
22
+ /* Inject all our matchers constructors in the `expect` function */
23
+ for (const key of Object.getOwnPropertyNames(Matchers.prototype)) {
24
+ if (! key.startsWith('to')) continue
363
25
 
364
- // Create a matcher for each expectation function
365
- for (const name in syncExpectations) {
366
- Object.defineProperty(expect, name, {
367
- value: function(...args: any[]): Matchers {
368
- const builder = new MatcherImpl([])
369
- return (builder as any)[name](...args)
370
- },
371
- })
26
+ const matcher = (...args: any[]): any => ((new Matchers() as any)[key](...args))
27
+ Object.defineProperty(matcher, 'name', { value: key })
28
+ Object.defineProperty(expect, key, { value: matcher })
372
29
  }
30
+
31
+ /* Inject the negative matcher constructor in the `expect` function */
32
+ Object.defineProperty(expect, 'not', { get: () => new Matchers().not })