risei 1.2.0 → 1.3.0

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  ## What Risei is
5
5
 
6
6
  **Risei is a new way to write unit tests that allows you to:**
7
- * Whip up full test coverage of object-oriented or object-hosted JavaScript in no time.
7
+ * Whip up full test coverage of object-oriented or object-hosted JavaScript and TypeScript in no time.
8
8
  * Refactor or replace existing designs without worrying about the cost in past or future test time.
9
9
  * Create tests with immediate confidence, because you can't introduce mistakes in test code you write.
10
10
 
@@ -41,7 +41,11 @@ Test runs also feature a title bar at the top, as well as a summary bar at the b
41
41
 
42
42
  ## Using Risei
43
43
 
44
- Risei is under active development.  If you've been here before, check out [what's new in Risei](#whats-new-in-risei) for the latest.  Also see [known bugs and workarounds](#known-bugs-and-workarounds) and [limitations in Risei](#limitations-in-risei).
44
+ Risei is under active development.  If you've been here before, check out [what's new in Risei](#whats-new-in-risei) for the latest.  Also see [known issues and workarounds](#known-issues-and-workarounds) and [limitations in Risei](#limitations-in-risei).
45
+
46
+ There are a few additional or different steps for [using Typescript with Risei](#using-typescript-with-risei).
47
+
48
+
45
49
 
46
50
  ### Installation
47
51
 
@@ -65,6 +69,8 @@ And add Risei's metadata to `package.json`:
65
69
  }
66
70
  ```
67
71
 
72
+ Just a [few extra steps](#using-typescript-with-risei) are required for Risei to work with TypeScript.
73
+
68
74
 
69
75
 
70
76
  ### Siting tests
@@ -117,13 +123,15 @@ You can save a lot of time by putting repeated test properties into an object on
117
123
  { of: "countOf", for: "Returns the number present.", in: [ "b" ], out: 2 }
118
124
  ```
119
125
 
120
- This _collapsing forward_ works for just about every test property, but is reset when you change the class in `.on`, when you give the property a new value, or you erase it with an empty array `[ ]`.
126
+ - This _collapsing forward_ works for just about every test property, but is reset when you change the class in `.on`, when you give the property a new value, or you erase it with an empty array `[ ]`.
127
+
128
+ - Collapsing forward doesn't reduce test isolation — for instance, with mutable args — because Risei always runs a copy of the test definition, not the original.
121
129
 
122
130
 
123
131
 
124
132
  #### Spoof away code dependencies:
125
133
 
126
- When your code has dependencies on other code, just _spoof_ the results of that code to get what your test needs from it, using a `.plus` property on your tests that offers many options:
134
+ When your tests need certain results from code dependencies, just _spoof_ what you want using a `.plus` test property:
127
135
 
128
136
  ```javascript
129
137
  { on: CombinerClass, with: [ ],
@@ -145,7 +153,9 @@ When your code has dependencies on other code, just _spoof_ the results of that
145
153
  in: [ "green" ], out: [ 7, 8, 9, 10, 10, 11, 12, { color: "green" } ] }
146
154
  ```
147
155
 
148
- These are basically all varieties of spoofing.  Spoofing collapses forward across tests, but not across the elements within `.plus`.
156
+ - Spoofing collapses forward across tests, but not across the elements within `.plus`.
157
+
158
+ - Spoofing is also fully isolated within tests.
149
159
 
150
160
 
151
161
 
@@ -171,15 +181,15 @@ And then run that script:
171
181
  npm test
172
182
  ```
173
183
 
174
- Risei can be used alongside other test frameworks.  You might run them all from the same test script, or perhaps write unique scripts for each.
184
+ Risei can be used alongside other test frameworks, and even run with them from the same test script if you want.
175
185
 
176
186
 
177
187
 
178
188
  ### Learning more about Risei
179
189
 
180
- Be sure to read through the rest of this doc to learn more about Risei's many capabilities, and about where Risei is headed.
190
+ Read through the rest of this doc to learn more about Risei's many capabilities, and about where Risei is headed.
181
191
 
182
- - For instance, learn about using `.and` to test static code or throws.
192
+ - For instance, learn about using `.and` to test static methods or throws.
183
193
  - Or learn about using `.from` to test property results or other state.
184
194
  - Don't miss out:  Once you've tried the basics, read the rest...!
185
195
 
@@ -188,6 +198,11 @@ Be sure to read through the rest of this doc to learn more about Risei's many ca
188
198
 
189
199
  ## Risei in depth
190
200
 
201
+ <details>
202
+ <summary>
203
+ There's plenty more to learn about Risei and how it makes testing easy...
204
+ </summary>
205
+
191
206
  ### Installation
192
207
 
193
208
  - You can use any file extension you want in Risei's metadata in `package.json`, and Risei will scan those files for tests.
@@ -211,6 +226,7 @@ Be sure to read through the rest of this doc to learn more about Risei's many ca
211
226
  - The order and placement of test properties doesn't matter, although the order seen in the examples is probably most readable.
212
227
 
213
228
 
229
+
214
230
  #### Basic test properties and options for each:
215
231
 
216
232
  | Name | Contents |
@@ -226,25 +242,22 @@ Be sure to read through the rest of this doc to learn more about Risei's many ca
226
242
  - The property names were chosen to be easy to remember and type, but longer alternatives are available, covered later.
227
243
 
228
244
 
229
- </details>
230
-
231
245
 
232
246
  ### Test-property reuse _AKA_ Collapsing forward
233
247
 
234
248
  - To save time and effort, any property you write is collapsed forward to subsequent tests unless you replace it or erase it with an empty array `[ ]`.
235
249
  - Property values are gathered across partial test objects until they add up to a runnable test, which is then run.
236
250
  - Changes to properties are combined with previous ones to produce intended new tests.
237
- - For a rare and avoidable side-effect of this system, see [Known bugs and workarounds](#known-bugs-and-workarounds).
251
+ - For a rare and avoidable side-effect of this system, see [known issues and workarounds](#known-issues-and-workarounds).
238
252
 
239
253
  - Test contents, reused or not, are automatically reset when it makes the most sense:
240
254
  - Changing the tested class in `.on` wipes out all prior test properties, so the new class has a fresh start.
241
255
  - Changing the tested method in `.of` wipes out only test properties related to methods, to preserve class values you usually want.
242
256
 
257
+ - Individual tests remain fully isolated:
258
+ - Test args, including objects and functions in `.with`, `.plus`, and `.in`, are all copied for running in each test, so nothing is reused across tests.
259
+ - Class instances, spoofs (covered later), and so on are all created anew for each test.
243
260
 
244
- - Individual tests remain isolated because class instances, spoofed methods (covered later) and so on are all created anew for each test.
245
- - However, input (`.in`) and instantiation (`.with`) arguments that are mutated by tested code are not yet isolated.
246
- - They will be fully isolated in a future release.
247
- - In the meantime, calling a function to supply them to `.in` or `.with` does isolate them completely.
248
261
 
249
262
 
250
263
  ### Choosing test-only dependency inputs _AKA_ Spoofing
@@ -257,6 +270,7 @@ Be sure to read through the rest of this doc to learn more about Risei's many ca
257
270
  - All classes whose members are being spoofed have to be imported.
258
271
 
259
272
 
273
+
260
274
  #### Spoof-definition properties:
261
275
 
262
276
  | Name | Necessary or Optional | Contents |
@@ -342,7 +356,7 @@ To test a value that isn't the exercised code's return value, you use `.out` nor
342
356
 
343
357
 
344
358
  - Getting properties, mutated args, and other non-return values is known as _retrieving_.
345
- - Retrieving definitions collapse forward across tests unless replaced with new definitions, or erased by setting `.from` to an empty array `[ ]`.
359
+ - Retrieving definitions collapse forward across tests unless replaced with new definitions, or erased by setting `.from` to an empty array `[ ]`.
346
360
 
347
361
 
348
362
  <details>
@@ -446,9 +460,72 @@ Constructors can be tested with no special test properties or keywords.
446
460
  - Any `.with` args are completely ignored for a constructor test.&nbsp; Only those in the test's `.in` property are used.
447
461
  - However, a `.with` must still be provided.&nbsp; It can simply be an empty array `[ ]`.
448
462
 
463
+ </details>
464
+
465
+
466
+
467
+
468
+ ## Using TypeScript with Risei
469
+
470
+ Testing TypeScript code with Risei basically just means transpiling before running the tests, and being sure to point to its output JS files, not the TS ones.
471
+
472
+ - Anything beyond those basics is intended to keep JS files separate from TS files and the output of web frameworks' own, complex build processes.
473
+
474
+ If you follow the general Risei set-up, you can just make the following few modifications for TypeScript applications.
475
+ - These steps have worked with both Angular and React.
476
+ - Variant approaches are also sure to work, depending on the other technical choices in play.
477
+
449
478
 
450
479
 
451
- ### Limitations in Risei
480
+ ### In `package.json`:
481
+
482
+ Add transpilation and deletion operations to the `test` script, with each operation conditional on completion of the preceding one:
483
+
484
+ ```json
485
+ "scripts": {
486
+ "test": "tsc && node ./node_modules/risei/index.js && rm -r ./dist/out-tsc"
487
+ }
488
+ ```
489
+
490
+ - Generally, you should use `tsc` or another plain transpiler, not web frameworks' complex processes with single output files.
491
+ - Deleting the files at the end prevents interference with web frameworks' bundling.
492
+ - The deletion path must match the `outDir` in `tsconfig.json`.
493
+
494
+ > You can run Risei manually with the same sequence of operations.
495
+
496
+
497
+
498
+ ### In `tsconfig.json`:
499
+
500
+ You set up the transpiler to output files to a directory with these settings:
501
+
502
+ ```json
503
+ {
504
+ "outDir": "dist/out-tsc",
505
+ "noEmit": false
506
+ }
507
+ ```
508
+
509
+ - The `outDir` can be any location.&nbsp; It's best not to just use `dist`, where adding or deleting files may interfere with web frameworks' build steps.
510
+ - These settings are normally not near each other in the file (as seen here).
511
+ - You can also set the `target` to `es6` or higher, although Risei works fine with ES5.
512
+
513
+
514
+
515
+
516
+ ### In test files:
517
+
518
+ All `import` statements have to point to the `outDir` path or subfolders there, using relative-path syntax:
519
+
520
+ ```javascript
521
+ import { TestedClass } from "../../dist/out-tsc/SubPath/TestedClass.js";
522
+ ```
523
+
524
+ - Output files may be in a folder tree parallel to the originals (Angular), or may all be in the `outDir` folder itself (React).
525
+
526
+
527
+
528
+ ## Limitations in Risei
452
529
 
453
530
  The following are not supported at present:
454
531
  - Use of `async` syntax
@@ -468,52 +545,42 @@ Some of these are on the tentative future-development list.&nbsp; In the meanti
468
545
 
469
546
  Most problems with using Risei are minor mistakes in syntax, or omissions in test definitions:
470
547
 
471
- | Error condition or text | Probable cause / fix |
472
- |-----------------------------------|----------------------------------------------------------------|
473
- | Sudden drop in the number of tests run | An error occurred in a test file; error output at the top of the test run explains why |
474
- | `"Test loading failed for... SyntaxError: Unexpected token ':'"` | Missing comma in your tests in the named file |
475
- | `"Test loading failed for... SyntaxError: Unexpected token '.'"` | Using `this.tests = []` instead of `tests = []` in the file named |
476
- | Other `... Unexpected token ...` errors | Some other syntax error in the file named, most likely a missing or extra delimiter |
477
- | Unexpected actual values, or unexpected passes / fails in test runs | Spoofs, retrievals, or special conditions from previous tests not replaced or reset with `[ ]`<br>&mdash; or &mdash;<br>Tested method mutates `.in` or `.with` args: preventable by using a function to supply those args<br>&mdash; or &mdash;<br>Pre-listed test properties produce extra tests: preventable by restating class in `.on` |
548
+ | Error condition or text | Probable cause / fix |
549
+ |---------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
550
+ | Gold bar appears below the summary, and the number of tests run drops | A syntax error caused a test file not to load; error output in the gold bar explains why |
551
+ | `"Test loading failed for... SyntaxError: Unexpected token ':'"` | Missing comma in your tests in the named file |
552
+ | `"Test loading failed for... SyntaxError: Unexpected token '.'"` | Using `this.tests = []` instead of `tests = []` in the file named |
553
+ | Other `... Unexpected token ...` errors | Some other syntax error in the file named, most likely a missing or extra delimiter |
554
+ | Unexpected actual values, or unexpected passes / fails in test runs | Spoofs, retrievals, or special conditions from previous tests not replaced or reset with `[ ]`<br>&mdash; or &mdash;<br>Pre-listed test properties produce extra tests: preventable by restating class in `.on` |
478
555
 
479
556
 
480
557
 
481
558
 
482
- ## Known bugs and workarounds
559
+ ## Known issues and workarounds
483
560
 
484
- One known bug exists:
485
- - When the args stated in `.with` or `.in` are mutated by the method under test (or by anything done within a test), the mutated values are carried forward to other tests.
486
- - A workaround exists for now: just provide those args using a fixture function when they may be mutated.&nbsp; The function is called each time, isolating them completely.
561
+ - No bugs are known to exist at present.
487
562
 
563
+ - One unexpected result is known to exist:
564
+ - Changing one or more properties in objects by themselves in the middle of tests (perhaps to emphasize them) can create extra tests.
565
+ - The extra tests usually fail, because they have an unintended mix of old and new properties.
566
+ - In this case, Rs is actually working properly, running prior tests with the new properties swapped in.
567
+ - To avoid this problem, include changed properties in full tests to run, or restate `.of` along with the changed properties.
488
568
 
489
- - This problem with test isolation is being fixed in an upcoming release.
490
-
491
-
492
- One known unexpected result (not quite a bug) exists:
493
- - Because test properties collapse forward to form whole tests, pre-stating new properties for upcoming tests without changing `.on` is treated as a new test like prior ones, with just those properties changed.
494
- - Pre-stating properties might be done as a way to make them stand out when reading through the tests.
495
-
496
- - This means you see an extra unexpected test that most likely fails, due to the mix of old and new properties.
497
-
498
- - A workaround exists: if you pre-state new properties, also restate the class under test in `.on`, which erases all prior test properties.
499
- - Restating `.on` doesn't cause the class name to be displayed again in output.
500
-
501
-
502
- - This output is rarely an issue, and may be what is wanted in some cases, but options for preventing it are being considered.
569
+ - This situation is rarely an issue, but ways to optionally prevent it are being considered.
503
570
 
504
571
 
505
572
 
506
573
  ## What's new in Risei
507
574
 
508
- - Release **1.2.0** (January, 2024) changes sorting of test files.&nbsp; Previously they were displayed in the order found.&nbsp; Now the last-edited file is moved to the bottom, making it easy to see the latest test results.
575
+ - Release **1.3.0** (February, 2024) moves the display of test-loading error messages to a new gold bar that appears at the bottom of the summary when there are any loading errors.&nbsp; A sorting error that occurs when no test files exist yet has also been fixed.
509
576
 
577
+ - Release **1.2.0** (January, 2024) changes sorting of test files.&nbsp; Previously they were displayed in the order found.&nbsp; Now the order remains the same, except that the last-edited file is moved to the bottom, making it easy to see the latest test results.
510
578
 
511
579
  - Release **1.1.2** of Risei (January, 2024) fixes two problems:
512
580
  - Classes were sometimes displayed in output as their entire definition.&nbsp; Now just the class name is displayed.
513
581
  - All `Date` instances were considered equal, regardless of their actual value.&nbsp; Now they only are considered equal when they actually are.
514
582
 
515
-
516
- > Don't use release **1.1.1**, which contains an internal path error.
583
+ - Don't use release **1.1.1**, which contains an internal path error.
517
584
 
518
585
 
519
586
 
@@ -534,7 +601,7 @@ Risei is published for use under the terms of the MIT license:
534
601
 
535
602
  <div style="border: solid darkgray 1px; padding: 0.5rem;">
536
603
 
537
- <b>Risei Copyright &copy; 2023 Ed Fallin</b>
604
+ <b>Risei Copyright &copy; 2023&ndash;2024 Ed Fallin</b>
538
605
 
539
606
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
540
607
 
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**/
2
2
 
3
- /* Copyright (c) 2023 Ed Fallin. Published under the terms of the MIT license. */
3
+ /* Copyright (c) 2023-2024 Ed Fallin. Published under the terms of the MIT license. */
4
4
 
5
5
  /* This index.js is the entry point for running Risei tests from
6
6
  other code. It imports other modules to perform its work.
@@ -47,6 +47,7 @@ export * from "./system/ATestReporter.js";
47
47
 
48
48
  /* Display styles for the start title and other general needs. */
49
49
  const title = chalk.hex("FFFFFF").bgHex("191970").bold;
50
+ const fails = chalk.hex("000000").bgHex("FFD700").bold;
50
51
 
51
52
  // endregion Named styles
52
53
 
@@ -61,7 +62,7 @@ let wide = (text) => {
61
62
 
62
63
  // endregion Styling for color stripes
63
64
 
64
- // region Key callable, its scriptable call, and its export
65
+ // region Key callable, its scripted call, and its export
65
66
 
66
67
  async function runRiseiTests(testFinderPath) {
67
68
  // region Converting test-finder from path to class
@@ -90,7 +91,7 @@ async function runRiseiTests(testFinderPath) {
90
91
  console.log();
91
92
 
92
93
  // endregion Intro / title
93
-
94
+
94
95
  // region Running tests
95
96
 
96
97
  // Test-system objects and their relationships.
@@ -104,7 +105,19 @@ async function runRiseiTests(testFinderPath) {
104
105
  await caller.runAllTests();
105
106
 
106
107
  // endregion Running tests
107
-
108
+
109
+ // region Trailing display of test-loading issues
110
+
111
+ if (finder.thrown.length !== 0) {
112
+ let loadFails = finder.thrown;
113
+
114
+ for (let fail of loadFails) {
115
+ console.log(fails(wide(` ${ fail }`)));
116
+ }
117
+ }
118
+
119
+ // endregion Trailing display of test-loading issues
120
+
108
121
  // region Trailing formatting
109
122
 
110
123
  console.log();
@@ -118,5 +131,5 @@ await runRiseiTests();
118
131
 
119
132
  export default runRiseiTests;
120
133
 
121
- // endregion Key callable, its scriptable call, and its export
134
+ // endregion Key callable, its scripted call, and its export
122
135
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "risei",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Risei is the framework that allows you to write unit tests as collections of values in JavaScript objects, so it's easy and fast, and tests don't serve as a drag on redesigns.",
5
5
  "keywords": [
6
6
  "unit test",
@@ -28,8 +28,7 @@
28
28
  "test": "clear; node ./node_modules/risei/index.js"
29
29
  },
30
30
  "risei": {
31
- "tests": "**.rt.js",
32
- "sort": "normal"
31
+ "tests": "**.rt.js"
33
32
  },
34
33
  "exports": {
35
34
  ".": "./index.js",
@@ -49,6 +48,6 @@
49
48
  "fs": "^0.0.1-security",
50
49
  "mocha": "^10.0.0",
51
50
  "morgan": "~1.9.1",
52
- "risei": "1.1.2"
51
+ "risei": "1.2.0"
53
52
  }
54
53
  }
@@ -1,7 +1,7 @@
1
1
  /**/
2
2
 
3
3
  import { ATestFixture } from "./ATestFixture.js";
4
- import { SpoofTuple } from "./SpoofTuple.js";
4
+ import { SpoofDefinition } from "./SpoofDefinition.js";
5
5
 
6
6
  export class ASpoofingFixture extends ATestFixture {
7
7
  constructor(name, kind) {
@@ -25,8 +25,8 @@ export class ASpoofingFixture extends ATestFixture {
25
25
  // Recursive case: Spoof defines a whole object
26
26
  // tree to be returned as method output.
27
27
  if (Array.isArray(spoofOutput)) {
28
- if (spoofOutput.every(x => SpoofTuple.isASpoof(x))) {
29
- spoofOutput = SpoofTuple.fromNonceTuples(spoofOutput);
28
+ if (spoofOutput.every(x => SpoofDefinition.isASpoof(x))) {
29
+ spoofOutput = SpoofDefinition.fromNonceTuples(spoofOutput);
30
30
  spoofOutput = this.spoofObjectTree(spoofOutput);
31
31
  }
32
32
  }
@@ -5,7 +5,14 @@
5
5
  import { ATestSource } from "./ATestSource.js";
6
6
 
7
7
  export class ATestFinder {
8
+ // region Fields
9
+
8
10
  #testSources;
11
+ #thrown = [];
12
+
13
+ // endregion Fields
14
+
15
+ // region Properties
9
16
 
10
17
  get testSources() {
11
18
  return this.#testSources;
@@ -15,6 +22,12 @@ export class ATestFinder {
15
22
  this.#testSources = value;
16
23
  }
17
24
 
25
+ get thrown() {
26
+ return this.#thrown;
27
+ }
28
+
29
+ // endregion Properties
30
+
18
31
  constructor() {
19
32
  this.#testSources = [];
20
33
  }
package/system/Risei.js CHANGED
@@ -1,14 +1,19 @@
1
1
  /**/
2
2
 
3
- /* Risei.js is the entry point for running Kitten / Koneko / Risei tests.
4
- It imports other modules to do all of its work. */
3
+ /* Copyright (c) 2023-2024 Ed Fallin. Published under the terms of the MIT license. */
4
+
5
+ /* This index.js is the entry point for running Risei tests from
6
+ other code. It imports other modules to perform its work.
7
+ It also exports modules that should / can be subclassed. */
8
+
9
+ // region Imports
5
10
 
6
11
  // region Test-running dependencies
7
12
 
8
13
  import { TestRunner } from "./TestRunner.js";
9
- import { ChosenTestFinder } from "./ChosenTestFinder.js";
10
14
  import { LocalCaller } from "./LocalCaller.js";
11
15
  import { TerminalReporter } from "./TerminalReporter.js";
16
+ import { TestFinder } from "./TestFinder.js";
12
17
 
13
18
  // endregion Test-running dependencies
14
19
 
@@ -19,19 +24,13 @@ import { Moment } from "./Moment.js";
19
24
 
20
25
  // endregion Display dependencies
21
26
 
27
+ // endregion Imports
28
+
22
29
  // region Named styles
23
30
 
24
31
  /* Display styles for the start title and other general needs. */
25
- const cal = chalk.hex("0000FF").bgHex("EEEE00").bold;
26
- const onBlue = chalk.bgBlueBright;
27
- const onGreen = chalk.bgGreenBright;
28
-
29
- const future = chalk.hex("FFFFFF").bgHex("191970").bold;
30
-
31
- /* Display styles for tests. */
32
- const group = chalk.hex("FFFFFF").bgHex("0000CD");
33
- const passed = chalk.hex("000000").bgHex("90EE90");
34
- const failed = chalk.hex("000000").bgHex("F08080");
32
+ const title = chalk.hex("FFFFFF").bgHex("191970").bold;
33
+ const fails = chalk.hex("000000").bgHex("FFD700").bold;
35
34
 
36
35
  // endregion Named styles
37
36
 
@@ -46,43 +45,74 @@ let wide = (text) => {
46
45
 
47
46
  // endregion Styling for color stripes
48
47
 
49
- // region Intro / title
50
-
51
- /* To clear the console first, you can include `clear;` in the script
52
- ahead of calling this, or else restore console.clear() here,
53
- although the Risei output may then overwrite some prior output. */
54
-
55
- console.log();
56
- console.log(future(wide()));
57
-
58
- let now = new Date();
59
- now = new Moment(now);
60
-
61
- console.log(future(wide(` Risei tests run on ${ now.asReadable() } local time.`)));
62
- console.log(future(wide()));
63
-
64
- console.log();
65
-
66
- // endregion Intro / title
67
-
68
- // region Running tests
69
-
70
- // Test-system objects and their relationships.
71
- const finder = new ChosenTestFinder();
72
- const runner = new TestRunner();
73
- const reporter = new TerminalReporter();
74
-
75
- const caller = new LocalCaller(finder, runner, reporter);
76
-
77
- // Actually running the tests using this system.
78
- await caller.runAllTests();
79
-
80
- // endregion Running tests
81
-
82
- // region Trailing formatting
83
-
84
- console.log();
85
- console.log();
86
-
87
- // endregion Trailing formatting
48
+ // region Key callable and its scripted call
49
+
50
+ async function runRiseiMetaTests(testFinderPath) {
51
+ // region Converting test-finder from path to class
52
+
53
+ testFinderPath = testFinderPath || "./TestFinder.js";
54
+ let finderModule = await import(testFinderPath);
55
+
56
+ let moduleKeys = Object.keys(finderModule);
57
+ let classKey = moduleKeys[0];
58
+ let finderClass = finderModule[classKey];
59
+
60
+ // endregion Converting test-finder from path to class
61
+
62
+ // region Intro / title
63
+
64
+ console.clear();
65
+ console.log();
66
+ console.log(title(wide()));
67
+
68
+ let now = new Date();
69
+ now = new Moment(now);
70
+
71
+ console.log(title(wide(` Risei tests run on ${ now.asReadable() } local time.`)));
72
+ console.log(title(wide()));
73
+
74
+ console.log();
75
+
76
+ // endregion Intro / title
77
+
78
+ // region Running tests
79
+
80
+ // Test-system objects and their relationships.
81
+ const finder = new finderClass.prototype.constructor();
82
+ finder.sourceBySearch = () => { return { tests: "**.outward-rt.js" }; };
83
+
84
+ const runner = new TestRunner();
85
+ const reporter = new TerminalReporter();
86
+
87
+ const caller = new LocalCaller(finder, runner, reporter);
88
+
89
+ // Actually running the tests using this system.
90
+ await caller.runAllTests();
91
+
92
+ // endregion Running tests
93
+
94
+ // region Trailing display of test-loading issues
95
+
96
+ if (finder.thrown.length !== 0) {
97
+ let loadFails = finder.thrown;
98
+
99
+ for (let fail of loadFails) {
100
+ console.log(fails(wide(` ${ fail }`)));
101
+ }
102
+ }
103
+
104
+ // endregion Trailing display of test-loading issues
105
+
106
+ // region Trailing formatting
107
+
108
+ console.log();
109
+ console.log();
110
+
111
+ // endregion Trailing formatting
112
+ }
113
+
114
+ /* Runs tests now. */
115
+ await runRiseiMetaTests();
116
+
117
+ // endregion Key callable and its scripted call
88
118
 
@@ -1,7 +1,7 @@
1
1
  /**/
2
2
 
3
3
  import { ASpoofingFixture } from "./ASpoofingFixture.js";
4
- import { SpoofTuple } from "./SpoofTuple.js";
4
+ import { SpoofDefinition } from "./SpoofDefinition.js";
5
5
 
6
6
  export class SpoofClassMethodsFixture extends ASpoofingFixture {
7
7
  /* Algorithm: Forward method spoof() looks at spoof definitions in .plus and applies them
@@ -53,10 +53,10 @@ export class SpoofClassMethodsFixture extends ASpoofingFixture {
53
53
  }
54
54
 
55
55
  // Converting to scope object type.
56
- let spoofTuples = SpoofTuple.fromNonceTuples(spoofNonces);
56
+ let spoofDefinitionss = SpoofDefinition.fromNonceTuples(spoofNonces);
57
57
 
58
58
  // Storing spoofing definitions.
59
- this.#retainSpoofsByClass(type, spoofTuples);
59
+ this.#retainSpoofsByClass(type, spoofDefinitionss);
60
60
 
61
61
  // Storing originals for restoring later.
62
62
  this.#reserveOriginalsByClass();
@@ -67,9 +67,9 @@ export class SpoofClassMethodsFixture extends ASpoofingFixture {
67
67
 
68
68
  // region Dependencies of spoof()
69
69
 
70
- #retainSpoofsByClass(type, spoofTuples) {
70
+ #retainSpoofsByClass(type, spoofDefinitionss) {
71
71
  // Map of Maps: by type, then by method.
72
- for (let tuple of spoofTuples) {
72
+ for (let tuple of spoofDefinitionss) {
73
73
  // If no .target, use `type`.
74
74
  if (!tuple.target) {
75
75
  tuple.target = type;