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,313 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
/* Lists tuples defining tests of Counter and other model code,
|
|
4
|
+
possibly along with any fixtures needed for those tests. */
|
|
5
|
+
|
|
6
|
+
import ATestSource from "../system/ATestSource.js"; // Path must match class used in TestFinder.
|
|
7
|
+
|
|
8
|
+
import Counter from "../test-target-objects/Counter.js";
|
|
9
|
+
import Sorter from "../test-target-objects/Sorter.js";
|
|
10
|
+
import Searcher from "../test-target-objects/Searcher.js";
|
|
11
|
+
import DomTarget from "../test-target-objects/DomTarget.js";
|
|
12
|
+
import StaticTarget from "../test-target-objects/StaticTarget.js";
|
|
13
|
+
import StateTarget from "../test-target-objects/StateTarget.js";
|
|
14
|
+
|
|
15
|
+
export default class TopicTests extends ATestSource {
|
|
16
|
+
// region Local test fixtures
|
|
17
|
+
|
|
18
|
+
getIntervalValues(interval, count, doPermute, doWrap) {
|
|
19
|
+
let values = [];
|
|
20
|
+
|
|
21
|
+
for (let of = 0; of < count; of++) {
|
|
22
|
+
let value = interval * of;
|
|
23
|
+
values.push(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (doPermute) {
|
|
27
|
+
/* Permuting order by pairing each value with a random value,
|
|
28
|
+
sorting on the random values, then dropping those again. */
|
|
29
|
+
|
|
30
|
+
let pairings = [];
|
|
31
|
+
|
|
32
|
+
for (let at = 0; at < values.length; at++) {
|
|
33
|
+
pairings.push({ value: values[at], order: Math.random() });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
pairings.sort((a, b) => a.order - b.order);
|
|
37
|
+
values = pairings.map(x => x.value);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (doWrap) {
|
|
41
|
+
return [ values ];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return values;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// endregion Local test fixtures
|
|
48
|
+
|
|
49
|
+
// region Tests
|
|
50
|
+
|
|
51
|
+
tests = [
|
|
52
|
+
/* Counter . howMany() */
|
|
53
|
+
{ on: Counter, with: [], of: "howMany" },
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
for: "Returns the right number for a repeated single character.", /* good */
|
|
57
|
+
in: [ "a b c a b c", "a" ], out: 2
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
for: "Returns the right number for a repeated string.", /* good */
|
|
61
|
+
in: [ "more text with more words", "more" ], out: 2
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
for: "Returns one for a target once at the start.", /* good */
|
|
65
|
+
in: [ "a b c d e f", "a" ], out: 1
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
for: "Returns one for a target once in the middle.", /* good */
|
|
69
|
+
in: [ "x b c a b c", "a" ], out: 1
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
for: "Returns one for a target once at the end.", /* good */
|
|
73
|
+
in: [ "a b x a b c", "c" ], out: 1
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
/* Trying out .type-restatement syntax. */
|
|
77
|
+
{ on: Counter, with: [], of: "howMany" },
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
for: "Returns one for a multi-character target present once.", /* good */
|
|
81
|
+
in: [ "some text with words", "text" ], out: 1
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
for: "When target is not present in subject, returns zero.", /* good */
|
|
85
|
+
in: [ "a b c a b c", "x" ], out: 0
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
/* Trying out .method-restatement syntax. */
|
|
89
|
+
{ of: "howMany" },
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
for: "When subject is empty, returns zero.", /* good */
|
|
93
|
+
in: [ "", "a" ], out: 0
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
for: "When target is empty, returns zero.", /* good */
|
|
97
|
+
in: [ "something", "" ], out: 0
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
for: "When both args are empty, returns zero.", /* good */
|
|
101
|
+
in: [ "", "" ], out: 0
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
for: "When only subject is provided, returns zero.", /* good */
|
|
105
|
+
in: [ "something" ], out: 0
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
for: "When no arguments are provided, returns zero.", /* good */
|
|
109
|
+
in: [], out: 0
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
for: "When subject is null, returns zero.", /* good */
|
|
113
|
+
in: [ null, "a" ], out: 0
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
for: "When target is null, returns zero.", /* good */
|
|
117
|
+
in: [ "something", null ], out: 0
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
for: "When both args are null, returns zero.", /* good */
|
|
121
|
+
in: [ null, null ], out: 0
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
/* Sorter */
|
|
125
|
+
{ on: Sorter, with: [] },
|
|
126
|
+
|
|
127
|
+
/* .countSort() */
|
|
128
|
+
{
|
|
129
|
+
for: "When given an unsorted array, returns the values sorted.", /* good */
|
|
130
|
+
of: "countSort",
|
|
131
|
+
in: [ [ 3, 2, 6, 4, 1, 5 ] ], out: [ 1, 2, 3, 4, 5, 6 ]
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
for: "When given a sorted array, returns the same sort order.", /* good */
|
|
135
|
+
in: [ [ 2, 4, 6, 8, 9, 10 ] ], out: [ 2, 4, 6, 8, 9, 10 ]
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
/* .mergeSort() */
|
|
139
|
+
{
|
|
140
|
+
for: "When given an unsorted array, returns the values sorted.", /* good */
|
|
141
|
+
of: "mergeSort",
|
|
142
|
+
in: [ [ 3, 2, 6, 4, 1, 5 ] ], out: [ 1, 2, 3, 4, 5, 6 ]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
for: "Sorts correctly when all stages are divisible by two.", /* good */
|
|
146
|
+
in: [ [ 3, 2, 6, 4, 1, 5, 8, 7 ] ],
|
|
147
|
+
out: [ 1, 2, 3, 4, 5, 6, 7, 8 ]
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
{
|
|
151
|
+
for: "Sorts interval values correctly.",
|
|
152
|
+
of: "mergeSort",
|
|
153
|
+
in: this.getIntervalValues(3, 10, true, true), out: this.getIntervalValues(3, 10, false, false)
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
{ on: Searcher, with: [], of: "findLinear" },
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
for: "When sought is present in subject, returns true.", /* good */
|
|
160
|
+
in: [ 3, [ 6, 2, 8, 1, 4, 4, 3, 7, 2, 9, 11 ] ], out: true
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
for: "When sought is not present, returns false.", /* good */
|
|
164
|
+
in: [ 10, [ 6, 2, 8, 1, 4, 4, 3, 7, 2, 9, 11 ] ], out: false
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
for: "When no subject is provided, returns false.", /* good */
|
|
168
|
+
in: [ 7 ], out: false
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
for: "When no sought is provided, returns false.", /* good */
|
|
172
|
+
in: [ undefined, [ 3, 8, 10 ] ], out: false
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
for: "When no args are provided, returns false.", /* good */
|
|
176
|
+
in: [], out: false
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
{ on: DomTarget, with: [ "spoof-id" ] },
|
|
180
|
+
|
|
181
|
+
{
|
|
182
|
+
for: "When an instance is inited, `id` arg is set as .id.", /* good */
|
|
183
|
+
of: "constructor",
|
|
184
|
+
plus: [ { of: "domNodeFrom" } ],
|
|
185
|
+
in: [ "arg-id" ],
|
|
186
|
+
out: "arg-id",
|
|
187
|
+
from: "id"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
for: "When an instance is inited, return value from domNodeFrom() is set as .node.", /* good */
|
|
191
|
+
of: "constructor",
|
|
192
|
+
plus: [ { of: "domNodeFrom", as: "returned-node" } ],
|
|
193
|
+
in: [ "arg-node" ],
|
|
194
|
+
out: "returned-node",
|
|
195
|
+
from: "node"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
for: "When changeDomItem() is called, its arg is the new .id.", /* good */
|
|
199
|
+
of: "changeDomItem",
|
|
200
|
+
plus: [ { of: "domNodeFrom" } ],
|
|
201
|
+
in: [ "new-id" ],
|
|
202
|
+
out: "new-id",
|
|
203
|
+
from: "id"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
for: "When changeDomItem() is called, domNodeFrom() changes .node based on the arg.", /* good */
|
|
207
|
+
of: "changeDomItem",
|
|
208
|
+
plus: [ { of: "domNodeFrom", as: (arg) => { return arg; } } ],
|
|
209
|
+
in: [ "new-node" ],
|
|
210
|
+
out: "new-node",
|
|
211
|
+
from: "node"
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
/* Tests of inline tuple-based spoofing for static methods, using StaticTarget. */
|
|
215
|
+
|
|
216
|
+
{ on: StaticTarget, with: [] },
|
|
217
|
+
|
|
218
|
+
{ for: "When a call is made to a static method with .and set, " +
|
|
219
|
+
"that method is invoked to return the right result.", /* good */
|
|
220
|
+
of: "multiplyThenDivide",
|
|
221
|
+
and: "static",
|
|
222
|
+
in: [ 3, 4, 2 ],
|
|
223
|
+
out: 6 /* (3 *4) ÷2 */ },
|
|
224
|
+
{ for: "When .and is set and .from is an arrow function, a value " +
|
|
225
|
+
"retrieved after a static method call is the right result.", /* good */
|
|
226
|
+
of: "setStaticProperty",
|
|
227
|
+
and: "static",
|
|
228
|
+
in: [ "static-was-set" ],
|
|
229
|
+
out: "static-was-set",
|
|
230
|
+
from: (target, test) => { return test.on.staticProperty; }
|
|
231
|
+
},
|
|
232
|
+
{ for: "When .and is not set and .from is an arrow function, a value " +
|
|
233
|
+
"retrieved after a static method call is the right result.", /* good */
|
|
234
|
+
of: "setStaticProperty",
|
|
235
|
+
and: [ ],
|
|
236
|
+
in: [ "was-set-to-static" ],
|
|
237
|
+
out: "was-set-to-static",
|
|
238
|
+
from: (target, test) => { return test.on.staticProperty; }
|
|
239
|
+
},
|
|
240
|
+
{ for: "When .and is set and .from is a static property name, a value " +
|
|
241
|
+
"retrieved after a static method call is the right result.", /* good */
|
|
242
|
+
of: "setStaticProperty",
|
|
243
|
+
and: "static",
|
|
244
|
+
in: [ "static-was-set" ],
|
|
245
|
+
out: "static-was-set",
|
|
246
|
+
from: "staticProperty"
|
|
247
|
+
},
|
|
248
|
+
{ for: "When .and is not set and .from is a static property name, a value " +
|
|
249
|
+
"retrieved after a static method call is the right result.", /* good */
|
|
250
|
+
of: "setStaticProperty",
|
|
251
|
+
and: [ ],
|
|
252
|
+
in: [ "was-set-to-static" ],
|
|
253
|
+
out: "was-set-to-static",
|
|
254
|
+
from: "staticProperty"
|
|
255
|
+
},
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
/* Tests of inline tuple-based spoofing, using CompositionModel. */
|
|
259
|
+
|
|
260
|
+
{ on: StateTarget, with: [] },
|
|
261
|
+
|
|
262
|
+
{ for: "When instance is constructed, .numberState is 1.", /* good */
|
|
263
|
+
of: "constructor",
|
|
264
|
+
from: "numberState",
|
|
265
|
+
in: [ ], out: 1 },
|
|
266
|
+
{ for: "When instance is constructed, .textState is \"1\".", /* good */
|
|
267
|
+
of: "constructor",
|
|
268
|
+
from: "textState",
|
|
269
|
+
in: [ ], out: "1" },
|
|
270
|
+
{ for: "When number is set, .numberState property has the chosen value.", /* good */
|
|
271
|
+
of: "setNumberState",
|
|
272
|
+
from: "numberState",
|
|
273
|
+
in: [ 77 ], out: 77 },
|
|
274
|
+
{ for: "When text is set, .textState has the chosen value.", /* good */
|
|
275
|
+
of: "setTextState",
|
|
276
|
+
from: "textState",
|
|
277
|
+
in: [ "This is some text." ], out: "This is some text." },
|
|
278
|
+
|
|
279
|
+
{ of: "changeNumberAndTextState" },
|
|
280
|
+
|
|
281
|
+
{ for: "When text and number are changed, .numberState matches the number arg.", /* good */
|
|
282
|
+
from: "numberState",
|
|
283
|
+
in: [ 2, "a phrase" ], out: 2 },
|
|
284
|
+
{ for: "When a change is made with property test.from before a test with .from of [], property is used.", /* good */
|
|
285
|
+
from: "textState",
|
|
286
|
+
in: [ 2, "a phrase" ], out: "a phrase" },
|
|
287
|
+
{ for: "When a change is made and test.from is [], not a retrieval, the return value is used.", /* good */
|
|
288
|
+
from: [ ],
|
|
289
|
+
in: [ 2, "a phrase" ], out: { number: 2, text: "a phrase" } },
|
|
290
|
+
{ for: "When a change is made with property test.from before a test with .from of { }, property is used.", /* good */
|
|
291
|
+
from: "numberState",
|
|
292
|
+
in: [ 2, "a phrase" ], out: 2 },
|
|
293
|
+
{ for: "When a change is made and test.from is { }, not a retrieval, the return value is used.", /* good */
|
|
294
|
+
from: { },
|
|
295
|
+
in: [ 2, "a phrase" ], out: { number: 2, text: "a phrase" } },
|
|
296
|
+
{ for: "When a change is made with property test.from before a test with .from of false, property is used.", /* good */
|
|
297
|
+
from: "textState",
|
|
298
|
+
in: [ 2, "a phrase" ], out: "a phrase" },
|
|
299
|
+
{ for: "When a change is made and test.from is false, not a retrieval, the return value is used.", /* good */
|
|
300
|
+
from: false,
|
|
301
|
+
in: [ 2, "a phrase" ], out: { number: 2, text: "a phrase" } },
|
|
302
|
+
{ for: "When a change is made with property test.from before a test with .from of \"\", property is used.", /* good */
|
|
303
|
+
from: "numberState",
|
|
304
|
+
in: [ 2, "a phrase" ], out: 2 },
|
|
305
|
+
{ for: "When a change is made and test.from is \"\", not a retrieval, the return value is used.", /* good */
|
|
306
|
+
from: "",
|
|
307
|
+
in: [ 2, "a phrase" ], out: { number: 2, text: "a phrase" } }
|
|
308
|
+
|
|
309
|
+
];
|
|
310
|
+
|
|
311
|
+
// endregion Tests
|
|
312
|
+
|
|
313
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import ASpoofingFixture from "../system/ASpoofingFixture.js";
|
|
4
|
+
import SpoofDef from "../system/SpoofDef.js";
|
|
5
|
+
import TotalComparer from "../system/TotalComparer.js";
|
|
6
|
+
import { expect } from "chai";
|
|
7
|
+
|
|
8
|
+
describe("ASpoofingFixture", () => {
|
|
9
|
+
/* All the tests here are valid as long as TotalComparer
|
|
10
|
+
and any linked objects are passing all their tests. */
|
|
11
|
+
let comparer = new TotalComparer();
|
|
12
|
+
|
|
13
|
+
/* Some cases here are effectively impossible to test directly in self-tests, at least
|
|
14
|
+
without complicated workarounds, because of how SpoofDef is used by Risei tests. */
|
|
15
|
+
|
|
16
|
+
describe("spoofMethod()", () => {
|
|
17
|
+
describe("Direct tests: Definition of spoofed method is compared.", () => {
|
|
18
|
+
it("Should return an empty method when not provided an arg.", /* good */ () => {
|
|
19
|
+
let target = new ASpoofingFixture();
|
|
20
|
+
|
|
21
|
+
let expected = () => { };
|
|
22
|
+
|
|
23
|
+
let actual = target.spoofMethod();
|
|
24
|
+
|
|
25
|
+
let comparison = comparer.compare(expected, actual);
|
|
26
|
+
expect(comparison).to.be.true;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("Should return an empty method when not provided undefined as arg.", /* good */ () => {
|
|
30
|
+
let target = new ASpoofingFixture();
|
|
31
|
+
|
|
32
|
+
let expected = () => { };
|
|
33
|
+
|
|
34
|
+
let actual = target.spoofMethod(undefined);
|
|
35
|
+
|
|
36
|
+
let comparison = comparer.compare(expected, actual);
|
|
37
|
+
expect(comparison).to.be.true;
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("Should return any whole function supplied as arg.", /* good */ () => {
|
|
41
|
+
let target = new ASpoofingFixture();
|
|
42
|
+
|
|
43
|
+
let expected = () => {
|
|
44
|
+
let sum = 6 + 5;
|
|
45
|
+
console.log(sum);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let actual = target.spoofMethod(expected);
|
|
49
|
+
|
|
50
|
+
let comparison = comparer.compare(expected, actual);
|
|
51
|
+
expect(comparison).to.be.true;
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("Should return a simple method naming the parameter when any non-function arg supplied.", /* good */ () => {
|
|
55
|
+
let target = new ASpoofingFixture();
|
|
56
|
+
|
|
57
|
+
let expected = () => { return spoofOutput; };
|
|
58
|
+
|
|
59
|
+
let actual = target.spoofMethod(778);
|
|
60
|
+
|
|
61
|
+
let comparison = comparer.compare(expected, actual);
|
|
62
|
+
expect(comparison).to.be.true;
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("Indirect tests: Result of calling spoofed method is tested.", () => {
|
|
67
|
+
it("Should return a simple method returning any value supplied as arg.", /* good */ () => {
|
|
68
|
+
let target = new ASpoofingFixture();
|
|
69
|
+
|
|
70
|
+
let expected = 322;
|
|
71
|
+
|
|
72
|
+
let spoofed = target.spoofMethod(322);
|
|
73
|
+
let actual = spoofed();
|
|
74
|
+
|
|
75
|
+
let comparison = comparer.compare(expected, actual);
|
|
76
|
+
expect(comparison).to.be.true;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it("Should return a simple method returning any string supplied as arg.", /* good */ () => {
|
|
80
|
+
let target = new ASpoofingFixture();
|
|
81
|
+
|
|
82
|
+
let expected = "A short text.";
|
|
83
|
+
|
|
84
|
+
let spoofed = target.spoofMethod("A short text.");
|
|
85
|
+
let actual = spoofed();
|
|
86
|
+
|
|
87
|
+
let comparison = comparer.compare(expected, actual);
|
|
88
|
+
expect(comparison).to.be.true;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("Should return a simple method returning any object supplied as arg.", /* good */ () => {
|
|
92
|
+
let target = new ASpoofingFixture();
|
|
93
|
+
|
|
94
|
+
let expected = { first: "a", second: 2, third: "C" };
|
|
95
|
+
|
|
96
|
+
let spoofed = target.spoofMethod({ first: "a", second: 2, third: "C" });
|
|
97
|
+
let actual = spoofed();
|
|
98
|
+
|
|
99
|
+
let comparison = comparer.compare(expected, actual);
|
|
100
|
+
expect(comparison).to.be.true;
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("Should return a simple method returning any specialized object supplied as arg.", /* good */ () => {
|
|
104
|
+
let target = new ASpoofingFixture();
|
|
105
|
+
|
|
106
|
+
let expected = new Map([[1, "g"], [2, "k"]]);
|
|
107
|
+
|
|
108
|
+
let spoofed = target.spoofMethod(new Map([[1, "g"], [2, "k"]]));
|
|
109
|
+
let actual = spoofed();
|
|
110
|
+
|
|
111
|
+
let comparison = comparer.compare(expected, actual);
|
|
112
|
+
expect(comparison).to.be.true;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("Should return a simple method returning any deep object supplied as arg", /* good */ () => {
|
|
116
|
+
let target = new ASpoofingFixture();
|
|
117
|
+
let arg = { these: { those: { the: { other: () => { return 44; } } } } };
|
|
118
|
+
|
|
119
|
+
let spoofed = target.spoofMethod(arg);
|
|
120
|
+
let actual = spoofed();
|
|
121
|
+
|
|
122
|
+
let expected = { these: { those: { the: { other: () => { return 44; } } } } };
|
|
123
|
+
|
|
124
|
+
let comparison = comparer.compare(expected, actual);
|
|
125
|
+
expect(comparison).to.be.true;
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("Should return a simple method returning any deep spoofed object defined in the arg.", /* good */ () => {
|
|
129
|
+
let target = new ASpoofingFixture();
|
|
130
|
+
let arg = [ { of: "these.those.the.other", as: 76 } ];
|
|
131
|
+
|
|
132
|
+
let spoofed = target.spoofMethod(arg);
|
|
133
|
+
let actual = spoofed();
|
|
134
|
+
|
|
135
|
+
let expected = { these: { those: { the: { other: () => { return spoofOutput; } } } } };
|
|
136
|
+
|
|
137
|
+
let comparison = comparer.compare(actual, expected);
|
|
138
|
+
expect(comparison).to.be.true;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe("spoofObjectTree()", () => {
|
|
145
|
+
it("Should return (object(empty method)) when given one part and no output.", /* good */ () => {
|
|
146
|
+
let target = new ASpoofingFixture();
|
|
147
|
+
let arg = [{ of: "action" }];
|
|
148
|
+
|
|
149
|
+
let expected = { action: () => { } };
|
|
150
|
+
|
|
151
|
+
let actual = target.spoofObjectTree(arg);
|
|
152
|
+
|
|
153
|
+
let comparison = comparer.compare(expected, actual);
|
|
154
|
+
expect(comparison).to.be.true;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it("Should return (object(object(empty method))) when given two parts and no output.", /* good */ () => {
|
|
158
|
+
let target = new ASpoofingFixture();
|
|
159
|
+
let arg = [{ of: "thing.action" }];
|
|
160
|
+
|
|
161
|
+
let expected = { thing: { action: () => { } } };
|
|
162
|
+
|
|
163
|
+
let actual = target.spoofObjectTree(arg);
|
|
164
|
+
|
|
165
|
+
let comparison = comparer.compare(expected, actual);
|
|
166
|
+
expect(comparison).to.be.true;
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it("Should return (object(object(object(empty method)))) when given three parts and no output.", /* good */ () => {
|
|
170
|
+
let target = new ASpoofingFixture()
|
|
171
|
+
let arg = [{ of: "outer.inner.action" }];
|
|
172
|
+
|
|
173
|
+
let expected = { outer: { inner: { action: () => { } } } };
|
|
174
|
+
|
|
175
|
+
let actual = target.spoofObjectTree(arg);
|
|
176
|
+
|
|
177
|
+
let comparison = comparer.compare(expected, actual);
|
|
178
|
+
expect(comparison).to.be.true;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it("Should return (object(value-returning method)) when given one part and an output value.", /* good */ () => {
|
|
182
|
+
let target = new ASpoofingFixture();
|
|
183
|
+
let arg = [{ of: "ten", as: 10 }];
|
|
184
|
+
|
|
185
|
+
let expected = { ten: () => { return spoofOutput; } };
|
|
186
|
+
|
|
187
|
+
let actual = target.spoofObjectTree(arg);
|
|
188
|
+
|
|
189
|
+
let comparison = comparer.compare(expected, actual);
|
|
190
|
+
expect(comparison).to.be.true;
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it("Should return (object(object(value-returning method))) when given two parts and an output value.", /* good */ () => {
|
|
194
|
+
let target = new ASpoofingFixture();
|
|
195
|
+
let arg = [{ of: "thing.eleven", as: 11 }];
|
|
196
|
+
|
|
197
|
+
let expected = { thing: { eleven: () => { return spoofOutput; } } };
|
|
198
|
+
|
|
199
|
+
let actual = target.spoofObjectTree(arg);
|
|
200
|
+
|
|
201
|
+
let comparison = comparer.compare(expected, actual);
|
|
202
|
+
expect(comparison).to.be.true;
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("Should return (object(object(object(value-returning method)))) when given three parts and an output value.", /* good */ () => {
|
|
206
|
+
let target = new ASpoofingFixture();
|
|
207
|
+
let arg = [{ of: "outer.inner.twelve", as: 12 }];
|
|
208
|
+
|
|
209
|
+
let expected = { outer: { inner: { twelve: () => { return spoofOutput; } } } };
|
|
210
|
+
|
|
211
|
+
let actual = target.spoofObjectTree(arg);
|
|
212
|
+
|
|
213
|
+
let comparison = comparer.compare(expected, actual);
|
|
214
|
+
expect(comparison).to.be.true;
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("Should return (object(object(string-returning method))) when given two parts and an output string.", /* good */ () => {
|
|
218
|
+
let target = new ASpoofingFixture();
|
|
219
|
+
let arg = [{ of: "thing.outputText", as: "text-output" }];
|
|
220
|
+
|
|
221
|
+
let expected = { thing: { outputText: () => { return spoofOutput; } } };
|
|
222
|
+
|
|
223
|
+
let actual = target.spoofObjectTree(arg);
|
|
224
|
+
|
|
225
|
+
let comparison = comparer.compare(expected, actual);
|
|
226
|
+
expect(comparison).to.be.true;
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("Should return (object(object(nonce method))) when given two parts and a nonce method.", /* good */ () => {
|
|
230
|
+
let target = new ASpoofingFixture();
|
|
231
|
+
let arg = [{ of: "thing.sumIsFourteen", as: () => { return 11 + 3; } }];
|
|
232
|
+
|
|
233
|
+
let expected = { thing: { sumIsFourteen: () => { return 11 + 3; } } };
|
|
234
|
+
|
|
235
|
+
let actual = target.spoofObjectTree(arg);
|
|
236
|
+
|
|
237
|
+
let comparison = comparer.compare(expected, actual);
|
|
238
|
+
expect(comparison).to.be.true;
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
});
|
|
242
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**/
|
|
2
|
+
|
|
3
|
+
import MethodSpoofer from "../system/MethodSpoofer.js";
|
|
4
|
+
import Spoofable from "../test-target-objects/Spoofable.js";
|
|
5
|
+
import TotalComparer from "../system/TotalComparer.js";
|
|
6
|
+
|
|
7
|
+
import { expect } from "chai";
|
|
8
|
+
|
|
9
|
+
describe("MethodSpoofer", () => {
|
|
10
|
+
let comparer = new TotalComparer();
|
|
11
|
+
|
|
12
|
+
describe("spoof()", () => {
|
|
13
|
+
describe("Direct tests: Definition of spoofed method is compared.", () => {
|
|
14
|
+
it("Should set class method to be empty when given args which define that.", /* good */ () => {
|
|
15
|
+
let target = new MethodSpoofer();
|
|
16
|
+
let definition = { of: "spoofNumber" };
|
|
17
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
18
|
+
|
|
19
|
+
target.spoof(arg);
|
|
20
|
+
|
|
21
|
+
let actual = Spoofable.prototype.spoofNumber;
|
|
22
|
+
|
|
23
|
+
target.unspoof();
|
|
24
|
+
|
|
25
|
+
let comparison = comparer.compare(actual, () => { });
|
|
26
|
+
expect(comparison).to.be.true;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("Should set class method to a known nonce function when given that nonce as an arg.", /* good */ () => {
|
|
30
|
+
let target = new MethodSpoofer();
|
|
31
|
+
let definition = { of: "spoofNumber", as: (a, b) => { return b - a; } };
|
|
32
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
33
|
+
|
|
34
|
+
target.spoof(arg);
|
|
35
|
+
|
|
36
|
+
let actual = Spoofable.prototype.spoofNumber;
|
|
37
|
+
|
|
38
|
+
target.unspoof();
|
|
39
|
+
|
|
40
|
+
let comparison = comparer.compare(actual, (a, b) => { return b - a; });
|
|
41
|
+
expect(comparison).to.be.true;
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("Should set class method to a simple function returning a named parameter when given args which define that.", /* good */ () => {
|
|
45
|
+
let target = new MethodSpoofer();
|
|
46
|
+
let definition = { of: "spoofNumber" , as: 32 };
|
|
47
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
48
|
+
|
|
49
|
+
target.spoof(arg);
|
|
50
|
+
|
|
51
|
+
let actual = Spoofable.prototype.spoofNumber;
|
|
52
|
+
|
|
53
|
+
target.unspoof();
|
|
54
|
+
|
|
55
|
+
let comparison = comparer.compare(actual, () => { return spoofOutput; });
|
|
56
|
+
expect(comparison).to.be.true;
|
|
57
|
+
});
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
describe("Indirect tests: Result of calling spoofed method is compared.", () => {
|
|
61
|
+
it("Should set class method to return a known value when given args which define that.", /* good */ () => {
|
|
62
|
+
let target = new MethodSpoofer();
|
|
63
|
+
let definition = { of: "spoofNumber", as: 17 };
|
|
64
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
65
|
+
|
|
66
|
+
target.spoof(arg);
|
|
67
|
+
|
|
68
|
+
let spoofed = Spoofable.prototype.spoofNumber;
|
|
69
|
+
let actual = spoofed();
|
|
70
|
+
|
|
71
|
+
target.unspoof();
|
|
72
|
+
|
|
73
|
+
let comparison = comparer.compare(actual, 17);
|
|
74
|
+
expect(comparison).to.be.true;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("Should set class method to return a known string when given args which define that.", /* good */ () => {
|
|
78
|
+
let target = new MethodSpoofer();
|
|
79
|
+
let definition = { of: "spoofText", as: "return-text" };
|
|
80
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
81
|
+
|
|
82
|
+
target.spoof(arg);
|
|
83
|
+
|
|
84
|
+
let spoofed = Spoofable.prototype.spoofText;
|
|
85
|
+
let actual = spoofed();
|
|
86
|
+
|
|
87
|
+
target.unspoof();
|
|
88
|
+
|
|
89
|
+
let comparison = comparer.compare(actual, "return-text");
|
|
90
|
+
expect(comparison).to.be.true;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("Should set class method to return a known object when given args which define that.", /* good */ () => {
|
|
94
|
+
let target = new MethodSpoofer();
|
|
95
|
+
let definition = { of: "spoofText", as: { first: "one", second: "two" } };
|
|
96
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
97
|
+
|
|
98
|
+
target.spoof(arg);
|
|
99
|
+
|
|
100
|
+
let spoofed = Spoofable.prototype.spoofText;
|
|
101
|
+
let actual = spoofed();
|
|
102
|
+
|
|
103
|
+
target.unspoof();
|
|
104
|
+
|
|
105
|
+
let comparison = comparer.compare(actual, { first: "one", second: "two" });
|
|
106
|
+
expect(comparison).to.be.true;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("Should set class method to return a deep spoofed object when given args which define that.", /* good */ () => {
|
|
110
|
+
let target = new MethodSpoofer();
|
|
111
|
+
let definition = { of: "spoofNumber", as: [ { of: "these.those.the.other", as: 76 } ] };
|
|
112
|
+
let arg = { on: Spoofable, plus: [ definition ] };
|
|
113
|
+
|
|
114
|
+
target.spoof(arg);
|
|
115
|
+
|
|
116
|
+
let spoofed = Spoofable.prototype.spoofNumber;
|
|
117
|
+
let actual = spoofed();
|
|
118
|
+
|
|
119
|
+
target.unspoof();
|
|
120
|
+
|
|
121
|
+
let expected = { these: { those: { the: { other: () => { return spoofOutput; } } } } };
|
|
122
|
+
|
|
123
|
+
let comparison = comparer.compare(actual, expected);
|
|
124
|
+
expect(comparison).to.be.true;
|
|
125
|
+
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|