@@ -6,6 +6,14 @@ description: |
6
6
defines: [asyncTest]
7
7
---*/
8
8
9
+ /**
10
+ * Defines the **sole** asynchronous test of a file.
11
+ * @see {@link ../docs/rfcs/async-helpers.md } for background.
12
+ *
13
+ * @param {Function } testFunc a callback whose returned promise indicates test results
14
+ * (fulfillment for success, rejection for failure)
15
+ * @returns {void }
16
+ */
9
17
function asyncTest ( testFunc ) {
10
18
if ( ! Object . hasOwn ( globalThis , "$DONE" ) ) {
11
19
throw new Test262Error ( "asyncTest called without async flag" ) ;
@@ -28,86 +36,62 @@ function asyncTest(testFunc) {
28
36
}
29
37
}
30
38
39
+ /**
40
+ * Asserts that a callback asynchronously throws an instance of a particular
41
+ * error (i.e., returns a promise whose rejection value is an object referencing
42
+ * the constructor).
43
+ *
44
+ * @param {Function } expectedErrorConstructor the expected constructor of the
45
+ * rejection value
46
+ * @param {Function } func the callback
47
+ * @param {string } [message] the prefix to use for failure messages
48
+ * @returns {Promise<void> } fulfills if the expected error is thrown,
49
+ * otherwise rejects
50
+ */
31
51
assert . throwsAsync = function ( expectedErrorConstructor , func , message ) {
32
52
return new Promise ( function ( resolve ) {
33
- var innerThenable ;
34
- if ( message === undefined ) {
35
- message = "" ;
36
- } else {
37
- message += " " ;
38
- }
39
- if ( typeof func === "function" ) {
40
- try {
41
- innerThenable = func ( ) ;
42
- if (
43
- innerThenable === null ||
44
- typeof innerThenable !== "object" ||
45
- typeof innerThenable . then !== "function"
46
- ) {
47
- message +=
48
- "Expected to obtain an inner promise that would reject with a" +
49
- expectedErrorConstructor . name +
50
- " but result was not a thenable" ;
51
- throw new Test262Error ( message ) ;
52
- }
53
- } catch ( thrown ) {
54
- message +=
55
- "Expected a " +
56
- expectedErrorConstructor . name +
57
- " to be thrown asynchronously but an exception was thrown synchronously while obtaining the inner promise" ;
58
- throw new Test262Error ( message ) ;
53
+ var expectedName = expectedErrorConstructor . name ;
54
+ var expectation = "Expected a " + expectedName + " to be thrown asynchronously" ;
55
+ var fail = function ( detail ) {
56
+ if ( message === undefined ) {
57
+ throw new Test262Error ( detail ) ;
59
58
}
60
- } else {
61
- message +=
62
- "assert.throwsAsync called with an argument that is not a function" ;
63
- throw new Test262Error ( message ) ;
59
+ throw new Test262Error ( message + " " + detail ) ;
60
+ } ;
61
+ var res ;
62
+ if ( typeof func !== "function" ) {
63
+ fail ( "assert.throwsAsync called with an argument that is not a function" ) ;
64
+ }
65
+ try {
66
+ res = func ( ) ;
67
+ } catch ( thrown ) {
68
+ fail ( expectation + " but the function threw synchronously" ) ;
69
+ }
70
+ if ( res === null || typeof res !== "object" || typeof res . then !== "function" ) {
71
+ fail ( expectation + " but result was not a thenable" ) ;
64
72
}
65
73
66
74
try {
67
- resolve ( innerThenable . then (
75
+ resolve ( res . then (
68
76
function ( ) {
69
- message +=
70
- "Expected a " +
71
- expectedErrorConstructor . name +
72
- " to be thrown asynchronously but no exception was thrown at all" ;
73
- throw new Test262Error ( message ) ;
77
+ fail ( expectation + " but no exception was thrown at all" ) ;
74
78
} ,
75
79
function ( thrown ) {
76
- var expectedName , actualName ;
77
- if ( typeof thrown !== "object" || thrown === null ) {
78
- message += "Thrown value was not an object!" ;
79
- throw new Test262Error ( message ) ;
80
+ var actualName ;
81
+ if ( thrown === null || typeof thrown !== "object" ) {
82
+ fail ( expectation + " but thrown value was not an object" ) ;
80
83
} else if ( thrown . constructor !== expectedErrorConstructor ) {
81
- expectedName = expectedErrorConstructor . name ;
82
84
actualName = thrown . constructor . name ;
83
85
if ( expectedName === actualName ) {
84
- message +=
85
- "Expected a " +
86
- expectedName +
87
- " but got a different error constructor with the same name" ;
88
- } else {
89
- message +=
90
- "Expected a " + expectedName + " but got a " + actualName ;
86
+ fail ( expectation +
87
+ " but got a different error constructor with the same name" ) ;
91
88
}
92
- throw new Test262Error ( message ) ;
89
+ fail ( expectation + " but got a " + actualName ) ;
93
90
}
94
91
}
95
92
) ) ;
96
93
} catch ( thrown ) {
97
- if ( typeof thrown !== "object" || thrown === null ) {
98
- message +=
99
- "Expected a " +
100
- expectedErrorConstructor . name +
101
- " to be thrown asynchronously but innerThenable synchronously threw a value that was not an object " ;
102
- } else {
103
- message +=
104
- "Expected a " +
105
- expectedErrorConstructor . name +
106
- " to be thrown asynchronously but a " +
107
- thrown . constructor . name +
108
- " was thrown synchronously" ;
109
- }
110
- throw new Test262Error ( message ) ;
94
+ fail ( expectation + " but .then threw synchronously" ) ;
111
95
}
112
96
} ) ;
113
97
} ;
0 commit comments