risei 1.3.4 → 2.0.1
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/README.md +134 -479
- package/index.js +5 -5
- package/package.json +10 -11
- package/system/ASpoofingFixture.js +7 -8
- package/system/ATestCaller.js +3 -3
- package/system/ATestFinder.js +2 -2
- package/system/ATestReporter.js +2 -1
- package/system/ATestSource.js +5 -1
- package/system/ChosenTestFinder.js +4 -4
- package/system/ClassTestGroup.js +2 -2
- package/system/LocalCaller.js +5 -5
- package/system/{ClassMethodSpoofer.js → MethodSpoofer.js} +54 -48
- package/system/MethodTestGroup.js +2 -2
- package/system/Moment.js +1 -1
- package/system/NameAnalyzer.js +26 -0
- package/system/PropertySpoofer.js +156 -0
- package/system/Risei.js +5 -5
- package/system/SpoofDef.js +260 -0
- package/system/TerminalReporter.js +8 -8
- package/system/{TestDefinition.js → TestDef.js} +153 -107
- package/system/TestFinder.js +3 -3
- package/system/TestFrame.js +15 -52
- package/system/TestGroup.js +1 -1
- package/system/TestResult.js +2 -2
- package/system/TestRunner.js +23 -107
- package/system/TestStages.js +80 -76
- package/system/TestSummary.js +1 -1
- package/system/TotalComparer.js +60 -11
- package/system/TotalDisplayer.js +33 -12
- package/system/TypeAnalyzer.js +41 -79
- package/system/TypeIdentifier.js +18 -8
- package/system/Types.js +3 -1
- package/system/AComparer.js +0 -9
- package/system/ATestFixture.js +0 -44
- package/system/ClassPropertySpoofer.js +0 -185
- package/system/ObjectMethodSpoofer.js +0 -58
- package/system/ObjectPropertySpoofer.js +0 -136
- package/system/SpoofDefinition.js +0 -243
- package/system/TestFrameChooser.js +0 -54
- package/system/TestFrames.js +0 -232
- package/system/TotalCopier.js +0 -106
- package/usage-examples/Output-example.png +0 -0
- package/usage-examples/Summary-example.png +0 -0
- package/usage-examples/Syntax-example.png +0 -0
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
/**/
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
3
|
+
import TypeAnalyzer from "./TypeAnalyzer.js";
|
|
4
|
+
import NameAnalyzer from "./NameAnalyzer.js";
|
|
5
|
+
import TypeIdentifier from "./TypeIdentifier.js";
|
|
6
|
+
import Types from "./Types.js";
|
|
7
7
|
|
|
8
|
-
/* Defines what is found in a test
|
|
8
|
+
/* Defines what is found in a test definition, typically as
|
|
9
|
+
a nonce object rather than an instance of this class. */
|
|
9
10
|
|
|
10
|
-
export class
|
|
11
|
+
export default class TestDef {
|
|
11
12
|
// region Definitions
|
|
12
13
|
|
|
13
14
|
static staticName = "static";
|
|
14
15
|
static throwName = "throw";
|
|
15
16
|
static constructorName = "constructor";
|
|
16
|
-
static nonceLocalCallableName = "
|
|
17
|
-
static dotOperator = ".";
|
|
18
|
-
static colonOperator = ":";
|
|
19
|
-
static parensOperator = "()";
|
|
20
|
-
static operatorsRegExp = /\.|:|\(\)/g;
|
|
17
|
+
static nonceLocalCallableName = "nonce";
|
|
21
18
|
|
|
22
19
|
// endregion Definitions
|
|
23
20
|
|
|
@@ -29,17 +26,14 @@ export class TestDefinition {
|
|
|
29
26
|
[ "with", "initors" ],
|
|
30
27
|
[ "of", "method" ],
|
|
31
28
|
[ "plus", "spoofed" ],
|
|
32
|
-
[ "amid", "settables" ],
|
|
33
29
|
[ "in", "inputs" ],
|
|
34
30
|
[ "out", "output" ],
|
|
35
31
|
[ "from", "source" ],
|
|
36
|
-
[ "and", "factors" ]
|
|
32
|
+
[ "and", "factors" ],
|
|
33
|
+
[ "do", "enact" ],
|
|
34
|
+
[ "undo", "counteract" ]
|
|
37
35
|
]);
|
|
38
36
|
|
|
39
|
-
static #copier = new TotalCopier();
|
|
40
|
-
|
|
41
|
-
static #identifier = new TypeIdentifier();
|
|
42
|
-
|
|
43
37
|
// endregion Static fields
|
|
44
38
|
|
|
45
39
|
// region Fields
|
|
@@ -52,14 +46,14 @@ export class TestDefinition {
|
|
|
52
46
|
initors;
|
|
53
47
|
method;
|
|
54
48
|
spoofed;
|
|
55
|
-
settables;
|
|
56
49
|
inputs;
|
|
57
50
|
output;
|
|
58
51
|
source;
|
|
59
52
|
factors;
|
|
53
|
+
enact;
|
|
54
|
+
counteract;
|
|
60
55
|
|
|
61
56
|
target;
|
|
62
|
-
localCallable;
|
|
63
57
|
|
|
64
58
|
actual;
|
|
65
59
|
thrown;
|
|
@@ -112,15 +106,6 @@ export class TestDefinition {
|
|
|
112
106
|
this.spoofed = value;
|
|
113
107
|
}
|
|
114
108
|
|
|
115
|
-
/* &cruft, drop or rename this .amid property pair */
|
|
116
|
-
get amid() {
|
|
117
|
-
return this.settables;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
set amid(value) {
|
|
121
|
-
this.settables = value;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
109
|
get in() {
|
|
125
110
|
return this.inputs;
|
|
126
111
|
}
|
|
@@ -153,11 +138,27 @@ export class TestDefinition {
|
|
|
153
138
|
this.factors = value;
|
|
154
139
|
}
|
|
155
140
|
|
|
141
|
+
get do() {
|
|
142
|
+
return this.enact;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
set do(value) {
|
|
146
|
+
this.enact = value;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
get undo() {
|
|
150
|
+
return this.counteract;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
set undo(value) {
|
|
154
|
+
this.counteract = value;
|
|
155
|
+
}
|
|
156
|
+
|
|
156
157
|
// endregion Test definition, short names
|
|
157
158
|
|
|
158
|
-
// region
|
|
159
|
+
// region Def state
|
|
159
160
|
|
|
160
|
-
get isRunnable() {
|
|
161
|
+
get isRunnable() /* passed */ {
|
|
161
162
|
let isRunnable
|
|
162
163
|
= this.nature !== undefined
|
|
163
164
|
&& this.type !== undefined
|
|
@@ -174,32 +175,22 @@ export class TestDefinition {
|
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
get isStaticTest() /* passed */ {
|
|
177
|
-
let plainName =
|
|
178
|
+
let plainName = NameAnalyzer.plainNameOf(this.of);
|
|
178
179
|
|
|
179
|
-
let is = TypeAnalyzer.
|
|
180
|
-
let stated = this.andStringContains(
|
|
180
|
+
let is = TypeAnalyzer.isStaticMember(this.on, plainName);
|
|
181
|
+
let stated = this.andStringContains(TestDef.staticName);
|
|
181
182
|
|
|
182
183
|
return is || stated;
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
get isThrowTest() /* passed */ {
|
|
186
|
-
let is = this.andStringContains(
|
|
187
|
+
let is = this.andStringContains(TestDef.throwName);
|
|
187
188
|
return is;
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
/* Needed externally, and dependency
|
|
191
|
-
of all .and-based properties. */
|
|
192
|
-
andStringContains(keyword) /* passed */ {
|
|
193
|
-
let doesContain
|
|
194
|
-
= typeof this.and === "string"
|
|
195
|
-
&& this.and.includes(keyword);
|
|
196
|
-
|
|
197
|
-
return doesContain;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
191
|
get isConstructorTest() /* passed */ {
|
|
201
|
-
let plainTarget =
|
|
202
|
-
return plainTarget ===
|
|
192
|
+
let plainTarget = NameAnalyzer.plainNameOf(this.of);
|
|
193
|
+
return plainTarget === TestDef.constructorName;
|
|
203
194
|
}
|
|
204
195
|
|
|
205
196
|
get isMethodTest() /* passed */ {
|
|
@@ -207,12 +198,11 @@ export class TestDefinition {
|
|
|
207
198
|
}
|
|
208
199
|
|
|
209
200
|
get isPropertyTest() /* passed */ {
|
|
210
|
-
let plainName =
|
|
201
|
+
let plainName = NameAnalyzer.plainNameOf(this.of);
|
|
211
202
|
|
|
212
203
|
let isPropertyTest
|
|
213
|
-
= this.of
|
|
214
|
-
||
|
|
215
|
-
|| TypeAnalyzer.memberIsProperty(this.on, plainName);
|
|
204
|
+
= NameAnalyzer.hasPropertySigil(this.of)
|
|
205
|
+
|| TypeAnalyzer.isPropertyMember(this.on, plainName);
|
|
216
206
|
|
|
217
207
|
return isPropertyTest;
|
|
218
208
|
}
|
|
@@ -237,121 +227,185 @@ export class TestDefinition {
|
|
|
237
227
|
return false;
|
|
238
228
|
}
|
|
239
229
|
|
|
240
|
-
|
|
230
|
+
get doesHaveDoEarly() /* passed */ {
|
|
231
|
+
if (this.do === undefined) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
241
234
|
|
|
242
|
-
|
|
235
|
+
return TypeIdentifier.identify(this.do.early) === Types.isFunction;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
get doesHaveDoLate() /* passed */ {
|
|
239
|
+
if (this.do === undefined) {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return TypeIdentifier.identify(this.do.late) === Types.isFunction;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
get doesHaveUndo() /* passed */ {
|
|
247
|
+
return TypeIdentifier.identify(this.undo) === Types.isFunction;
|
|
248
|
+
}
|
|
243
249
|
|
|
244
|
-
|
|
250
|
+
/* Used for grouping in output by method or
|
|
251
|
+
prop name, with type sigil only once. */
|
|
252
|
+
get runName() /* passed */ {
|
|
253
|
+
let plain = NameAnalyzer.plainNameOf(this.of);
|
|
245
254
|
|
|
246
|
-
|
|
255
|
+
if (this.isMethodTest) {
|
|
256
|
+
return `${ plain }()`;
|
|
257
|
+
}
|
|
247
258
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
this.spoofed = spoofed; // .plus
|
|
252
|
-
this.initors = initors; // .with
|
|
253
|
-
this.settables = settables; // .amid
|
|
254
|
-
this.method = method; // .of
|
|
255
|
-
this.inputs = inputs; // .in
|
|
256
|
-
this.output = output; // .out
|
|
257
|
-
this.source = source; // .from
|
|
258
|
-
this.factors = factors; // .and
|
|
259
|
+
if (this.isPropertyTest) {
|
|
260
|
+
return `.${ plain }`;
|
|
261
|
+
}
|
|
259
262
|
}
|
|
260
263
|
|
|
261
|
-
|
|
262
|
-
// Empty initial copy.
|
|
263
|
-
let copy = new TestDefinition();
|
|
264
|
+
// endregion Def state
|
|
264
265
|
|
|
265
|
-
|
|
266
|
+
// endregion Properties
|
|
266
267
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
// region Def state methods
|
|
269
|
+
|
|
270
|
+
/* Needed externally, and dependency
|
|
271
|
+
of all .and-based properties. */
|
|
272
|
+
andStringContains(keyword) /* passed */ {
|
|
273
|
+
let doesContain
|
|
274
|
+
= typeof this.and === "string"
|
|
275
|
+
&& this.and.includes(keyword);
|
|
276
|
+
|
|
277
|
+
return doesContain;
|
|
272
278
|
}
|
|
273
279
|
|
|
274
|
-
|
|
280
|
+
// endregion Def state methods
|
|
281
|
+
|
|
282
|
+
// region Initing, including constructor()
|
|
283
|
+
|
|
284
|
+
/* Constructor can't use parameter names like `for`:
|
|
285
|
+
when not .-prefixed, they are purely keywords. */
|
|
286
|
+
constructor(nature, type, spoofed, initors, method, inputs, output, source, factors, enact, counteract) /* ok */ {
|
|
287
|
+
this.nature = nature; // .for
|
|
288
|
+
this.type = type; // .on
|
|
289
|
+
this.spoofed = spoofed; // .plus
|
|
290
|
+
this.initors = initors; // .with
|
|
291
|
+
this.method = method; // .of
|
|
292
|
+
this.inputs = inputs; // .in
|
|
293
|
+
this.output = output; // .out
|
|
294
|
+
this.source = source; // .from
|
|
295
|
+
this.factors = factors; // .and
|
|
296
|
+
this.enact = enact; // .do
|
|
297
|
+
this.counteract = counteract; // .undo
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static fromNonceTuples(nonces) /* passed */ {
|
|
275
301
|
// Throughput and output.
|
|
276
|
-
let full = new
|
|
277
|
-
let
|
|
302
|
+
let full = new TestDef();
|
|
303
|
+
let defs = [];
|
|
278
304
|
|
|
279
305
|
// Looping over all.
|
|
280
306
|
for (let nonce of nonces) {
|
|
281
307
|
// Get latest test definition.
|
|
282
|
-
let latest =
|
|
308
|
+
let latest = TestDef.fromNonceTuple(nonce);
|
|
283
309
|
|
|
284
310
|
// Restarting test definitions when desired.
|
|
285
|
-
full =
|
|
311
|
+
full = TestDef.maybeRestartFull(full, latest);
|
|
286
312
|
|
|
287
313
|
// Merge any previous
|
|
288
314
|
// values into latest.
|
|
289
|
-
|
|
315
|
+
TestDef.combine(latest, full);
|
|
290
316
|
|
|
291
317
|
// Make latest the tuple for
|
|
292
318
|
// combining with next time.
|
|
293
319
|
full = latest;
|
|
294
320
|
|
|
321
|
+
// Changes to the current def, rather than
|
|
322
|
+
// a new one, should not result in a new def.
|
|
323
|
+
if (TestDef.isChangeOnlyNonce(nonce)) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
|
|
295
327
|
// Add latest, if it's ready to run as a test.
|
|
296
328
|
if (latest.isRunnable) {
|
|
297
|
-
|
|
329
|
+
defs.push(latest);
|
|
298
330
|
}
|
|
299
331
|
}
|
|
300
332
|
|
|
301
333
|
// Back to caller.
|
|
302
|
-
return
|
|
334
|
+
return defs;
|
|
303
335
|
}
|
|
304
336
|
|
|
305
|
-
|
|
337
|
+
/* Transfers properties in 'nonce' to a new TestDef
|
|
338
|
+
if they match by either (first) short or long name.
|
|
339
|
+
Unmatched props remain undefined on the TestDef. */
|
|
340
|
+
static fromNonceTuple(nonce) /* passed */ {
|
|
306
341
|
// Empty, since properties can be set
|
|
307
342
|
// by either of two nonce naming styles.
|
|
308
|
-
let
|
|
343
|
+
let def = new TestDef();
|
|
309
344
|
|
|
310
|
-
let shortNames =
|
|
345
|
+
let shortNames = TestDef.longsByShort.keys();
|
|
311
346
|
|
|
312
347
|
// Traversing matching pairs of names and applying
|
|
313
348
|
// whichever one is present as the tuple property;
|
|
314
349
|
// if neither is present, the property is undefined.
|
|
315
350
|
for (let shortName of shortNames) {
|
|
316
|
-
let longName =
|
|
317
|
-
|
|
351
|
+
let longName = TestDef.longsByShort.get(shortName);
|
|
352
|
+
def[shortName] = shortName in nonce ? nonce[shortName] : nonce[longName];
|
|
318
353
|
}
|
|
319
354
|
|
|
320
355
|
// Back to caller.
|
|
321
|
-
return
|
|
356
|
+
return def;
|
|
322
357
|
}
|
|
323
358
|
|
|
324
359
|
// region Dependencies of nonce-tuple initing methods
|
|
325
360
|
|
|
326
|
-
|
|
361
|
+
/* Replaces some or all of the 'full' that gathers test
|
|
362
|
+
props for reuse when targeting changes significantly
|
|
363
|
+
in the middle of the collapsing-forward process. */
|
|
364
|
+
static maybeRestartFull(full, latest) /* passed */ {
|
|
327
365
|
// When a (new) model class is named,
|
|
328
366
|
// wipe out all reused test values.
|
|
329
367
|
if (latest.type !== undefined) {
|
|
330
|
-
full = new
|
|
368
|
+
full = new TestDef();
|
|
331
369
|
}
|
|
332
370
|
|
|
333
371
|
// When a (new) model method is named, wipe out reused
|
|
334
|
-
// test values except the general ones for its class
|
|
372
|
+
// test values except the general ones for its class
|
|
373
|
+
// and .nature, needed for collapsing forward.
|
|
335
374
|
if (latest.method !== undefined) {
|
|
336
|
-
full =
|
|
337
|
-
full.nature, full.type,
|
|
338
|
-
full.spoofed, full.initors
|
|
339
|
-
);
|
|
375
|
+
full = TestDef.classOnlyDefFrom(full);
|
|
340
376
|
}
|
|
341
377
|
|
|
342
378
|
return full;
|
|
343
379
|
}
|
|
344
380
|
|
|
345
|
-
|
|
346
|
-
let
|
|
381
|
+
static classOnlyDefFrom(original) /* passed */ {
|
|
382
|
+
let output = new TestDef();
|
|
383
|
+
|
|
384
|
+
output.type = original.type;
|
|
385
|
+
output.initors = original.initors;
|
|
386
|
+
output.spoofed = original.spoofed;
|
|
387
|
+
|
|
388
|
+
return output;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* Replaces properties of the 'self'
|
|
392
|
+
TestDef with any from 'other'. */
|
|
393
|
+
static combine(self, other) /* passed */ {
|
|
394
|
+
let shortNames = TestDef.longsByShort.keys();
|
|
347
395
|
|
|
348
396
|
// Collapse properties forward.
|
|
349
397
|
for (let shortName of shortNames) {
|
|
350
|
-
|
|
398
|
+
TestDef.combineValues(self, other, shortName);
|
|
351
399
|
}
|
|
352
400
|
}
|
|
353
401
|
|
|
354
|
-
static
|
|
402
|
+
static isChangeOnlyNonce(nonce) /* passed */ {
|
|
403
|
+
return nonce.just !== undefined || nonce.only !== undefined;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/* Replaces the named property of 'self', if
|
|
407
|
+
missing, with any new property of 'other'. */
|
|
408
|
+
static combineValues(self, other, name) /* passed */ {
|
|
355
409
|
// Property may still end up undefined.
|
|
356
410
|
if (self[name] === undefined) {
|
|
357
411
|
self[name] = other[name];
|
|
@@ -362,12 +416,4 @@ export class TestDefinition {
|
|
|
362
416
|
|
|
363
417
|
// endregion Initing, including constructor()
|
|
364
418
|
|
|
365
|
-
// region Other statics
|
|
366
|
-
|
|
367
|
-
static plainNameOf(name) /* passed */ {
|
|
368
|
-
let plain = name.replaceAll(TestDefinition.operatorsRegExp, "");
|
|
369
|
-
return plain;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// endregion Other statics
|
|
373
419
|
}
|
package/system/TestFinder.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
/* TestFinder is an ATestFinder that finds tests in the places identified in package.json. */
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import ATestFinder from "./ATestFinder.js";
|
|
6
|
+
import ATestSource from "./ATestSource.js";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
9
|
import { minimatch } from "minimatch";
|
|
10
10
|
|
|
11
|
-
export class TestFinder extends ATestFinder {
|
|
11
|
+
export default class TestFinder extends ATestFinder {
|
|
12
12
|
// region Definitions
|
|
13
13
|
|
|
14
14
|
static NO_SUCH_FILE = "ENOENT";
|
package/system/TestFrame.js
CHANGED
|
@@ -1,95 +1,58 @@
|
|
|
1
1
|
/**/
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import TestStages from "./TestStages.js";
|
|
4
4
|
|
|
5
|
-
export class TestFrame {
|
|
6
|
-
/* &cruft, when TestStages is ready, use it and its methods here */
|
|
7
|
-
|
|
5
|
+
export default class TestFrame {
|
|
8
6
|
#stages;
|
|
9
7
|
|
|
10
|
-
constructor() {
|
|
8
|
+
constructor() /* ok */ {
|
|
11
9
|
// A TestStages is inited for each test.
|
|
12
10
|
this.#stages = new TestStages();
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
/* &cruft, removing logging after it's no longer needed */
|
|
17
|
-
// console.log(`cruft : a`);
|
|
18
|
-
|
|
13
|
+
run(test) /* passed */ {
|
|
19
14
|
// Outer try for fails of groundwork requested.
|
|
20
15
|
try {
|
|
21
|
-
//
|
|
22
|
-
|
|
23
|
-
// Spoofing, setting static properties, and so on.
|
|
16
|
+
// Spoofing and so on.
|
|
24
17
|
this.#stages.anyPreTargetingGroundwork(test);
|
|
25
18
|
|
|
26
|
-
// console.log(`cruft : c`);
|
|
27
|
-
|
|
28
19
|
// Target may be instance, prototype for constructors, the class
|
|
29
20
|
// itself for statics, or nonce for properties. Sets test.target.
|
|
30
21
|
this.#stages.setTarget(test);
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
|
|
23
|
+
let target = this.#stages.supplyLocalTarget(test);
|
|
24
|
+
|
|
34
25
|
// Method under test may be on instance, class,
|
|
35
26
|
// or nonce for properties. Sets test.callable.
|
|
36
|
-
this.#stages.
|
|
27
|
+
let callable = this.#stages.supplyCallableName(test);
|
|
37
28
|
|
|
38
|
-
//
|
|
39
|
-
|
|
40
|
-
// Setting instance properties and so on.
|
|
29
|
+
// Setting (spoofing) properties and so on.
|
|
41
30
|
this.#stages.anyPostTargetingGroundwork(test);
|
|
42
31
|
|
|
43
|
-
// console.log(`cruft : f`);
|
|
44
|
-
|
|
45
32
|
// Inner try for fails of targeted code only.
|
|
46
33
|
try {
|
|
47
|
-
// console.log(`cruft : g`);
|
|
48
|
-
|
|
49
|
-
// console.log(`cruft : test.actual:`, test.actual);
|
|
50
|
-
// console.log(`cruft : test.target:`, test.target);
|
|
51
|
-
// console.log(`cruft : test.localCallable:`, test.localCallable);
|
|
52
|
-
// console.log(`cruft : test.in:`, test.in);
|
|
53
|
-
|
|
54
34
|
// Tests usually look for this.
|
|
55
|
-
test.actual =
|
|
56
|
-
|
|
57
|
-
// console.log(`cruft : test.actual:`, test.actual);
|
|
58
|
-
// console.log(`cruft : h`);
|
|
35
|
+
test.actual = target[callable](...test.in);
|
|
59
36
|
}
|
|
60
37
|
catch (thrown) {
|
|
61
|
-
// console.log(`cruft : i`);
|
|
62
|
-
|
|
63
38
|
// Sometimes tests look for this.
|
|
64
39
|
test.thrown = thrown;
|
|
65
|
-
|
|
66
|
-
// console.log(`cruft : j`);
|
|
67
40
|
}
|
|
68
41
|
|
|
69
|
-
// console.log(`cruft : k`);
|
|
70
|
-
|
|
71
42
|
// Sometimes tests look for results elsewhere.
|
|
72
43
|
this.#stages.anyModifyActual(test);
|
|
73
44
|
|
|
74
|
-
// console.log(`cruft : l`);
|
|
75
|
-
|
|
76
45
|
// Actually testing the result.
|
|
77
46
|
test.didPass = this.#stages.compareResults(test.output, test.actual);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// console.log(`cruft : m`);
|
|
47
|
+
}
|
|
48
|
+
catch (thrown) {
|
|
49
|
+
/* Block needed, but no operations. */
|
|
83
50
|
}
|
|
84
51
|
finally {
|
|
85
|
-
// console.log(`cruft : n`);
|
|
86
|
-
|
|
87
52
|
// Undoing any groundwork changes made.
|
|
88
|
-
this.#stages.
|
|
89
|
-
|
|
90
|
-
// console.log(`cruft : o`);
|
|
53
|
+
this.#stages.anyGroundworkReversal(test);
|
|
91
54
|
}
|
|
92
55
|
|
|
93
|
-
// console.log(`cruft :
|
|
56
|
+
// console.log(`cruft : q, outer try-catch : after`);
|
|
94
57
|
}
|
|
95
58
|
}
|
package/system/TestGroup.js
CHANGED