risei 2.0.0 → 3.0.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 +123 -220
- package/package.json +2 -2
- package/system/ATestReporter.js +26 -26
- package/system/ClassTestGroup.js +8 -8
- package/system/LocalCaller.js +2 -2
- package/system/MethodSpoofer.js +2 -2
- package/system/MethodTestGroup.js +8 -8
- package/system/Moment.js +29 -29
- package/system/NameAnalyzer.js +26 -26
- package/system/PropertySpoofer.js +1 -1
- package/system/SpoofDef.js +0 -5
- package/system/TestDef.js +14 -13
- package/system/TestFrame.js +8 -10
- package/system/TestGroup.js +25 -25
- package/system/TestRunner.js +8 -6
- package/system/TestStages.js +66 -10
- package/system/TestSummary.js +37 -37
- package/system/TypeAnalyzer.js +79 -26
- package/Read-me reduced.md +0 -294
- package/Read-me redux.md +0 -581
- package/system/ChosenTestFinder.js +0 -31
- package/system/Risei.js +0 -118
- package/test-target-objects/ConditionalThrowTarget.js +0 -11
- package/test-target-objects/Counter.js +0 -46
- package/test-target-objects/DomTarget.js +0 -37
- package/test-target-objects/InterSpoofer.js +0 -230
- package/test-target-objects/MixedContents.js +0 -33
- package/test-target-objects/MutationTarget.js +0 -37
- package/test-target-objects/ObjectComposer.js +0 -34
- package/test-target-objects/PolySpoofableInner.js +0 -29
- package/test-target-objects/PolySpoofableOuter.js +0 -52
- package/test-target-objects/PropertiesTarget.js +0 -98
- package/test-target-objects/Returner.js +0 -7
- package/test-target-objects/Searcher.js +0 -25
- package/test-target-objects/Sorter.js +0 -91
- package/test-target-objects/Spoofable.js +0 -36
- package/test-target-objects/StateTarget.js +0 -34
- package/test-target-objects/StaticTarget.js +0 -17
- package/test-target-objects/TestableTarget.js +0 -57
- package/trial-tests/SelfTests.outward-rt.js +0 -511
- package/trial-tests/TopicTests.outward-rt.js +0 -313
- package/usage-examples/Gold-bar-example.png +0 -0
- package/usage-examples/Output-example.png +0 -0
- package/usage-examples/Summary-example.png +0 -0
- package/usage-examples/Syntax-example.png +0 -0
- package/usage-examples/Title-example.png +0 -0
- package/xternal-tests/ASpoofingFixture.tests.js +0 -242
- package/xternal-tests/MethodSpoofer.tests.js +0 -130
- package/xternal-tests/SpoofDef.tests.js +0 -91
- package/xternal-tests/TotalComparer.tests.js +0 -1055
- package/xternal-tests/package.json +0 -7
package/README.md
CHANGED
|
@@ -1,76 +1,75 @@
|
|
|
1
1
|
|
|
2
|
-
# Risei
|
|
2
|
+
# Risei Read-Me
|
|
3
3
|
|
|
4
|
-
##
|
|
4
|
+
## Overview
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
* Whip up full test coverage in no time for object-oriented (or object-hosted) JavaScript and TypeScript.
|
|
8
|
-
* Refactor or replace existing designs without worrying about about a heavy cost in past or future test construction.
|
|
9
|
-
* Create tests with immediate confidence, since you can't introduce mistakes when writing test code.
|
|
6
|
+
Risei is a new way to write unit tests that's easier and faster, more dependable, and keeps your tests from standing in the way of redesigns.
|
|
10
7
|
|
|
8
|
+
Risei does all this by replacing hand-coded tests with simple declarative syntax.
|
|
11
9
|
|
|
10
|
+
- Risei has many convenient and time-saving [features](#features-of-risei).
|
|
11
|
+
- Risei works with object-oriented JavaScript in modules.
|
|
12
|
+
- Risei works with TypeScript after just a few [tweaks](https://deusware.com/risei/index.html#typescript-with-risei).
|
|
12
13
|
|
|
14
|
+
You can find a longer version of this read-me at [https://deusware.com/risei](https://deusware.com/risei/index.html). It expands greatly on the information here.
|
|
13
15
|
|
|
14
|
-
## The Risei approach
|
|
15
16
|
|
|
16
|
-
Risei replaces coded tests with simple declarative syntax.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Examples
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Here are two example tests, in which `SortModel.countSort()` is being tested using the inputs from `.in` and the expected output from `.out`:
|
|
21
21
|
|
|
22
|
+

|
|
22
23
|
|
|
23
|
-
Here is the terminal output of these two example tests. Tests are grouped by class and method. Inputs, expected, and actual values are displayed for all tests, to make intended usage obvious at a glance:
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Here are the example test results for those two tests:
|
|
26
26
|
|
|
27
|
+

|
|
27
28
|
|
|
29
|
+
- Outputs are always listed, even on passing tests, which makes code usage much clearer.
|
|
28
30
|
- Any failing tests appear in light red.
|
|
29
31
|
- Your latest tests always sort to the bottom so it's easy to find their results.
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
Test runs
|
|
34
|
+
Test runs have a title bar so the starting point is easy to find:
|
|
33
35
|
|
|
34
|
-

|
|
36
|
+

|
|
35
37
|
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
And they have a summary bar at the bottom:
|
|
38
40
|
|
|
39
|
-

|
|
41
|
+

|
|
40
42
|
|
|
43
|
+
- This bar is red when any tests fail, much as you'd expect.
|
|
41
44
|
|
|
42
45
|
|
|
43
46
|
|
|
44
|
-
##
|
|
47
|
+
## Status
|
|
45
48
|
|
|
46
|
-
Risei is under active development. The
|
|
49
|
+
Risei is under active development and new enhancements appear often. The latest release, **3.0.0**, brings major improvements, starting with the ability to test `async` code, and builds on many major improvements in **2.0.0**, including broader capabilities and simpler syntax, and a few minor breaking changes.
|
|
47
50
|
|
|
48
|
-
|
|
49
|
-
- You can now spoof properties on the targeted class instance.
|
|
50
|
-
- Risei now can determine automatically if tested or spoofed methods and properties are static.
|
|
51
|
-
- You can now perform arbitrary operations if needed.
|
|
52
|
-
- You can now change a test property without accidentally creating a new test.
|
|
53
|
-
- `Error` objects are now compared accurately.
|
|
54
|
-
- Outputs for `throw` tests are now the entire `Error` objects (breaking change).
|
|
51
|
+
Check out the [full list of changes](#version-history).
|
|
55
52
|
|
|
56
|
-
Risei has been reengineered internally along with these improvements.
|
|
57
53
|
|
|
58
|
-
- In addition, `ATestSource` is now a default export (breaking change).
|
|
59
|
-
- This means a simple adjustment from `import { ATestSource }` to `import ATestSource`.
|
|
60
54
|
|
|
61
|
-
|
|
55
|
+
## Features of Risei
|
|
62
56
|
|
|
63
|
-
&
|
|
64
|
-
[
|
|
57
|
+
- #### Declarative syntax to write tests simply and quickly. ► [Writing tests](https://deusware.com/risei/index.html#writing-tests) (basics below)
|
|
58
|
+
- #### Easy-to-read test definitions and test outputs. ► [Test and output examples](https://deusware.com/risei/index.html#examples) (also above)
|
|
59
|
+
- #### Even less to write by stating reused test properties only once. ► [Collapsing forward](https://deusware.com/risei/index.html#collapsing-forward) (basics below)
|
|
60
|
+
- #### Built-in declarative syntax to fake test-time values from dependencies. ► [Spoofing using `.plus`](https://deusware.com/risei/index.html#spoofing) (basics below)
|
|
61
|
+
- #### Full support for `async` code with no special syntax needed. ► [Writing tests](https://deusware.com/risei/index.html#writing-tests) (basics below)
|
|
62
|
+
- #### Testing properties and methods, static and instance members all the same way. ► [Properties and statics](https://deusware.com/risei/index.html#testing-properties-and-static-methods)
|
|
63
|
+
- #### Testing `throw` paths effortlessly. ► [Using `.and: "throws"`](https://deusware.com/risei/index.html#using-and-throws)
|
|
64
|
+
- #### Deriving actual values to test from raw outputs or property retrieval. ► [Using `.from`](https://deusware.com/risei/index.html#using-from)
|
|
65
|
+
- #### Setting up and tearing down arbitrary test state. ► [Using `.do` and `.undo`](https://deusware.com/risei/index.html#using-do-and-undo)
|
|
66
|
+
- #### Testing for `undefined` as output. ► [Using `this.undef`](https://deusware.com/risei/index.html#using-undef)
|
|
67
|
+
- #### Running a method repeatedly in one test. ► [Using `.and: "poly"`](https://deusware.com/risei/index.html#using-and-poly)
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
- And more! Check out the full [Risei home page](https://deusware.com/risei).
|
|
67
70
|
|
|
68
|
-
Risei works with Typescript, requiring only a few additional or different steps, described in [using Typescript with Risei](#using-typescript-with-risei).
|
|
69
71
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
### Installation
|
|
72
|
+
## Installation
|
|
74
73
|
|
|
75
74
|
Install Risei for development time only:
|
|
76
75
|
|
|
@@ -78,7 +77,7 @@ Install Risei for development time only:
|
|
|
78
77
|
npm install --save-dev risei
|
|
79
78
|
```
|
|
80
79
|
|
|
81
|
-
|
|
80
|
+
Ensure that `package.json` specifies ECMAScript modules:
|
|
82
81
|
|
|
83
82
|
```json
|
|
84
83
|
"type": "module"
|
|
@@ -92,26 +91,17 @@ And add Risei's metadata to `package.json`:
|
|
|
92
91
|
}
|
|
93
92
|
```
|
|
94
93
|
|
|
95
|
-
> Just a [few extra steps](#using-typescript-with-risei) are required for Risei to work with TypeScript.
|
|
96
|
-
|
|
97
|
-
&cruft, new site / section
|
|
98
|
-
- Further general options can be found [here](https://deusware.com/risei-docs/index.html#installation).
|
|
99
|
-
|
|
100
|
-
&cruft, new site / section
|
|
101
|
-
- Further Typescript details can be found [here](https://deusware.com/risei-docs/index.html#using-typescript).
|
|
102
94
|
|
|
103
95
|
|
|
96
|
+
## Running Tests
|
|
104
97
|
|
|
105
|
-
|
|
106
|
-
### Running tests
|
|
107
|
-
|
|
108
|
-
Once you've written your tests, run them by invoking Risei's `index.js` file:
|
|
98
|
+
Once you have some tests written, you can run them manually:
|
|
109
99
|
|
|
110
100
|
```bash
|
|
111
101
|
node ./node_modules/risei/index.js
|
|
112
102
|
```
|
|
113
103
|
|
|
114
|
-
Or write a `package.json`
|
|
104
|
+
Or write a script in `package.json` that does the same:
|
|
115
105
|
|
|
116
106
|
```json
|
|
117
107
|
"scripts": {
|
|
@@ -125,253 +115,167 @@ And then run that script:
|
|
|
125
115
|
npm test
|
|
126
116
|
```
|
|
127
117
|
|
|
128
|
-
- Risei can be used alongside other test frameworks, and even run with them from the same test script if you want.
|
|
129
|
-
|
|
130
|
-
&cruft, new site / section
|
|
131
|
-
- Find more information about this mixed testing and other config / run options [here](https://deusware.com/risei-docs/index.html#running-tests).
|
|
132
|
-
|
|
133
118
|
|
|
134
119
|
|
|
120
|
+
## Writing Tests
|
|
135
121
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
Add tests in files ending in `.rt.js` like this:
|
|
122
|
+
You write tests in `.rt.js` files like this:
|
|
139
123
|
|
|
140
124
|
```javascript
|
|
141
125
|
import ATestSource from "risei/ATestSource";
|
|
142
|
-
import
|
|
126
|
+
import ClassToTest from "ClassToTest.js";
|
|
143
127
|
|
|
144
128
|
export class SomeTests extends ATestSource {
|
|
145
|
-
tests = [ ... ];
|
|
129
|
+
tests = [ ... ];
|
|
146
130
|
}
|
|
147
131
|
```
|
|
148
132
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
### Writing tests
|
|
152
|
-
|
|
153
|
-
Write tests with Risei's simple syntax:
|
|
133
|
+
Write individual tests as plain JavaScript objects with Risei's simple syntax:
|
|
154
134
|
|
|
155
135
|
```javascript
|
|
156
136
|
tests = [ ...
|
|
157
|
-
{ on:
|
|
158
|
-
of: "doesContain",
|
|
159
|
-
for: "When the arg is present, returns true.",
|
|
160
|
-
in: [ "c" ],
|
|
161
|
-
out: true },
|
|
162
|
-
...];
|
|
137
|
+
{ on: ContainerClass, with: [ "a", "b", "c" ], // Target class and constructor args.
|
|
138
|
+
of: "doesContain", // Target method name.
|
|
139
|
+
for: "When the arg is present, returns true.", // Description of test.
|
|
140
|
+
in: [ "c" ], // Inputs to method.
|
|
141
|
+
out: true }, // Expected output.
|
|
142
|
+
... ];
|
|
163
143
|
```
|
|
164
144
|
|
|
165
|
-
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
- To test a value derived from the initial actual value, or otherwise from any available context, add a `from` property that's an arrow function taking (at present) `target` and `test` parameters: `(target, test) => { return test.actual.someProperty; }`.
|
|
170
|
-
|
|
171
|
-
- To perform operations like creating files temporarily, use the `.do` property (encompassing two stages, `.before` and `.after`) to set up isolated test state, and `.undo` to restore normal state.
|
|
172
|
-
- The `.do`-`.before` steps are taken before the target class instance is created, the `.do`-`.after steps are taken after that but before the target method / property is run.
|
|
173
|
-
- The `.undo` is an arrow function taking a `test` arg. It is run after all other steps of the test have been run. **(2.0.0)**
|
|
174
|
-
|
|
175
|
-
- To maintain the benefits of using Risei's declarative style, avoid arbitrary options as much as possible.
|
|
145
|
+
- Asynchronous code with `async` and `await` keywords can tested with no changes at all to this syntax.
|
|
146
|
+
- Use empty arrays for `.in` or `.with` when there are no args to pass.
|
|
147
|
+
- You can use [long names](https://deusware.com/risei/index.html#long-names) for properties if you want.
|
|
176
148
|
|
|
177
|
-
- If you prefer test property names that aren't JavaScript keywords, alternatives are available for all of them.
|
|
178
149
|
|
|
179
|
-
|
|
150
|
+
## Basic collapsing forward example
|
|
180
151
|
|
|
152
|
+
You can state test properties once and let them _collapse forward_ across subsequent tests to save time and make tests easier to read.
|
|
181
153
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
#### Write more tests with less syntax:
|
|
185
|
-
|
|
186
|
-
To save a lot of time, state repeated test values just once, and let them _collapse forward_ into following tests:
|
|
154
|
+
Risei collapses values together from partial or full test objects until it has a full test to run. Every property collapses forward until it is changed or wiped out:
|
|
187
155
|
|
|
188
156
|
```javascript
|
|
189
|
-
|
|
190
|
-
{ on: ContainerModelClass, with: [ "a", "b", "c", "a", "b" ] },
|
|
191
|
-
|
|
192
|
-
/* Two tests for ContainerModelClass .doesContain(). */
|
|
193
|
-
{ of: "doesContain" },
|
|
194
|
-
{ for: "When the input arg is present, returns true.",
|
|
195
|
-
in: [ "c" ], out: true },
|
|
196
|
-
{ for: "When the input arg is not present, returns false.",
|
|
197
|
-
in: [ "d" ], out: false },
|
|
198
|
-
|
|
199
|
-
/* First test for ContainerModelClass .countOf(). */
|
|
200
|
-
{ of: "countOf", for: "Returns the number present.", in: [ "b" ], out: 2 }
|
|
201
|
-
```
|
|
157
|
+
{ on: ContainerClass, with: [ "a", "b", "c" ] }, // Following tests are of this class.
|
|
202
158
|
|
|
203
|
-
|
|
159
|
+
{ of: "doesContain" }, // Following tests are of this method.
|
|
160
|
+
{ for: "Returns true when arg present.", in: [ "c" ], out: true }, // First test: now Risei has enough to run on.
|
|
161
|
+
{ for: "Returns false when arg absent.", in: [ "d" ], out: false }, // Next test: same method, different test case.
|
|
204
162
|
|
|
205
|
-
|
|
163
|
+
{ of: "countOf" }, // Change of tested method. Method-related props are wiped out.
|
|
164
|
+
...
|
|
206
165
|
|
|
207
|
-
|
|
166
|
+
{ on: SortingClass, with: [ ] }, // Change of tested class. All existing props are wiped out.
|
|
167
|
+
```
|
|
208
168
|
|
|
209
|
-
|
|
210
|
-
-
|
|
169
|
+
- There are more options available, and an exclusion for mutated args.
|
|
170
|
+
- Learn all the details [here](https://deusware.com/risei/index.html#collapsing-forward).
|
|
211
171
|
|
|
212
172
|
|
|
213
173
|
|
|
174
|
+
## Basic spoofing example
|
|
214
175
|
|
|
215
|
-
|
|
176
|
+
You can use declarative _spoofing_ syntax to define what dependencies of your targeted code return for it to use.
|
|
216
177
|
|
|
217
|
-
|
|
178
|
+
The most basic spoofing looks like this:
|
|
218
179
|
|
|
219
180
|
```javascript
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
],
|
|
230
|
-
for: "When called, returns an array of values from sources.",
|
|
231
|
-
in: [ "green" ], out: [ 7, 8, 9, 10, 10, 11, 12, { color: "green" } ] }
|
|
181
|
+
{
|
|
182
|
+
on: TestedClass,
|
|
183
|
+
...
|
|
184
|
+
plus: [
|
|
185
|
+
{ on: Dependency, of: "someMethod", as: 10 }, // Dependency.someMethod() returns 10 in this test.
|
|
186
|
+
{ of: "testedClassMethod", as: 11 } // TestedClass.testedClassMethod() returns 11 in this test.
|
|
187
|
+
],
|
|
188
|
+
...
|
|
189
|
+
}
|
|
232
190
|
```
|
|
233
191
|
|
|
234
192
|
- It's just like _fakes_, _mocks_, or _test doubles_ in other test systems, but easier to write and read.
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
- There are many further spoofing options that save effort, including using nonce methods as spoofs and spoofing target-instance properties. **(2.0.0)** Check out all your options [here](https://deusware.com/risei-docs/index.html#collapsing-forward).
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
- Spoofed code is fully isolated within tests, even though spoof definitions collapse forward across tests (and within `.plus`).
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
## Using TypeScript with Risei
|
|
246
|
-
|
|
247
|
-
Testing TypeScript code with Risei basically just means transpiling before running the tests, and pointing Risei to the transpiled JS files.
|
|
248
|
-
|
|
249
|
-
- Anything beyond those basics is intended to keep JS files separate from TS files and the output of web frameworks' own, complex build processes.
|
|
250
|
-
|
|
251
|
-
If you follow the general Risei set-up, you can just make the following few modifications for TypeScript applications.
|
|
252
|
-
- These steps have worked with both Angular and React.
|
|
253
|
-
- Varying other approaches are also sure to work, depending on the other technical choices in play.
|
|
254
|
-
|
|
193
|
+
- Numerous additional capabilities, as well as compressed syntax, can be mixed freely in many ways.
|
|
194
|
+
- Learn more [here](https://deusware.com/risei/index.html#spoofing).
|
|
255
195
|
|
|
256
196
|
|
|
257
|
-
### In `package.json`:
|
|
258
197
|
|
|
259
|
-
|
|
198
|
+
## TypeScript with Risei
|
|
260
199
|
|
|
261
|
-
|
|
262
|
-
"scripts": {
|
|
263
|
-
"test": "tsc && node ./node_modules/risei/index.js && rm -r ./dist/out-tsc"
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
- Generally, you should use `tsc` or another plain transpiler, not web frameworks' complex processes with single output files.
|
|
268
|
-
- Deleting the files at the end prevents interference with web frameworks' bundling.
|
|
269
|
-
- The deletion path must match the `outDir` in `tsconfig.json`.
|
|
200
|
+
To test TypeScript code with Risei, you make sure the code is transpiled before the tests are run, and you point Risei to the transpiled `.js` files.
|
|
270
201
|
|
|
271
|
-
|
|
202
|
+
- Learn all about it [here](https://deusware.com/risei/index.html#typescript-with-risei).
|
|
272
203
|
|
|
273
204
|
|
|
274
205
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
You set up the transpiler to output files to a directory with these settings:
|
|
278
|
-
|
|
279
|
-
```json
|
|
280
|
-
{
|
|
281
|
-
"outDir": "dist/out-tsc",
|
|
282
|
-
"noEmit": false
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
- The `outDir` can be any location. It's best not to just use `dist`, where adding or deleting files may interfere with web frameworks' build steps.
|
|
287
|
-
- These settings are normally not near each other in the file (as seen here).
|
|
288
|
-
- You can also set the `target` to `es6` or higher, although Risei works fine with ES5.
|
|
206
|
+
## Troubleshooting
|
|
289
207
|
|
|
208
|
+
If problems cause test files not to load, a gold bar appears and tests in those files disappear from output:
|
|
290
209
|
|
|
210
|
+

|
|
291
211
|
|
|
292
|
-
|
|
212
|
+
- Those and other problems can be solved with the help of this [troubleshooting guide](https://deusware.com/risei/index.html#troubleshooting).
|
|
293
213
|
|
|
294
|
-
All `import` statements have to point to the Javascript (`.js`) files in the `outDir` path or subfolders there, using relative-path syntax:
|
|
295
214
|
|
|
296
|
-
```javascript
|
|
297
|
-
import { TestedClass } from "../../dist/out-tsc/SubPath/TestedClass.js";
|
|
298
|
-
```
|
|
299
215
|
|
|
300
|
-
|
|
216
|
+
## Version history
|
|
301
217
|
|
|
218
|
+
- Release **3.0.0** (August, 2024) contains all of these changes:
|
|
219
|
+
- Asynchronous code with `async` syntax is now fully supported, with no special test syntax required.
|
|
220
|
+
- **(Breaking change)** `.from` functions now take `test` and `actual` as parameters, rather than `target` and `test`.
|
|
221
|
+
- If you need to work with the target of the test (usually an instance of the class being tested), it's available as `test.target`.
|
|
222
|
+
- You can now call target code more than once in one test using an `.and` of `"poly"` (AKA _poly-calling_).
|
|
302
223
|
|
|
303
224
|
|
|
225
|
+
<details>
|
|
226
|
+
<summary>
|
|
227
|
+
Older releases
|
|
228
|
+
</summary>
|
|
304
229
|
|
|
305
|
-
|
|
230
|
+
- Release **2.0.1** (August, 2024) contained all of these changes:
|
|
231
|
+
- Risei now can determine automatically if tested methods are static.
|
|
232
|
+
- You can now directly test properties just like methods.
|
|
233
|
+
- Risei can also determine automatically if these are static.
|
|
234
|
+
- Directly tested properties appear in the output in the form `.name`.
|
|
235
|
+
- You can now spoof properties on the targeted class instance, and static properties on the target class itself.
|
|
236
|
+
- You can now perform arbitrary operations, if needed, with the two-part `.do` property and one-part `.undo` property.
|
|
237
|
+
- You can now change test properties without accidentally creating a new test using `.just`.
|
|
238
|
+
- You can now directly test for `undefined` in `.out` using `this.undef` / `ATestSource.undefSymbol`.
|
|
239
|
+
- `Error` objects are now compared accurately.
|
|
240
|
+
- You can now identify member types with `.`, `:`, and `()` in any of `.of`, `.plus`, and `.from`, though it isn't necessary.
|
|
241
|
+
- **(Breaking change)** The actual for throw tests is now the entire thrown object (usually an `Error`), rather than the `Error`'s message text.
|
|
242
|
+
- **(Breaking change)** `ATestSource` is now a default export, changing its imports from `import { ATestSource } from` to `import ATestSource from`.
|
|
243
|
+
- Major internal re-engineering.
|
|
306
244
|
|
|
307
|
-
- Release **2.0.0** (
|
|
245
|
+
- Release **2.0.0** (August, 2024) was identical to 2.0.1 except for some unneeded extra files.
|
|
308
246
|
|
|
309
247
|
- Release **1.3.4** (March, 2024) fixed a bug that caused class display problems in some cases.
|
|
310
|
-
|
|
311
248
|
- Release **1.3.3** (March, 2024) fixed a major bug that prevented tests from running in Windows.
|
|
312
|
-
|
|
313
249
|
- Release **1.3.2** (February, 2024) only improved this read-me's contents.
|
|
314
|
-
|
|
315
250
|
- Release **1.3.1** (February, 2024) reversed some changes in 1.3.0 that did not work as hoped.
|
|
316
|
-
|
|
317
251
|
- Release **1.3.0** (February, 2024) added the loading-error gold bar and fixed a test-sorting bug.
|
|
318
|
-
|
|
319
252
|
- Release **1.2.0** (January, 2024) changed test sorting to move last-edited tests to the end.
|
|
320
|
-
|
|
321
253
|
- Release **1.1.2** of Risei (January, 2024) fixed class displays and inaccurate `Date` comparisons.
|
|
322
254
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
## Troubleshooting
|
|
329
|
-
|
|
330
|
-
Problems loading tests are almost always a missing or extra comma, brace, or similar. When a test file can't be loaded, loading continues with the next file. The number of tests drops (or doesn't increase as expected), and a gold bar appears naming the file and problem:
|
|
331
|
-
|
|
332
|
-

|
|
333
|
-
|
|
334
|
-
- Unfortunately, there is no way to list the problem line number.
|
|
335
|
-
- A sudden fail of many test files is usually due to a problem in the tested code, not the tests themselves.
|
|
336
|
-
|
|
337
|
-
Problems with test results themselves are usually due to omissions or other mistakes in test definitions.
|
|
338
|
-
|
|
339
|
-
For far more information about troubleshooting, including some specific error messages, check out the documentation [here](https://deusware.com/risei-docs/index.html#troubleshooting).
|
|
255
|
+
> The oldest releases are no longer listed here, and old releases are dropped progressively over time. Using the latest release is recommended.
|
|
340
256
|
|
|
257
|
+
</details>
|
|
341
258
|
|
|
342
259
|
|
|
343
260
|
|
|
344
261
|
## Known issues and workarounds
|
|
345
262
|
|
|
346
|
-
|
|
263
|
+
The only issue at present is reuse of method args mutated by tested code when collapsing forward.
|
|
347
264
|
|
|
348
|
-
-
|
|
349
|
-
- To avoid this, simply restate the args for each test that mutates them.
|
|
265
|
+
- The workaround is just to restate those args for each test.
|
|
350
266
|
|
|
351
267
|
|
|
352
|
-
- When a few properties are changed in separate objects, they are treated as whole new tests, which usually fail because of their unintended mix of old and new properties.
|
|
353
|
-
- To avoid this problem, just add a `.just` or `.only` property, of any value, in the same objects as those tests.change properties as part of whole new tests, or else restate `.of` along with the changed properties.
|
|
354
|
-
- You can also clear existing properties with `.on` or `.of` and then do this, since then there aren't enough test properties present yet to comprise a full test.
|
|
355
268
|
|
|
269
|
+
## Exclusions from Risei
|
|
356
270
|
|
|
271
|
+
At present, there are a few things Risei doesn't support. Some of these may be supported in the future.
|
|
357
272
|
|
|
358
|
-
|
|
273
|
+
- You can see the whole list [here](https://deusware.com/risei/index.html#exclusions-from-risei).
|
|
274
|
+
- You can save a lot of time by using Risei for most of your code, and another framework for whatever it doesn't support.
|
|
359
275
|
|
|
360
|
-
The following are not supported at present:
|
|
361
|
-
- Use of `async` syntax
|
|
362
|
-
- Code written in ESM `export` modules, but not within classes
|
|
363
|
-
- Standalone functions and other functionality not built into classes, AKA _loose code_
|
|
364
|
-
- CJS syntax using `require()`
|
|
365
|
-
- Debugging model code during tests
|
|
366
|
-
- Comparing rare JS object types like `Proxy` or `ArrayBuffer` in test assertions
|
|
367
276
|
|
|
368
|
-
Some of these are on the tentative future-development list.
|
|
369
|
-
- In the meantime, Risei can be used to save development time for most of your JavaScript code, while these cases can be tested using another framework invoked alongside Risei.
|
|
370
277
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
## Who makes Risei
|
|
278
|
+
## Maker
|
|
375
279
|
|
|
376
280
|
Risei is written by myself, Ed Fallin. I'm a longtime software developer who likes to find better ways to do things.
|
|
377
281
|
|
|
@@ -381,8 +285,7 @@ You can get in touch about Risei at **riseimaker@gmail.com**.
|
|
|
381
285
|
|
|
382
286
|
|
|
383
287
|
|
|
384
|
-
|
|
385
|
-
## Risei license
|
|
288
|
+
## License
|
|
386
289
|
|
|
387
290
|
Risei is published for use under the terms of the MIT license:
|
|
388
291
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "risei",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Risei allows you to write unit tests as simple JavaScript objects, so it's easy and fast, with no drag on redesign.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"unit test",
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
"fs": "^0.0.1-security",
|
|
51
51
|
"mocha": "^10.0.0",
|
|
52
52
|
"morgan": "~1.9.1",
|
|
53
|
-
"risei": "^
|
|
53
|
+
"risei": "^3.0.0"
|
|
54
54
|
}
|
|
55
55
|
}
|
package/system/ATestReporter.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
/**/
|
|
2
|
-
|
|
3
|
-
/* Defines operations that a test reporter must implement. A = abstract. */
|
|
4
|
-
|
|
5
|
-
/* &cruft, ? replace with my own code eventually */
|
|
6
|
-
import chalk from "chalk";
|
|
7
|
-
|
|
8
|
-
export default class ATestReporter {
|
|
9
|
-
// Reports whatever was just provided by the TestRunner.
|
|
10
|
-
// Can delegate to the other report-x methods.
|
|
11
|
-
reportNext(result) {
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
reportGroup() {
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
reportPassed(result) {
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
reportFailed(result) {
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
reportSummary(summary) {
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
}
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
/* Defines operations that a test reporter must implement. A = abstract. */
|
|
4
|
+
|
|
5
|
+
/* &cruft, ? replace with my own code eventually */
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
|
|
8
|
+
export default class ATestReporter {
|
|
9
|
+
// Reports whatever was just provided by the TestRunner.
|
|
10
|
+
// Can delegate to the other report-x methods.
|
|
11
|
+
reportNext(result) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
reportGroup() {
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
reportPassed(result) {
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
reportFailed(result) {
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
reportSummary(summary) {
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
}
|
package/system/ClassTestGroup.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/**/
|
|
2
|
-
|
|
3
|
-
import TestGroup from "./TestGroup.js";
|
|
4
|
-
|
|
5
|
-
/* Identifies a grouping of tests by class. No specialized workings. */
|
|
6
|
-
|
|
7
|
-
export default class ClassTestGroup extends TestGroup {
|
|
8
|
-
}
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import TestGroup from "./TestGroup.js";
|
|
4
|
+
|
|
5
|
+
/* Identifies a grouping of tests by class. No specialized workings. */
|
|
6
|
+
|
|
7
|
+
export default class ClassTestGroup extends TestGroup {
|
|
8
|
+
}
|
package/system/LocalCaller.js
CHANGED
|
@@ -11,11 +11,11 @@ import TestRunner from "./TestRunner.js";
|
|
|
11
11
|
export default class LocalCaller extends ATestCaller {
|
|
12
12
|
async runAllTests() {
|
|
13
13
|
let tests = await this.finder.findAllTests();
|
|
14
|
-
this.runner.useTests(tests);
|
|
14
|
+
this.runner.useTests(tests);
|
|
15
15
|
|
|
16
16
|
// Getting each run test / summary result
|
|
17
17
|
// and having it reported in the terminal.
|
|
18
|
-
for (let result of this.runner) {
|
|
18
|
+
for await (let result of this.runner.runTests()) {
|
|
19
19
|
this.reporter.reportNext(result);
|
|
20
20
|
}
|
|
21
21
|
}
|
package/system/MethodSpoofer.js
CHANGED
|
@@ -39,7 +39,7 @@ export default class MethodSpoofer extends ASpoofingFixture {
|
|
|
39
39
|
// endregion Properties
|
|
40
40
|
|
|
41
41
|
constructor() {
|
|
42
|
-
super(
|
|
42
|
+
super();
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// Spoofs methods of classes as defined in nonce
|
|
@@ -53,7 +53,7 @@ export default class MethodSpoofer extends ASpoofingFixture {
|
|
|
53
53
|
if (!Array.isArray(spoofNonces)) {
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
// Converting to scope object type.
|
|
58
58
|
let spoofDefs = SpoofDef.fromNonceTuples(spoofNonces, type);
|
|
59
59
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/**/
|
|
2
|
-
|
|
3
|
-
import TestGroup from "./TestGroup.js";
|
|
4
|
-
|
|
5
|
-
/* Identifies a grouping of tests by method. No specialized workings. */
|
|
6
|
-
|
|
7
|
-
export default class MethodTestGroup extends TestGroup {
|
|
8
|
-
}
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import TestGroup from "./TestGroup.js";
|
|
4
|
+
|
|
5
|
+
/* Identifies a grouping of tests by method. No specialized workings. */
|
|
6
|
+
|
|
7
|
+
export default class MethodTestGroup extends TestGroup {
|
|
8
|
+
}
|