@plugjs/expect5 0.4.6 → 0.4.7
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/cli.mjs +1 -1
- package/dist/expectation/async.cjs +14 -22
- package/dist/expectation/async.cjs.map +1 -1
- package/dist/expectation/async.d.ts +39 -13
- package/dist/expectation/async.mjs +14 -22
- package/dist/expectation/async.mjs.map +1 -1
- package/dist/expectation/expect.cjs +3 -3
- package/dist/expectation/expect.cjs.map +1 -1
- package/dist/expectation/expect.d.ts +3 -3
- package/dist/expectation/expect.mjs +4 -4
- package/dist/expectation/expect.mjs.map +1 -1
- package/dist/expectation/expectations.cjs +27 -44
- package/dist/expectation/expectations.cjs.map +1 -1
- package/dist/expectation/expectations.d.ts +72 -14
- package/dist/expectation/expectations.mjs +27 -44
- package/dist/expectation/expectations.mjs.map +1 -1
- package/dist/expectation/matchers.cjs +24 -47
- package/dist/expectation/matchers.cjs.map +1 -1
- package/dist/expectation/matchers.d.ts +136 -93
- package/dist/expectation/matchers.mjs +23 -46
- package/dist/expectation/matchers.mjs.map +1 -1
- package/dist/expectation/types.cjs.map +1 -1
- package/dist/expectation/types.d.ts +2 -2
- package/dist/expectation/types.mjs.map +1 -1
- package/dist/test.cjs +5 -2
- package/dist/test.cjs.map +1 -1
- package/dist/test.mjs +6 -3
- package/dist/test.mjs.map +1 -1
- package/package.json +3 -3
- package/src/expectation/async.ts +69 -17
- package/src/expectation/expect.ts +6 -6
- package/src/expectation/expectations.ts +152 -27
- package/src/expectation/matchers.ts +207 -125
- package/src/expectation/types.ts +2 -2
- package/src/test.ts +8 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { diff, type Diff } from './diff'
|
|
2
2
|
import { toInclude, toMatchContents } from './include'
|
|
3
|
-
import { type
|
|
3
|
+
import { type Matcher } from './matchers'
|
|
4
4
|
import {
|
|
5
5
|
ExpectationError,
|
|
6
6
|
isMatcher,
|
|
@@ -28,13 +28,20 @@ export type AssertedType<T, F extends AssertionFunction<any>, R = ReturnType<F>>
|
|
|
28
28
|
I : // returns Expectations<something>, use "something"
|
|
29
29
|
T // returns something else (void), use T
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
/** Infer the type of a {@link Matcher} */
|
|
32
|
+
export type InferMatcher<T, M extends Matcher> =
|
|
33
|
+
M extends Matcher<infer I> ?
|
|
34
|
+
unknown extends I ? T : T & I :
|
|
35
|
+
never
|
|
36
|
+
|
|
37
|
+
/** Recursively infer the type of a {@link Matcher} in a `Record` */
|
|
38
|
+
export type InferToEqual<T> =
|
|
39
|
+
T extends Matcher<infer V> ? V :
|
|
40
|
+
T extends Record<any, any> ? { [ k in keyof T ] : InferToEqual<T[k]> } :
|
|
34
41
|
T
|
|
35
42
|
|
|
36
43
|
/** Simple wrapper defining the _parent_ instance of an {@link Expectations}. */
|
|
37
|
-
type ExpectationsParent = {
|
|
44
|
+
export type ExpectationsParent = {
|
|
38
45
|
/** Parent {@link Expectations} instance */
|
|
39
46
|
expectations: Expectations,
|
|
40
47
|
/** Property associating _this_ to the parent */
|
|
@@ -79,9 +86,31 @@ export class Expectations<T = unknown> {
|
|
|
79
86
|
* BASIC *
|
|
80
87
|
* ------------------------------------------------------------------------ */
|
|
81
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Expects the value to be of the specified _extended_ {@link TypeName type}.
|
|
91
|
+
*
|
|
92
|
+
* Negation: {@link NegativeExpectations.toBeA `not.toBeA(...)`}
|
|
93
|
+
*/
|
|
94
|
+
toBeA<Name extends TypeName>(type: Name): Expectations<TypeMappings[Name]>
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Expects the value to be of the specified _extended_ {@link TypeName type},
|
|
98
|
+
* and further validates it with a {@link Matcher}.
|
|
99
|
+
*
|
|
100
|
+
* Negation: {@link NegativeExpectations.toBeA `not.toBeA(...)`}
|
|
101
|
+
*/
|
|
102
|
+
toBeA<
|
|
103
|
+
Name extends TypeName,
|
|
104
|
+
Mapped extends TypeMappings[Name],
|
|
105
|
+
Match extends Matcher,
|
|
106
|
+
>(
|
|
107
|
+
type: Name,
|
|
108
|
+
matcher: Match,
|
|
109
|
+
): Expectations<InferMatcher<Mapped, Match>>
|
|
110
|
+
|
|
82
111
|
/**
|
|
83
112
|
* Expects the value to be of the specified _extended_ {@link TypeName type},
|
|
84
|
-
* and
|
|
113
|
+
* and further asserts it with an {@link AssertionFunction}.
|
|
85
114
|
*
|
|
86
115
|
* Negation: {@link NegativeExpectations.toBeA `not.toBeA(...)`}
|
|
87
116
|
*/
|
|
@@ -90,11 +119,20 @@ export class Expectations<T = unknown> {
|
|
|
90
119
|
Mapped extends TypeMappings[Name],
|
|
91
120
|
Assert extends AssertionFunction<Mapped>,
|
|
92
121
|
>(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
): Expectations<AssertedType<Mapped, Assert>>
|
|
122
|
+
type: Name,
|
|
123
|
+
assertion: Assert,
|
|
124
|
+
): Expectations<AssertedType<Mapped, Assert>>
|
|
125
|
+
|
|
126
|
+
toBeA(
|
|
127
|
+
type: TypeName,
|
|
128
|
+
assertionOrMatcher?: AssertionFunction | Matcher,
|
|
129
|
+
): Expectations {
|
|
96
130
|
if (typeOf(this.value) === type) {
|
|
97
|
-
if (
|
|
131
|
+
if (isMatcher(assertionOrMatcher)) {
|
|
132
|
+
assertionOrMatcher.expect(this.value)
|
|
133
|
+
} else if (assertionOrMatcher) {
|
|
134
|
+
assertionOrMatcher(this as Expectations<any>)
|
|
135
|
+
}
|
|
98
136
|
return this as Expectations<any>
|
|
99
137
|
}
|
|
100
138
|
|
|
@@ -250,9 +288,32 @@ export class Expectations<T = unknown> {
|
|
|
250
288
|
|
|
251
289
|
/* ------------------------------------------------------------------------ */
|
|
252
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Expects the value to be an instance of the specified {@link Constructor}.
|
|
293
|
+
*
|
|
294
|
+
* Negation: {@link NegativeExpectations.toBeInstanceOf `not.toInstanceOf(...)`}
|
|
295
|
+
*/
|
|
296
|
+
toBeInstanceOf<Class extends Constructor>(
|
|
297
|
+
constructor: Class,
|
|
298
|
+
): Expectations<InstanceType<Class>>
|
|
299
|
+
|
|
253
300
|
/**
|
|
254
301
|
* Expects the value to be an instance of the specified {@link Constructor},
|
|
255
|
-
* and
|
|
302
|
+
* and further validates it with a {@link Matcher}.
|
|
303
|
+
*
|
|
304
|
+
* Negation: {@link NegativeExpectations.toBeInstanceOf `not.toInstanceOf(...)`}
|
|
305
|
+
*/
|
|
306
|
+
toBeInstanceOf<
|
|
307
|
+
Class extends Constructor,
|
|
308
|
+
Match extends Matcher,
|
|
309
|
+
>(
|
|
310
|
+
constructor: Class,
|
|
311
|
+
matcher: Match,
|
|
312
|
+
): Expectations<InferMatcher<InstanceType<Class>, Match>>
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Expects the value to be an instance of the specified {@link Constructor},
|
|
316
|
+
* and further asserts it with an {@link AssertionFunction}.
|
|
256
317
|
*
|
|
257
318
|
* Negation: {@link NegativeExpectations.toBeInstanceOf `not.toInstanceOf(...)`}
|
|
258
319
|
*/
|
|
@@ -260,11 +321,20 @@ export class Expectations<T = unknown> {
|
|
|
260
321
|
Class extends Constructor,
|
|
261
322
|
Assert extends AssertionFunction<InstanceType<Class>>,
|
|
262
323
|
>(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
): Expectations<AssertedType<InstanceType<Class>, Assert>>
|
|
324
|
+
constructor: Class,
|
|
325
|
+
assertion: Assert,
|
|
326
|
+
): Expectations<AssertedType<InstanceType<Class>, Assert>>
|
|
327
|
+
|
|
328
|
+
toBeInstanceOf(
|
|
329
|
+
constructor: Constructor,
|
|
330
|
+
assertionOrMatcher?: AssertionFunction | Matcher,
|
|
331
|
+
): Expectations {
|
|
266
332
|
if (this.value instanceof constructor) {
|
|
267
|
-
if (
|
|
333
|
+
if (isMatcher(assertionOrMatcher)) {
|
|
334
|
+
assertionOrMatcher.expect(this.value)
|
|
335
|
+
} else if (assertionOrMatcher) {
|
|
336
|
+
assertionOrMatcher(this as Expectations<any>)
|
|
337
|
+
}
|
|
268
338
|
return this as Expectations<any>
|
|
269
339
|
}
|
|
270
340
|
|
|
@@ -404,7 +474,7 @@ export class Expectations<T = unknown> {
|
|
|
404
474
|
*
|
|
405
475
|
* Negation: {@link NegativeExpectations.toEqual `not.toEqual(...)`}
|
|
406
476
|
*/
|
|
407
|
-
toEqual<Type>(expected: Type): Expectations<
|
|
477
|
+
toEqual<Type>(expected: Type): Expectations<InferToEqual<Type>> {
|
|
408
478
|
if ((this.value as any) === expected) return this as Expectations<any>
|
|
409
479
|
|
|
410
480
|
const result = diff(this.value, expected)
|
|
@@ -443,6 +513,29 @@ export class Expectations<T = unknown> {
|
|
|
443
513
|
|
|
444
514
|
/* ------------------------------------------------------------------------ */
|
|
445
515
|
|
|
516
|
+
/**
|
|
517
|
+
* Expects the value to have the specified _property_.
|
|
518
|
+
*
|
|
519
|
+
* Negation: {@link NegativeExpectations.toHaveProperty `not.toHaveProperty(...)`}
|
|
520
|
+
*/
|
|
521
|
+
toHaveProperty<Prop extends string | number | symbol>(
|
|
522
|
+
property: Prop,
|
|
523
|
+
): Expectations<T & { [keyt in Prop] : unknown }>
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Expects the value to have the specified _property_ and (if specified)
|
|
527
|
+
* further validates its value with a {@link Matcher}.
|
|
528
|
+
*
|
|
529
|
+
* Negation: {@link NegativeExpectations.toHaveProperty `not.toHaveProperty(...)`}
|
|
530
|
+
*/
|
|
531
|
+
toHaveProperty<
|
|
532
|
+
Prop extends string | number | symbol,
|
|
533
|
+
Match extends Matcher,
|
|
534
|
+
>(
|
|
535
|
+
property: Prop,
|
|
536
|
+
matcher: Match,
|
|
537
|
+
): Expectations<T & { [keyt in Prop] : InferMatcher<unknown, Match> }>
|
|
538
|
+
|
|
446
539
|
/**
|
|
447
540
|
* Expects the value to have the specified _property_ and (if specified)
|
|
448
541
|
* further asserts its value with an {@link AssertionFunction}.
|
|
@@ -453,9 +546,14 @@ export class Expectations<T = unknown> {
|
|
|
453
546
|
Prop extends string | number | symbol,
|
|
454
547
|
Assert extends AssertionFunction,
|
|
455
548
|
>(
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
): Expectations<T & { [keyt in Prop] : AssertedType<unknown, Assert> }>
|
|
549
|
+
property: Prop,
|
|
550
|
+
assertion: Assert,
|
|
551
|
+
): Expectations<T & { [keyt in Prop] : AssertedType<unknown, Assert> }>
|
|
552
|
+
|
|
553
|
+
toHaveProperty(
|
|
554
|
+
property: string | number | symbol,
|
|
555
|
+
assertionOrMatcher?: AssertionFunction | Matcher,
|
|
556
|
+
): Expectations {
|
|
459
557
|
this.toBeDefined()
|
|
460
558
|
|
|
461
559
|
const propertyValue = (this.value as any)[property]
|
|
@@ -464,11 +562,15 @@ export class Expectations<T = unknown> {
|
|
|
464
562
|
this._fail(`to have property "${String(property)}"`)
|
|
465
563
|
}
|
|
466
564
|
|
|
467
|
-
if (
|
|
565
|
+
if (assertionOrMatcher) {
|
|
566
|
+
const parent: ExpectationsParent = { expectations: this, prop: property }
|
|
468
567
|
try {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
568
|
+
if (isMatcher(assertionOrMatcher)) {
|
|
569
|
+
assertionOrMatcher.expect(propertyValue, parent)
|
|
570
|
+
} else if (assertionOrMatcher) {
|
|
571
|
+
const expectations = new Expectations(propertyValue, this.remarks, parent)
|
|
572
|
+
assertionOrMatcher(expectations)
|
|
573
|
+
}
|
|
472
574
|
} catch (error) {
|
|
473
575
|
// any caught error difference gets remapped as a property diff
|
|
474
576
|
if ((error instanceof ExpectationError) && (error.diff)) {
|
|
@@ -596,12 +698,31 @@ export class Expectations<T = unknown> {
|
|
|
596
698
|
/* ------------------------------------------------------------------------ */
|
|
597
699
|
|
|
598
700
|
/**
|
|
599
|
-
* Expects the value to be a `function` throwing
|
|
600
|
-
* asserts the thrown value with an {@link AssertionFunction}.
|
|
701
|
+
* Expects the value to be a `function` throwing.
|
|
601
702
|
*
|
|
602
703
|
* Negation: {@link NegativeExpectations.toThrow `not.toThrow()`}
|
|
603
704
|
*/
|
|
604
|
-
toThrow(
|
|
705
|
+
toThrow(): Expectations<() => any>
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Expects the value to be a `function` throwing, and further validates the
|
|
709
|
+
* thrown value with a {@link Matcher}.
|
|
710
|
+
*
|
|
711
|
+
* Negation: {@link NegativeExpectations.toThrow `not.toThrow()`}
|
|
712
|
+
*/
|
|
713
|
+
toThrow(matcher: Matcher): Expectations<() => any>
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Expects the value to be a `function` throwing, and further asserts the
|
|
717
|
+
* thrown value with an {@link AssertionFunction}.
|
|
718
|
+
*
|
|
719
|
+
* Negation: {@link NegativeExpectations.toThrow `not.toThrow()`}
|
|
720
|
+
*/
|
|
721
|
+
toThrow(assert: AssertionFunction): Expectations<() => any>
|
|
722
|
+
|
|
723
|
+
toThrow(
|
|
724
|
+
assertionOrMatcher?: AssertionFunction | Matcher,
|
|
725
|
+
): Expectations<() => any> {
|
|
605
726
|
const func = this.toBeA('function')
|
|
606
727
|
|
|
607
728
|
let passed = false
|
|
@@ -609,7 +730,11 @@ export class Expectations<T = unknown> {
|
|
|
609
730
|
func.value()
|
|
610
731
|
passed = true
|
|
611
732
|
} catch (thrown) {
|
|
612
|
-
if (
|
|
733
|
+
if (isMatcher(assertionOrMatcher)) {
|
|
734
|
+
assertionOrMatcher.expect(thrown)
|
|
735
|
+
} else if (assertionOrMatcher) {
|
|
736
|
+
assertionOrMatcher(new Expectations(thrown, this.remarks))
|
|
737
|
+
}
|
|
613
738
|
}
|
|
614
739
|
|
|
615
740
|
if (passed) this._fail('to throw')
|