risei 1.3.4 → 2.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 +142 -379
- package/Read-me reduced.md +294 -0
- package/Read-me redux.md +581 -0
- 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/test-target-objects/ConditionalThrowTarget.js +11 -0
- package/test-target-objects/Counter.js +46 -0
- package/test-target-objects/DomTarget.js +37 -0
- package/test-target-objects/InterSpoofer.js +230 -0
- package/test-target-objects/MixedContents.js +33 -0
- package/test-target-objects/MutationTarget.js +37 -0
- package/test-target-objects/ObjectComposer.js +34 -0
- package/test-target-objects/PolySpoofableInner.js +29 -0
- package/test-target-objects/PolySpoofableOuter.js +52 -0
- package/test-target-objects/PropertiesTarget.js +98 -0
- package/test-target-objects/Returner.js +7 -0
- package/test-target-objects/Searcher.js +25 -0
- package/test-target-objects/Sorter.js +91 -0
- package/test-target-objects/Spoofable.js +36 -0
- package/test-target-objects/StateTarget.js +34 -0
- package/test-target-objects/StaticTarget.js +17 -0
- package/test-target-objects/TestableTarget.js +57 -0
- package/trial-tests/SelfTests.outward-rt.js +511 -0
- package/trial-tests/TopicTests.outward-rt.js +313 -0
- package/usage-examples/Gold-bar-example.png +0 -0
- package/usage-examples/Title-example.png +0 -0
- package/xternal-tests/ASpoofingFixture.tests.js +242 -0
- package/xternal-tests/MethodSpoofer.tests.js +130 -0
- package/xternal-tests/SpoofDef.tests.js +91 -0
- package/xternal-tests/TotalComparer.tests.js +1055 -0
- package/xternal-tests/package.json +7 -0
- 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
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import TypeAnalyzer from "./TypeAnalyzer.js";
|
|
4
|
+
import NameAnalyzer from "./NameAnalyzer.js";
|
|
5
|
+
|
|
6
|
+
/* Defines what is found in a spoof definition, typically as
|
|
7
|
+
a nonce object rather than an instance of this class. */
|
|
8
|
+
|
|
9
|
+
export default class SpoofDef {
|
|
10
|
+
// region Static fields
|
|
11
|
+
|
|
12
|
+
/* Properties can have short or long names. */
|
|
13
|
+
static #onNames = [ "on", "target" ];
|
|
14
|
+
static #ofNames = [ "of", "method" ];
|
|
15
|
+
static #asNames = [ "as", "output" ];
|
|
16
|
+
|
|
17
|
+
static #longsByShort = new Map([
|
|
18
|
+
SpoofDef.#onNames,
|
|
19
|
+
SpoofDef.#ofNames,
|
|
20
|
+
SpoofDef.#asNames
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
/* &cruft, remove these after spoofing in .with and .in is removed */
|
|
24
|
+
/* Objects with either of these property names aren't
|
|
25
|
+
converted to spoofDefs by from-nonce methods. */
|
|
26
|
+
static skipNames = [ "not", "skip" ];
|
|
27
|
+
|
|
28
|
+
// endregion Static fields
|
|
29
|
+
|
|
30
|
+
// region Public fields (long names)
|
|
31
|
+
|
|
32
|
+
/* These long names are clearer and match the constructor's parameter names. */
|
|
33
|
+
|
|
34
|
+
/* The test-definition field names use the longer, possibly clearer forms.
|
|
35
|
+
Equivalent short-name and long-name properties use the same fields. */
|
|
36
|
+
|
|
37
|
+
target;
|
|
38
|
+
method;
|
|
39
|
+
output;
|
|
40
|
+
|
|
41
|
+
// endregion Public fields (long names)
|
|
42
|
+
|
|
43
|
+
// region Properties
|
|
44
|
+
|
|
45
|
+
// region Spoof definition, short names
|
|
46
|
+
|
|
47
|
+
/* These short names make JSON-like definitions easier. */
|
|
48
|
+
|
|
49
|
+
get on() {
|
|
50
|
+
return this.target;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
set on(value) {
|
|
54
|
+
this.target = value;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
get of() {
|
|
58
|
+
return this.method;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
set of(value) {
|
|
62
|
+
this.method = value;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get as() {
|
|
66
|
+
return this.output;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set as(value) {
|
|
70
|
+
this.output = value;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// endregion Spoof definition, short names
|
|
74
|
+
|
|
75
|
+
// region Def state
|
|
76
|
+
|
|
77
|
+
/* Returns true if arg doesn't provide enough to spoof with. */
|
|
78
|
+
static isNotASpoof(nonce) /* passed */ {
|
|
79
|
+
return !SpoofDef.isASpoof(nonce);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Returns true if arg provides enough to spoof with. */
|
|
83
|
+
static isASpoof(nonce) /* passed */ {
|
|
84
|
+
/* Any nonce that is null or undefined is not a SpoofDef. */
|
|
85
|
+
if (nonce === undefined || nonce === null) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let hasAnOf = SpoofDef.#hasEitherName(nonce, SpoofDef.#ofNames);
|
|
90
|
+
let hasAnAs = SpoofDef.#hasEitherName(nonce, SpoofDef.#asNames);
|
|
91
|
+
|
|
92
|
+
/* Any nonce with at least an .of or an .as is a SpoofDef. */
|
|
93
|
+
return hasAnOf || hasAnAs;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get isMethodSpoof() /* passed */ {
|
|
97
|
+
if (this.target === undefined) {
|
|
98
|
+
throw new Error("No .on / .target present. It must be set for .isMethodSpoof to work.");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let plainName = NameAnalyzer.plainNameOf(this.method);
|
|
102
|
+
|
|
103
|
+
if (NameAnalyzer.hasPropertySigil(this.method)) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
let isMethod
|
|
108
|
+
= NameAnalyzer.hasMethodSigil(this.method)
|
|
109
|
+
|| TypeAnalyzer.isMethodMember(this.target, plainName);
|
|
110
|
+
|
|
111
|
+
return isMethod;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
get isPropertySpoof() /* passed */ {
|
|
115
|
+
if (this.target === undefined) {
|
|
116
|
+
throw new Error("No .on / .target present. It must be set for .isPropertySpoof to work.");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let plainName = NameAnalyzer.plainNameOf(this.method);
|
|
120
|
+
|
|
121
|
+
if (NameAnalyzer.hasMethodSigil(this.method)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let isProperty
|
|
126
|
+
= NameAnalyzer.hasPropertySigil(this.method)
|
|
127
|
+
|| TypeAnalyzer.isPropertyMember(this.target, plainName);
|
|
128
|
+
|
|
129
|
+
return isProperty;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// endregion Def state
|
|
133
|
+
|
|
134
|
+
// endregion Properties
|
|
135
|
+
|
|
136
|
+
// region Initing, including constructor() and statics
|
|
137
|
+
|
|
138
|
+
/* Constructor can't use param names like `of`, because when not .-prefixed, they are keywords. */
|
|
139
|
+
|
|
140
|
+
constructor(target, method, output) /* passed */ {
|
|
141
|
+
this.target = target;
|
|
142
|
+
this.method = method;
|
|
143
|
+
this.output = output;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
static fromNonceTuples(nonces, type) /* passed */ {
|
|
147
|
+
// Throughput and output.
|
|
148
|
+
let full = new SpoofDef();
|
|
149
|
+
let output = [ ];
|
|
150
|
+
|
|
151
|
+
// Looping over all.
|
|
152
|
+
for (let nonce of nonces) {
|
|
153
|
+
// Get latest spoof definition/s and retain for output.
|
|
154
|
+
let latests = SpoofDef.fromNonceTuple(nonce, type);
|
|
155
|
+
output.push(...latests);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Back to caller.
|
|
159
|
+
return output;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static fromNonceTuple(nonce, type) /* passed */ {
|
|
163
|
+
/* No spoof-def to output. */
|
|
164
|
+
if (SpoofDef.isNotASpoof(nonce)) {
|
|
165
|
+
return [ ];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Empty, since properties can be set
|
|
169
|
+
// by either of two nonce naming styles.
|
|
170
|
+
let def = new SpoofDef();
|
|
171
|
+
|
|
172
|
+
let shortNames = SpoofDef.#longsByShort.keys();
|
|
173
|
+
|
|
174
|
+
/* &cruft, maybe refactor to put property-setting loop in its own method, and possibly
|
|
175
|
+
recurse internally using it without inner arrays, for a cleaner algorithm */
|
|
176
|
+
|
|
177
|
+
// Traversing matching pairs of names and applying
|
|
178
|
+
// whichever one is present as the tuple property;
|
|
179
|
+
// if neither is present, the property is undefined.
|
|
180
|
+
for (let shortName of shortNames) {
|
|
181
|
+
let longName = SpoofDef.#longsByShort.get(shortName);
|
|
182
|
+
def[shortName] = shortName in nonce ? nonce[shortName] : nonce[longName];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// No nested partial spoof-defs
|
|
186
|
+
// (mono-spoof) is most likely.
|
|
187
|
+
let defs = [ def ];
|
|
188
|
+
|
|
189
|
+
// Recursion to handle nested partial spoof-defs (poly-spoofs).
|
|
190
|
+
if (def.method === undefined && Array.isArray(def.output)) {
|
|
191
|
+
let locals = [ ];
|
|
192
|
+
|
|
193
|
+
for (let ofAsPair of def.output) {
|
|
194
|
+
let localOf = ofAsPair.of !== undefined ? ofAsPair.of : ofAsPair.method;
|
|
195
|
+
let localAs = ofAsPair.as !== undefined ? ofAsPair.as : ofAsPair.output;
|
|
196
|
+
|
|
197
|
+
let passer = SpoofDef.fromNonceTuple({ on: def.target, of: localOf, as: localAs });
|
|
198
|
+
locals.push(passer[0]);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Replace default spoof
|
|
202
|
+
// with real poly-spoofs.
|
|
203
|
+
defs = locals;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// All defs need a type / target class.
|
|
207
|
+
SpoofDef.#setAnyMissingTypes(defs, type);
|
|
208
|
+
|
|
209
|
+
// Back to caller.
|
|
210
|
+
return defs;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// region Dependencies of nonce-tuple initing methods
|
|
214
|
+
|
|
215
|
+
static #hasEitherName(nonce, names) /* verified */ {
|
|
216
|
+
let hasEither = false;
|
|
217
|
+
|
|
218
|
+
for (let name of names) {
|
|
219
|
+
hasEither ||= SpoofDef.#hasName(nonce, name);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return hasEither;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static #hasName(nonce, name) /* verified */ {
|
|
226
|
+
return nonce[name] !== undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
static #setAnyMissingTypes(defs, type) /* verified */ {
|
|
230
|
+
// Adding test target's type, if no type provided.
|
|
231
|
+
for (let def of defs) {
|
|
232
|
+
if (def.target === undefined) {
|
|
233
|
+
def.target = type;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// endregion Dependencies of nonce-tuple initing methods
|
|
239
|
+
|
|
240
|
+
// endregion Initing, including constructor() and statics
|
|
241
|
+
|
|
242
|
+
// region Overrides and dependencies
|
|
243
|
+
|
|
244
|
+
toString() /* passed */ {
|
|
245
|
+
let text = `SpoofDefinition:{ target:${ this.#asRawOrString(this.target) }, `
|
|
246
|
+
+ `method:${ this.#asRawOrString(this.method) }, `
|
|
247
|
+
+ `output:${ this.#asRawOrString(this.output) } }`;
|
|
248
|
+
return text;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#asRawOrString(value) /* verified */ {
|
|
252
|
+
if (typeof value === "string") {
|
|
253
|
+
return `"${ value }"`;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// endregion Overrides and dependencies
|
|
260
|
+
}
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
/* TerminalReporter is an ATestReporter that sends each result to the terminal / console for display. */
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
5
|
+
import ATestReporter from "./ATestReporter.js";
|
|
6
|
+
import TestGroup from "./TestGroup.js";
|
|
7
|
+
import ClassTestGroup from "./ClassTestGroup.js";
|
|
8
|
+
import MethodTestGroup from "./MethodTestGroup.js";
|
|
9
|
+
import TestResult from "./TestResult.js";
|
|
10
|
+
import TestSummary from "./TestSummary.js";
|
|
11
11
|
|
|
12
12
|
import chalk from "chalk";
|
|
13
13
|
|
|
14
|
-
export class TerminalReporter extends ATestReporter {
|
|
14
|
+
export default class TerminalReporter extends ATestReporter {
|
|
15
15
|
// region Private fields
|
|
16
16
|
|
|
17
17
|
/* Foreground-colors using dependency calls and hex. */
|
|
@@ -69,7 +69,7 @@ export class TerminalReporter extends ATestReporter {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if (result instanceof MethodTestGroup) {
|
|
72
|
-
console.log(" " + this.#methodGroup(` ${ result.group }
|
|
72
|
+
console.log(" " + this.#methodGroup(` ${ result.group }: `));
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|