risei 1.0.4 → 1.1.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 +236 -339
- package/index.js +8 -8
- package/package.json +23 -9
- package/{public/javascript → system}/ASpoofingFixture.js +1 -1
- package/{public/javascript → system}/ChosenTestFinder.js +4 -3
- package/{public/javascript → system}/SpoofClassMethodsFixture.js +38 -22
- package/system/SpoofObjectMethodsFixture.js +58 -0
- package/{public/javascript → system}/SpoofTuple.js +14 -1
- package/{public/javascript → system}/TerminalReporter.js +249 -222
- package/system/TestFrame.js +187 -0
- package/system/TestFrameChooser.js +54 -0
- package/system/TestFrames.js +232 -0
- package/system/TestResult.js +187 -0
- package/system/TestRunner.js +280 -0
- package/system/TestStages.js +278 -0
- package/{public/javascript → system}/TestTuple.js +132 -13
- package/{public/javascript → system}/TotalComparer.js +12 -0
- package/system/TotalCopier.js +79 -0
- package/system/TotalDisplayer.js +143 -0
- package/system/TypeAnalyzer.js +103 -0
- package/system/TypeIdentifier.js +70 -0
- package/system/Types.js +17 -0
- package/tests/other-tests/ASpoofingFixture.tests.js +242 -0
- package/tests/other-tests/SpoofClassesFixture.tests.js +130 -0
- package/tests/other-tests/SpoofObjectsFixture.tests.js +95 -0
- package/tests/other-tests/SpoofTuple.tests.js +93 -0
- package/tests/other-tests/TotalComparer.tests.js +920 -0
- package/tests/other-tests/package.json +7 -0
- package/tests/risei-tests/ASpoofingFixtureTests.rt.js +51 -0
- package/tests/risei-tests/MomentTests.rt.js +103 -0
- package/tests/risei-tests/SpoofTupleTests.rt.js +274 -0
- package/tests/risei-tests/TestFrameChooserTests.rt.js +74 -0
- package/tests/risei-tests/TestFrameTests.rt.js +84 -0
- package/tests/risei-tests/TestStagesTests.rt.js +99 -0
- package/tests/risei-tests/TestTupleTests.rt.js +140 -0
- package/tests/risei-tests/TotalComparerTests.rt.js +184 -0
- package/tests/risei-tests/TotalCopierTests.rt.js +74 -0
- package/tests/risei-tests/TotalDisplayerTests.rt.js +186 -0
- package/tests/risei-tests/TypeAnalyzerTests.rt.js +29 -0
- package/tests/risei-tests/TypeIdentifierTests.rt.js +44 -0
- package/tests/self-tests/SelfTests.outward-rt.js +583 -0
- package/tests/target-objects/CompositionModel.js +38 -0
- package/tests/target-objects/ConditionalThrowModel.js +11 -0
- package/tests/target-objects/CountModel.js +46 -0
- package/tests/target-objects/DomModel.js +37 -0
- package/tests/target-objects/MixedContents.js +33 -0
- package/tests/target-objects/MutationModel.js +27 -0
- package/tests/target-objects/ObjectCompositionModel.js +34 -0
- package/tests/target-objects/PolySpoofableInner.js +30 -0
- package/tests/target-objects/PolySpoofableOuter.js +52 -0
- package/tests/target-objects/PropertiesModel.js +47 -0
- package/tests/target-objects/Returner.js +9 -0
- package/tests/target-objects/SearchModel.js +25 -0
- package/tests/target-objects/SortModel.js +91 -0
- package/tests/target-objects/SpoofCaller.js +24 -0
- package/tests/target-objects/Spoofable.js +36 -0
- package/tests/target-objects/SpoofableArgsCaller.js +33 -0
- package/tests/target-objects/StateModel.js +34 -0
- package/tests/target-objects/StaticModel.js +17 -0
- package/tests/target-objects/TestableModel.js +47 -0
- package/tests/topic-tests/TopicTests.outward-rt.js +354 -0
- package/public/javascript/SpoofObjectMethodsFixture.js +0 -52
- package/public/javascript/TestResult.js +0 -338
- package/public/javascript/TestRunner.js +0 -476
- /package/{public/javascript → system}/AComparer.js +0 -0
- /package/{public/javascript → system}/ATestCaller.js +0 -0
- /package/{public/javascript → system}/ATestFinder.js +0 -0
- /package/{public/javascript → system}/ATestFixture.js +0 -0
- /package/{public/javascript → system}/ATestReporter.js +0 -0
- /package/{public/javascript → system}/ATestSource.js +0 -0
- /package/{public/javascript → system}/ClassTestGroup.js +0 -0
- /package/{public/javascript → system}/LocalCaller.js +0 -0
- /package/{public/javascript → system}/MethodTestGroup.js +0 -0
- /package/{public/javascript → system}/Moment.js +0 -0
- /package/{public/javascript → system}/Risei.js +0 -0
- /package/{public/javascript → system}/TestFinder.js +0 -0
- /package/{public/javascript → system}/TestGroup.js +0 -0
- /package/{public/javascript → system}/TestSummary.js +0 -0
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
/* Runs tests one by one as an ATestCaller requests them. */
|
|
4
|
+
|
|
5
|
+
import { TestTuple } from "./TestTuple.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
|
+
|
|
12
|
+
import { TestFrameChooser } from "./TestFrameChooser.js";
|
|
13
|
+
import { TestFrames } from "./TestFrames.js";
|
|
14
|
+
|
|
15
|
+
import { SpoofClassMethodsFixture } from "./SpoofClassMethodsFixture.js";
|
|
16
|
+
import { SpoofObjectMethodsFixture } from "./SpoofObjectMethodsFixture.js";
|
|
17
|
+
import { SpoofTuple } from "./SpoofTuple.js";
|
|
18
|
+
|
|
19
|
+
export class TestRunner {
|
|
20
|
+
// region Static definition fields
|
|
21
|
+
|
|
22
|
+
// Used for a special test structural case;
|
|
23
|
+
// classes have one constructor by this name.
|
|
24
|
+
static #constructorName = "constructor";
|
|
25
|
+
|
|
26
|
+
// endregion Static definition fields
|
|
27
|
+
|
|
28
|
+
// region Private fields
|
|
29
|
+
|
|
30
|
+
// Components and state.
|
|
31
|
+
#tests;
|
|
32
|
+
|
|
33
|
+
#classSpoofer;
|
|
34
|
+
#instanceSpoofer;
|
|
35
|
+
|
|
36
|
+
#frameSource;
|
|
37
|
+
#frameChooser;
|
|
38
|
+
|
|
39
|
+
#comparer;
|
|
40
|
+
|
|
41
|
+
// Results summary.
|
|
42
|
+
#numberRun;
|
|
43
|
+
#numberPassed;
|
|
44
|
+
#numberFailed;
|
|
45
|
+
#allDidPass;
|
|
46
|
+
|
|
47
|
+
// endregion Private fields
|
|
48
|
+
|
|
49
|
+
// region Properties
|
|
50
|
+
|
|
51
|
+
get tests() {
|
|
52
|
+
return this.#tests;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
set tests(value) {
|
|
56
|
+
this.#tests = value;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// region Spoofing
|
|
60
|
+
|
|
61
|
+
get classSpoofer() {
|
|
62
|
+
return this.#classSpoofer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
set classSpoofer(value) {
|
|
66
|
+
this.#classSpoofer = value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get instanceSpoofer() {
|
|
70
|
+
return this.#instanceSpoofer;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
set instanceSpoofer(value) {
|
|
74
|
+
this.#instanceSpoofer = value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// endregion Spoofing
|
|
78
|
+
|
|
79
|
+
get numberRun() {
|
|
80
|
+
return this.#numberRun;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
set numberRun(value) {
|
|
84
|
+
this.#numberRun = value;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get numberPassed() {
|
|
88
|
+
return this.#numberPassed;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
set numberPassed(value) {
|
|
92
|
+
this.#numberPassed = value;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
get numberFailed() {
|
|
96
|
+
return this.#numberFailed;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
set numberFailed(value) {
|
|
100
|
+
this.#numberFailed = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get allDidPass() {
|
|
104
|
+
return this.#allDidPass;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
set allDidPass(value) {
|
|
108
|
+
this.#allDidPass = value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// endregion Properties
|
|
112
|
+
|
|
113
|
+
constructor() {
|
|
114
|
+
this.#tests = [];
|
|
115
|
+
this.#classSpoofer = new SpoofClassMethodsFixture();
|
|
116
|
+
this.#instanceSpoofer = new SpoofObjectMethodsFixture();
|
|
117
|
+
|
|
118
|
+
this.#frameSource = new TestFrames();
|
|
119
|
+
this.#frameChooser = new TestFrameChooser(this.#frameSource);
|
|
120
|
+
|
|
121
|
+
this.#numberRun = 0;
|
|
122
|
+
this.#numberPassed = 0;
|
|
123
|
+
this.#numberFailed = 0;
|
|
124
|
+
|
|
125
|
+
this.#allDidPass = true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// region Tests to run
|
|
129
|
+
|
|
130
|
+
useTests(tests) {
|
|
131
|
+
this.#tests = tests;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// endregion Tests to run
|
|
135
|
+
|
|
136
|
+
// region Running tests
|
|
137
|
+
|
|
138
|
+
// Generator for all test results,
|
|
139
|
+
// including groups and summary.
|
|
140
|
+
* [Symbol.iterator]() {
|
|
141
|
+
if (!this.#tests) {
|
|
142
|
+
throw new Error("No tests available to run. TestRunner's .tests must be set before an attempt to run is made.");
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Converting so that property names can be relied on.
|
|
146
|
+
this.#tests = TestTuple.fromNonceTuples(this.tests);
|
|
147
|
+
|
|
148
|
+
// Needed for displaying classes and methods as groups.
|
|
149
|
+
let classGroup = new ClassTestGroup();
|
|
150
|
+
let methodGroup = new MethodTestGroup();
|
|
151
|
+
let atFirstClassMethod = false;
|
|
152
|
+
|
|
153
|
+
// Iterative running of all tests in current order.
|
|
154
|
+
for (let test of this.#tests) {
|
|
155
|
+
// Each new class should be a group, and its start
|
|
156
|
+
// should be retained for grouping of methods.
|
|
157
|
+
if (test.on.name !== classGroup.group) {
|
|
158
|
+
classGroup.group = test.on.name;
|
|
159
|
+
atFirstClassMethod = true;
|
|
160
|
+
yield classGroup;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Each new method name should be a group,
|
|
164
|
+
// and so should each method for a class.
|
|
165
|
+
if (test.of !== methodGroup.group || atFirstClassMethod) {
|
|
166
|
+
methodGroup.group = test.of;
|
|
167
|
+
atFirstClassMethod = false;
|
|
168
|
+
yield methodGroup;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let result = this.runOneTest(test);
|
|
172
|
+
yield result;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Iterative returning of final results summary.
|
|
176
|
+
yield this.summarize();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
runOneTest(test) {
|
|
180
|
+
// Default outputs. Never left undefined.
|
|
181
|
+
test.didPass = false;
|
|
182
|
+
test.anyThrow = null;
|
|
183
|
+
|
|
184
|
+
// Spoofing based on any spoof
|
|
185
|
+
// definitions in .with and .of.
|
|
186
|
+
this.#anyObjectSpoofing(test);
|
|
187
|
+
|
|
188
|
+
// Gathering facts defining the nature of the test,
|
|
189
|
+
// some of which might change after the test is run.
|
|
190
|
+
let result = new TestResult(test);
|
|
191
|
+
result.setNature();
|
|
192
|
+
|
|
193
|
+
// Aspects of the test determine the right test frame,
|
|
194
|
+
// bound back to its class to use private class members.
|
|
195
|
+
let testFrame = this.#frameChooser.supplyTestFrame(test);
|
|
196
|
+
testFrame = testFrame.bind(this.#frameSource);
|
|
197
|
+
|
|
198
|
+
// Done in every test.
|
|
199
|
+
this.#anyMethodSpoofing(test);
|
|
200
|
+
|
|
201
|
+
// Actually running the test.
|
|
202
|
+
try {
|
|
203
|
+
testFrame(test);
|
|
204
|
+
}
|
|
205
|
+
catch (thrown) {
|
|
206
|
+
test.anyThrow = thrown;
|
|
207
|
+
test.didPass = false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Done in every test, whether passed, failed, or thrown.
|
|
211
|
+
this.#anyMethodRestoring(test);
|
|
212
|
+
|
|
213
|
+
// Gathering facts based on the test run.
|
|
214
|
+
result.setResults();
|
|
215
|
+
|
|
216
|
+
// For later summarizing.
|
|
217
|
+
this.#retainTestResults(test);
|
|
218
|
+
|
|
219
|
+
// Results and test back to the caller.
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// region Dependencies of runOneTest()
|
|
224
|
+
|
|
225
|
+
// Spoofs objects as defined in TestTuple's
|
|
226
|
+
// .with and .in, which can contain spoofs.
|
|
227
|
+
#anyObjectSpoofing(test) {
|
|
228
|
+
// Spoofing objects may be skipped for self-testing.
|
|
229
|
+
if (typeof test.and === "string") {
|
|
230
|
+
if (test.and.includes("nospoof")) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Actually spoofing, if any is defined.
|
|
236
|
+
this.#instanceSpoofer.spoof(test);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
#anyMethodSpoofing(test) {
|
|
240
|
+
if (test.plus === undefined) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this.#classSpoofer.spoof(test);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
#anyMethodRestoring(test) {
|
|
248
|
+
this.#classSpoofer.unspoof();
|
|
249
|
+
this.#classSpoofer.removeDefinitions();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
#retainTestResults(test) {
|
|
253
|
+
this.#numberRun++;
|
|
254
|
+
|
|
255
|
+
if (test.didPass) {
|
|
256
|
+
this.#numberPassed++;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
this.#numberFailed++;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
this.#allDidPass &= test.didPass;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// endregion Dependencies of runOneTest()
|
|
266
|
+
|
|
267
|
+
summarize() {
|
|
268
|
+
let summary = `Ran ${ this.#numberRun } test${ this.#numberRun !== 1 ? "s" : "" }. `
|
|
269
|
+
+ `${ this.#allDidPass ? "All tests passed. " : "" }`
|
|
270
|
+
+ `${ this.#numberPassed } passed. `
|
|
271
|
+
+ `${ this.#numberFailed } failed.`;
|
|
272
|
+
|
|
273
|
+
let anyWereRun = this.#numberRun > 0;
|
|
274
|
+
|
|
275
|
+
return new TestSummary(summary, this.#allDidPass, anyWereRun);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// endregion Running tests
|
|
279
|
+
|
|
280
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import { TestTuple } from "./TestTuple.js";
|
|
4
|
+
import { TotalComparer } from "./TotalComparer.js";
|
|
5
|
+
import { TotalCopier } from "./TotalCopier.js";
|
|
6
|
+
|
|
7
|
+
export class TestStages {
|
|
8
|
+
/* &cruft, implement all of these under test, and eventually factor them */
|
|
9
|
+
|
|
10
|
+
/* These methods hold operations carried out in the test frame,
|
|
11
|
+
or before / after all test frames, in the test runner.
|
|
12
|
+
Not necessarily all test steps are found here. */
|
|
13
|
+
|
|
14
|
+
static #comparer = new TotalComparer();
|
|
15
|
+
static #copier = new TotalCopier();
|
|
16
|
+
|
|
17
|
+
setLocalInitorsAndInputs(test) /* passed */ {
|
|
18
|
+
/* Sets local__ of each to a copy of the original,
|
|
19
|
+
so any mutated args aren't collapsed forward. */
|
|
20
|
+
|
|
21
|
+
test.localInitors = TestStages.#copier.copy(test.with);
|
|
22
|
+
test.localInputs = TestStages.#copier.copy(test.in);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
anyPreTargetingGroundwork(test) {
|
|
26
|
+
// Spoofing of class members here.
|
|
27
|
+
// Setting any static properties here.
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setLocalTarget(test) /* passed */ {
|
|
31
|
+
/* Target may be instance, prototype for constructors,
|
|
32
|
+
the class itself for statics, or a nonce for either
|
|
33
|
+
static or instance properties. */
|
|
34
|
+
|
|
35
|
+
if (test.isConstructorTest) {
|
|
36
|
+
test.localTarget = test.on.prototype;
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let callable = TestTuple.plainNameOf(test.of);
|
|
41
|
+
|
|
42
|
+
let target = test.isInstanceTest
|
|
43
|
+
? this.#supplyInstanceLocalTarget(test, callable)
|
|
44
|
+
: this.#supplyStaticLocalTarget(test, callable);
|
|
45
|
+
|
|
46
|
+
test.localTarget = target;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// region Dependencies of setLocalTarget()
|
|
50
|
+
|
|
51
|
+
#supplyStaticLocalTarget(test, callable) /* verified */ {
|
|
52
|
+
let type = test.on;
|
|
53
|
+
|
|
54
|
+
// Methods are called on class directly.
|
|
55
|
+
// Properties are called on class in nonce.
|
|
56
|
+
let target = test.isMethodTest
|
|
57
|
+
? type
|
|
58
|
+
: { localCallable: () => { return type[callable]; } };
|
|
59
|
+
|
|
60
|
+
return target;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
#supplyInstanceLocalTarget(test, callable) /* verified */ {
|
|
64
|
+
let instance = new test.on.prototype.constructor(...test.localInitors);
|
|
65
|
+
|
|
66
|
+
// Methods are called on instance directly.
|
|
67
|
+
// Properties are called on instance in nonce.
|
|
68
|
+
let target = test.isMethodTest
|
|
69
|
+
? instance
|
|
70
|
+
: { localCallable: () => { return instance[callable]; } };
|
|
71
|
+
|
|
72
|
+
return target;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// endregion Dependencies of setLocalTarget()
|
|
76
|
+
|
|
77
|
+
setLocalCallable(test) /* passed */ {
|
|
78
|
+
/* Method under test is a method named in test,
|
|
79
|
+
or a nonce method for a property test. */
|
|
80
|
+
|
|
81
|
+
test.localCallable = test.isMethodTest
|
|
82
|
+
? TestTuple.plainNameOf(test.method)
|
|
83
|
+
: TestTuple.nonceLocalCallableName;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
anyPostTargetingGroundwork(test) {
|
|
87
|
+
// Setting instance properties.
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
anyModifyActual(test) /* passed */ {
|
|
91
|
+
/* Original test.actual is used if a normal test, but replaced with .thrown
|
|
92
|
+
if a throw test, or result of supplier method if a retrieval test. */
|
|
93
|
+
|
|
94
|
+
if (test.isThrowTest) {
|
|
95
|
+
// May be undefined, if no throw.
|
|
96
|
+
test.actual = test.thrown;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (test.isRetrievalTest) {
|
|
100
|
+
test.actual = this.supplyNonReturnActual(test);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
compareResults(expected, actual) /* passed */ {
|
|
105
|
+
return TestStages.#comparer.compare(expected, actual);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
anyGroundworkReversion(test) {
|
|
109
|
+
// Unspoofing.
|
|
110
|
+
// Unsetting static properties.
|
|
111
|
+
// Undoing any other groundwork changes made.
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// region Dependencies of test stages
|
|
116
|
+
|
|
117
|
+
#anyOriginalPropertyGetting(target, settables) {
|
|
118
|
+
if (!Array.isArray(settables)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let unsettables = [ ];
|
|
123
|
+
|
|
124
|
+
for (let settable of settables) {
|
|
125
|
+
// Not a setter tuple.
|
|
126
|
+
if (!settable.of) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Retaining original.
|
|
131
|
+
let original = target[settable.of];
|
|
132
|
+
let unsettable = { of: settable.of, as: original };
|
|
133
|
+
unsettables.push(unsettable);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return unsettables;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#anyPropertySetting(target, settables) {
|
|
140
|
+
// No properties to set.
|
|
141
|
+
if (!Array.isArray(settables)) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for (let settable of settables) {
|
|
146
|
+
// Not a setter tuple.
|
|
147
|
+
if (!settable.of) {
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Actually setting property.
|
|
152
|
+
target[settable.of] = settable.as;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
#anyPropertyUnsetting(target, unsettables) {
|
|
157
|
+
// Unsetting is the same as setting,
|
|
158
|
+
// but with tuples of original values.
|
|
159
|
+
return this.#anyPropertySetting(target, unsettables);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
#compare(expected, actual) {
|
|
163
|
+
return this.#comparer.compare(expected, actual);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
supplyNonReturnActual(test) {
|
|
167
|
+
// When there is a .from that's a string,
|
|
168
|
+
// the actual is the named target member.
|
|
169
|
+
if (typeof test.from === "string") {
|
|
170
|
+
/* &cruft, maybe explain how this differs from setting .localTarget,
|
|
171
|
+
which can be a nonce, or else maybe make them the same */
|
|
172
|
+
|
|
173
|
+
// Common member host;
|
|
174
|
+
// undefined if static.
|
|
175
|
+
let host = test.target;
|
|
176
|
+
|
|
177
|
+
// When .and defines static.
|
|
178
|
+
if (test.isStaticTest) {
|
|
179
|
+
host = test.on;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return host[test.from];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/* &cruft, possibly change all .from syntax to (actual, test),
|
|
186
|
+
or maybe to (test), or else switch back args here */
|
|
187
|
+
// When there is a .from that's a function,
|
|
188
|
+
// the actual is the result of calling it,
|
|
189
|
+
// given everything that might be needed.
|
|
190
|
+
if (test.from instanceof Function) {
|
|
191
|
+
return test.from(test.actual, test.localTarget);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* &cruft, probably drop this, change maybe to a throw */
|
|
195
|
+
// When there is any other .from, the actual is the
|
|
196
|
+
// value of the code element provided as .from.
|
|
197
|
+
return test.from;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// endregion Dependencies of test stages
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
/* &cruft, remove or use this code... */
|
|
204
|
+
|
|
205
|
+
// anyOriginalPropertyGetting(target, settables) {
|
|
206
|
+
// if (!Array.isArray(settables)) {
|
|
207
|
+
// return;
|
|
208
|
+
// }
|
|
209
|
+
//
|
|
210
|
+
// let unsettables = [ ];
|
|
211
|
+
//
|
|
212
|
+
// for (let settable of settables) {
|
|
213
|
+
// // Not a setter tuple.
|
|
214
|
+
// if (!settable.of) {
|
|
215
|
+
// continue;
|
|
216
|
+
// }
|
|
217
|
+
//
|
|
218
|
+
// // Retaining original.
|
|
219
|
+
// let original = target[settable.of];
|
|
220
|
+
// let unsettable = { of: settable.of, as: original };
|
|
221
|
+
// unsettables.push(unsettable);
|
|
222
|
+
// }
|
|
223
|
+
//
|
|
224
|
+
// return unsettables;
|
|
225
|
+
// }
|
|
226
|
+
//
|
|
227
|
+
// anyPropertySetting(target, settables) {
|
|
228
|
+
// // No properties to set.
|
|
229
|
+
// if (!Array.isArray(settables)) {
|
|
230
|
+
// return;
|
|
231
|
+
// }
|
|
232
|
+
//
|
|
233
|
+
// for (let settable of settables) {
|
|
234
|
+
// // Not a setter tuple.
|
|
235
|
+
// if (!settable.of) {
|
|
236
|
+
// continue;
|
|
237
|
+
// }
|
|
238
|
+
//
|
|
239
|
+
// // Actually setting property.
|
|
240
|
+
// target[settable.of] = settable.as;
|
|
241
|
+
// }
|
|
242
|
+
// }
|
|
243
|
+
//
|
|
244
|
+
// anyPropertyUnsetting(target, unsettables) {
|
|
245
|
+
// // Unsetting is the same as setting,
|
|
246
|
+
// // but with tuples of original values.
|
|
247
|
+
// return this.anyPropertySetting(target, unsettables);
|
|
248
|
+
// }
|
|
249
|
+
//
|
|
250
|
+
// supplyNonReturnActual(test, target) {
|
|
251
|
+
// // When there is a .from that's a string,
|
|
252
|
+
// // the actual is the named target member.
|
|
253
|
+
// if (typeof test.from === "string") {
|
|
254
|
+
// // Common member host;
|
|
255
|
+
// // undefined if static.
|
|
256
|
+
// let host = target;
|
|
257
|
+
//
|
|
258
|
+
// // When .and defines static.
|
|
259
|
+
// if (test.isStaticTest) {
|
|
260
|
+
// host = test.on;
|
|
261
|
+
// }
|
|
262
|
+
//
|
|
263
|
+
// return host[test.from];
|
|
264
|
+
// }
|
|
265
|
+
//
|
|
266
|
+
// // When there is a .from that's a function,
|
|
267
|
+
// // the actual is the result of calling it,
|
|
268
|
+
// // given everything that might be needed.
|
|
269
|
+
// if (test.from instanceof Function) {
|
|
270
|
+
// return test.from(target, test);
|
|
271
|
+
// }
|
|
272
|
+
//
|
|
273
|
+
// // When there is any other .from, the actual is the
|
|
274
|
+
// // value of the code element provided as .from.
|
|
275
|
+
// return test.from;
|
|
276
|
+
// }
|
|
277
|
+
|
|
278
|
+
}
|