risei 1.0.4 → 1.1.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 +88 -46
- package/package.json +22 -8
- package/public/javascript/ASpoofingFixture.js +1 -1
- package/public/javascript/ChosenTestFinder.js +4 -3
- package/public/javascript/SpoofTuple.js +0 -1
- package/public/javascript/TerminalReporter.js +249 -222
- package/public/javascript/TestFrameChooser.js +95 -0
- package/public/javascript/TestFrames.js +180 -0
- package/public/javascript/TestRunner.js +37 -233
- package/public/javascript/TestTuple.js +13 -2
package/README.md
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
|
|
2
|
-
#
|
|
2
|
+
# Risei
|
|
3
3
|
|
|
4
|
-
## What
|
|
4
|
+
## What Risei is
|
|
5
5
|
|
|
6
|
-
**
|
|
6
|
+
**Risei is a new way to write unit tests that allows you to:**
|
|
7
7
|
* Whip up full test coverage of object-oriented or object-hosted JavaScript 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
|
|
|
11
|
-
|
|
11
|
+
Risei was originally known as _RiseiJs_. Risei is often referred to as **Rs** here for brevity.
|
|
12
12
|
|
|
13
|
-
### Basics of the RiseiJs approach
|
|
14
13
|
|
|
15
|
-
|
|
14
|
+
|
|
15
|
+
## Basics of the Risei approach
|
|
16
|
+
|
|
17
|
+
Risei replaces coded tests with simple declarative syntax that's far easier to draft than any other unit-testing approach.
|
|
16
18
|
|
|
17
19
|
Here are two example tests. `SortModel.countSort()` is being tested with the inputs found in `.in` and the expected output found in `.out`:
|
|
18
20
|
|
|
@@ -41,9 +43,10 @@ Test runs also feature a title bar, as well as a summary bar at the bottom:
|
|
|
41
43
|
</div>
|
|
42
44
|
|
|
43
45
|
|
|
44
|
-
## How to use RiseiJs
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
## How to install Risei
|
|
48
|
+
|
|
49
|
+
1. Install Risei the usual way for a development-time `npm` package:
|
|
47
50
|
|
|
48
51
|
<div style="padding-left: 1.5rem;">
|
|
49
52
|
|
|
@@ -59,16 +62,16 @@ npm install --save-dev risei
|
|
|
59
62
|
</summary>
|
|
60
63
|
<br>
|
|
61
64
|
|
|
62
|
-
-
|
|
63
|
-
- Although ESM is usable with older Node versions using external workarounds, a modern version is highly recommended, and
|
|
64
|
-
- You can install
|
|
65
|
-
-
|
|
65
|
+
- Risei is an `npm` package that uses ESM syntax. It only works well with modern versions of Node that automatically support ESM.
|
|
66
|
+
- Although ESM is usable with older Node versions using external workarounds, a modern version is highly recommended, and Rs is not guaranteed to work with older versions.
|
|
67
|
+
- You can install Rs as a regular dependency if you want, using `npm install risei`, but ordinarily this doesn't make sense, and exposing tests in production is generally considered a bad practice.
|
|
68
|
+
- Risei doesn't directly add any security risks to your code, but exposing tests that use it might (as it can with other test frameworks).
|
|
66
69
|
|
|
67
70
|
</details>
|
|
68
71
|
|
|
69
72
|
|
|
70
73
|
|
|
71
|
-
2. Add a `risei` node to your project's `package.json` to tell
|
|
74
|
+
2. Add a `risei` node to your project's `package.json` to tell Rs what kind of files to find tests in:
|
|
72
75
|
|
|
73
76
|
<div style="padding-left: 1.5rem;">
|
|
74
77
|
|
|
@@ -93,7 +96,9 @@ npm install --save-dev risei
|
|
|
93
96
|
|
|
94
97
|
|
|
95
98
|
|
|
96
|
-
|
|
99
|
+
## How to use Risei
|
|
100
|
+
|
|
101
|
+
1. Create test files with a `.rt.js` extension.
|
|
97
102
|
|
|
98
103
|
<details>
|
|
99
104
|
<summary>
|
|
@@ -107,7 +112,7 @@ npm install --save-dev risei
|
|
|
107
112
|
|
|
108
113
|
|
|
109
114
|
|
|
110
|
-
|
|
115
|
+
2. Import `ATestSource` from `risei/ATestSource` in each test file, subclass it, and set `tests` to an array of test definitions.
|
|
111
116
|
|
|
112
117
|
<div style="padding-left: 1.5rem;">
|
|
113
118
|
|
|
@@ -129,7 +134,7 @@ export TargetClassTests extends ATestSource {
|
|
|
129
134
|
<br>
|
|
130
135
|
|
|
131
136
|
- Tests must be placed in subclasses of `ATestSource`.
|
|
132
|
-
-
|
|
137
|
+
- Risei looks for this class relationship internally, so duck-typing does not work.
|
|
133
138
|
- You have to `import` the class/es being tested in the file/s containing their tests.
|
|
134
139
|
- Don't use ✗`this.tests` by accident — it just causes an exception when tests are run.
|
|
135
140
|
|
|
@@ -137,7 +142,7 @@ export TargetClassTests extends ATestSource {
|
|
|
137
142
|
|
|
138
143
|
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
3. Write each test as a JavaScript object literal in the array, using Risei's simple, light syntax:
|
|
141
146
|
|
|
142
147
|
<div style="padding-left: 1.5rem;">
|
|
143
148
|
|
|
@@ -183,7 +188,7 @@ export TargetClassTests extends ATestSource {
|
|
|
183
188
|
|
|
184
189
|
|
|
185
190
|
|
|
186
|
-
|
|
191
|
+
4. Write more tests with less syntax, by defining properties that are automatically reused in upcoming tests, and/or setting only the properties in a test that are different from the previous test/s:
|
|
187
192
|
|
|
188
193
|
<div style="padding-left: 1.5rem;">
|
|
189
194
|
|
|
@@ -221,7 +226,7 @@ export TargetClassTests extends ATestSource {
|
|
|
221
226
|
|
|
222
227
|
|
|
223
228
|
|
|
224
|
-
|
|
229
|
+
5. To isolate any tests with dependencies, you define test-only results for the methods depended on using _spoofing_, which is similar to mocks or fakes, but easier to use. Definitions for spoofs are set in the `.plus` property:
|
|
225
230
|
|
|
226
231
|
<div style="padding-left: 1.5rem;">
|
|
227
232
|
|
|
@@ -332,7 +337,9 @@ export TargetClassTests extends ATestSource {
|
|
|
332
337
|
|
|
333
338
|
|
|
334
339
|
|
|
335
|
-
|
|
340
|
+
## How to run Risei tests
|
|
341
|
+
|
|
342
|
+
1. Run your tests by invoking Risei's `index.js` file:
|
|
336
343
|
|
|
337
344
|
<div style="padding-left: 1.5rem;">
|
|
338
345
|
|
|
@@ -348,13 +355,13 @@ node ./node_modules/risei/index.js
|
|
|
348
355
|
</summary>
|
|
349
356
|
<br>
|
|
350
357
|
|
|
351
|
-
- At present,
|
|
358
|
+
- At present, Rs isn't set up as a script that runs independently, nor as a compiled executable, so you have to run it via its entry-point script.
|
|
352
359
|
|
|
353
360
|
</details>
|
|
354
361
|
|
|
355
362
|
|
|
356
363
|
|
|
357
|
-
|
|
364
|
+
2. Or write the `test` script in `package.json` to invoke `index.js`, to make your life easier:
|
|
358
365
|
|
|
359
366
|
<div style="padding-left: 1.5rem;">
|
|
360
367
|
|
|
@@ -371,7 +378,7 @@ node ./node_modules/risei/index.js
|
|
|
371
378
|
</summary>
|
|
372
379
|
<br>
|
|
373
380
|
|
|
374
|
-
- You can instead write a unique script for
|
|
381
|
+
- You can instead write a unique script for Rs, though this takes more syntax to call later:
|
|
375
382
|
|
|
376
383
|
<div style="padding-left: 1.5rem;">
|
|
377
384
|
|
|
@@ -383,7 +390,7 @@ node ./node_modules/risei/index.js
|
|
|
383
390
|
|
|
384
391
|
</div>
|
|
385
392
|
|
|
386
|
-
- You can define your test scripting to include the
|
|
393
|
+
- You can define your test scripting to include the Risei tests alongside other tests if you wish to mix framework usages, which may be appropriate for some scenarios:
|
|
387
394
|
|
|
388
395
|
<div style="padding-left: 1.5rem;">
|
|
389
396
|
|
|
@@ -400,7 +407,7 @@ node ./node_modules/risei/index.js
|
|
|
400
407
|
|
|
401
408
|
|
|
402
409
|
|
|
403
|
-
|
|
410
|
+
3. Run that script whenever you want to run tests:
|
|
404
411
|
|
|
405
412
|
<div style="padding-left: 1.5rem;">
|
|
406
413
|
|
|
@@ -430,16 +437,32 @@ npm run risei
|
|
|
430
437
|
|
|
431
438
|
|
|
432
439
|
|
|
433
|
-
## Advanced
|
|
440
|
+
## Advanced Risei usage
|
|
441
|
+
|
|
442
|
+
### Testing special test conditions with `.and`
|
|
443
|
+
|
|
444
|
+
You can use the special test property `.and`, always a string, to indicate special conditions that apply to your test. At present, the values available are `"static"` and `"throw"` / `"throws"` (either one works). You can list `static` and `throw` / `throws` together if needed, separated by a space.
|
|
445
|
+
|
|
446
|
+
<details>
|
|
447
|
+
<summary>
|
|
448
|
+
More information
|
|
449
|
+
</summary>
|
|
450
|
+
<br>
|
|
451
|
+
|
|
452
|
+
- The `.and` property is an expansion point for supporting more special conditions in the future. Values will always be listable together (as long as any particular grouping makes sense).
|
|
453
|
+
|
|
454
|
+
</details>
|
|
455
|
+
|
|
434
456
|
|
|
435
|
-
### Testing static methods
|
|
436
457
|
|
|
437
|
-
|
|
458
|
+
#### Testing static methods
|
|
459
|
+
|
|
460
|
+
To test a static method, use an `.and` of `"static"`:
|
|
438
461
|
|
|
439
462
|
<div style="padding-left: 1.5rem">
|
|
440
463
|
|
|
441
464
|
```javascript
|
|
442
|
-
{ on:
|
|
465
|
+
{ on: StaticTextProfileModel, with: [] },
|
|
443
466
|
|
|
444
467
|
{ of: "getTextProfile",
|
|
445
468
|
for: "Returns accurate profile of arg text.",
|
|
@@ -451,15 +474,27 @@ To test a static method, you add an `.and` property to a test, with the value `"
|
|
|
451
474
|
|
|
452
475
|
</div>
|
|
453
476
|
|
|
454
|
-
<details>
|
|
455
|
-
<summary>
|
|
456
|
-
More information
|
|
457
|
-
</summary>
|
|
458
|
-
<br>
|
|
459
477
|
|
|
460
|
-
- The `.and` property is an expansion point for supporting more unusual situations in the future. At present, it only supports static operations.
|
|
461
478
|
|
|
462
|
-
|
|
479
|
+
#### Testing throws
|
|
480
|
+
|
|
481
|
+
To test a throw, use an `.and` of `"throw"` or `"throws"`:
|
|
482
|
+
|
|
483
|
+
<div style="padding-left: 1.5rem">
|
|
484
|
+
|
|
485
|
+
```javascript
|
|
486
|
+
{ on: InstanceTextProfileModel, with: [] },
|
|
487
|
+
|
|
488
|
+
{ of: "getTextProfile",
|
|
489
|
+
for: "Throws with a helpful message when there is no arg text.",
|
|
490
|
+
and: "throws",
|
|
491
|
+
in: [ ],
|
|
492
|
+
out: "Could not build a profile. Did you forget to provide a text?"
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
</div>
|
|
497
|
+
|
|
463
498
|
|
|
464
499
|
|
|
465
500
|
### Testing object properties and other non-`return` results
|
|
@@ -540,6 +575,7 @@ When the contents of `.from` are a function, these are the two parameters:
|
|
|
540
575
|
</details>
|
|
541
576
|
|
|
542
577
|
|
|
578
|
+
|
|
543
579
|
### Property long names
|
|
544
580
|
|
|
545
581
|
Property names are short so they're easy to use. Some of them overlap with JavaScript keywords, but this causes no harm.
|
|
@@ -590,7 +626,8 @@ All test properties have long names that you can use instead of the short ones i
|
|
|
590
626
|
</details>
|
|
591
627
|
|
|
592
628
|
|
|
593
|
-
|
|
629
|
+
|
|
630
|
+
### Further capabilities of Risei
|
|
594
631
|
|
|
595
632
|
Constructors can be tested with no special test properties or keywords.
|
|
596
633
|
- The method name in `.of` is simply `"constructor"`.
|
|
@@ -598,7 +635,8 @@ Constructors can be tested with no special test properties or keywords.
|
|
|
598
635
|
- However, a `.with` must still be provided. It can simply be an empty array `[ ]`.
|
|
599
636
|
|
|
600
637
|
|
|
601
|
-
|
|
638
|
+
|
|
639
|
+
### Limitations in Risei
|
|
602
640
|
|
|
603
641
|
The following are not supported at present:
|
|
604
642
|
- Use of `async` syntax
|
|
@@ -607,9 +645,11 @@ The following are not supported at present:
|
|
|
607
645
|
- Spoofing mixes of properties and methods, such as `something.method.property.method`
|
|
608
646
|
- Debugging model code during tests.
|
|
609
647
|
|
|
648
|
+
|
|
649
|
+
|
|
610
650
|
## Troubleshooting
|
|
611
651
|
|
|
612
|
-
Most problems with using
|
|
652
|
+
Most problems with using Risei are minor mistakes in syntax, or omissions in test definitions:
|
|
613
653
|
|
|
614
654
|
| Error text | Probable cause / fix |
|
|
615
655
|
|---------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
|
|
@@ -621,22 +661,24 @@ Most problems with using RiseiJs are minor mistakes in syntax, or omissions in t
|
|
|
621
661
|
When something is wrong in one test file, other test files still usually load and run, so a good sign that there's a problem is a sudden decrease in the number of run tests reported.
|
|
622
662
|
|
|
623
663
|
|
|
624
|
-
## Who makes RiseiJs
|
|
625
664
|
|
|
626
|
-
|
|
665
|
+
## Who makes Risei
|
|
666
|
+
|
|
667
|
+
Risei is written by myself, Ed Fallin. I'm a longtime software developer who likes to find better ways to do things.
|
|
668
|
+
|
|
669
|
+
If you find Risei useful, consider spreading the word to other devs, making a donation, suggesting enhancements, or proposing sponsorships.
|
|
627
670
|
|
|
628
|
-
|
|
671
|
+
You can get in touch about Risei at **Riseimaker@gmail.com**.
|
|
629
672
|
|
|
630
|
-
You can get in touch about RiseiJs at **riseijsmaker@gmail.com**.
|
|
631
673
|
|
|
632
674
|
|
|
633
|
-
## What the
|
|
675
|
+
## What the Risei license is
|
|
634
676
|
|
|
635
|
-
|
|
677
|
+
Risei is published for use under the terms of the MIT license:
|
|
636
678
|
|
|
637
679
|
<div style="border: solid darkgray 1px; padding: 0.5rem;">
|
|
638
680
|
|
|
639
|
-
<b>
|
|
681
|
+
<b>Risei Copyright © 2023 Ed Fallin</b>
|
|
640
682
|
|
|
641
683
|
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:
|
|
642
684
|
|
package/package.json
CHANGED
|
@@ -1,23 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "risei",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "
|
|
5
|
-
"keywords": [
|
|
3
|
+
"version": "1.1.0",
|
|
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
|
+
"keywords": [
|
|
6
|
+
"unit test",
|
|
7
|
+
"test",
|
|
8
|
+
"unit testing",
|
|
9
|
+
"testing",
|
|
10
|
+
"easy",
|
|
11
|
+
"fast",
|
|
12
|
+
"simple",
|
|
13
|
+
"values",
|
|
14
|
+
"objects",
|
|
15
|
+
"declarative"
|
|
16
|
+
],
|
|
6
17
|
"author": "Ed Fallin <riseijsmaker@gmail.com>",
|
|
7
18
|
"license": "MIT",
|
|
8
19
|
"type": "module",
|
|
9
20
|
"private": false,
|
|
10
21
|
"scripts": {
|
|
11
22
|
"start": "node ./bin/www",
|
|
12
|
-
"
|
|
13
|
-
"rtest": "clear; node ./
|
|
23
|
+
"rself": "clear; node ./public/javascript/Risei.js",
|
|
24
|
+
"rtest": "clear; node ./node_modules/risei/index.js",
|
|
14
25
|
"xtest": "clear; mocha **/*.tests.js",
|
|
15
|
-
"
|
|
26
|
+
"mixedtest": "clear; mocha **/*.tests.js; node ./node_modules/risei/index.js",
|
|
27
|
+
"alltest": "clear; mocha **/*.tests.js; node ./node_modules/risei/index.js; node ./public/javascript/Risei.js",
|
|
28
|
+
"test": "clear; node ./node_modules/risei/index.js"
|
|
16
29
|
},
|
|
17
30
|
"risei": {
|
|
18
31
|
"tests": "**.rt.js"
|
|
19
32
|
},
|
|
20
|
-
"exports":{
|
|
33
|
+
"exports": {
|
|
21
34
|
".": "./index.js",
|
|
22
35
|
"./ATestSource": "./public/javascript/ATestSource.js"
|
|
23
36
|
},
|
|
@@ -34,6 +47,7 @@
|
|
|
34
47
|
"express": "~4.16.1",
|
|
35
48
|
"fs": "^0.0.1-security",
|
|
36
49
|
"mocha": "^10.0.0",
|
|
37
|
-
"morgan": "~1.9.1"
|
|
50
|
+
"morgan": "~1.9.1",
|
|
51
|
+
"risei": "^1.0.4"
|
|
38
52
|
}
|
|
39
53
|
}
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
/* ChosenTestFinder is an ATestFinder that finds tests in the places coded in its constructor. */
|
|
4
4
|
|
|
5
5
|
import { ATestFinder } from "./ATestFinder.js";
|
|
6
|
-
import {
|
|
7
|
-
import { SelfTests } from "./self-tests/SelfTests.rt.js";
|
|
6
|
+
import { TopicTests } from "./topic-tests/TopicTests.outward-rt.js";
|
|
7
|
+
import { SelfTests } from "./self-tests/SelfTests.outward-rt.js";
|
|
8
8
|
|
|
9
9
|
export class ChosenTestFinder extends ATestFinder {
|
|
10
10
|
constructor() {
|
|
11
11
|
super();
|
|
12
12
|
|
|
13
|
-
let testSource = new
|
|
13
|
+
let testSource = new TopicTests();
|
|
14
14
|
let selfTestSource = new SelfTests();
|
|
15
|
+
|
|
15
16
|
this.testSources = [ testSource, selfTestSource ];
|
|
16
17
|
}
|
|
17
18
|
|