nole 2.2.1 → 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 +142 -236
- package/bin/nole.js +44 -42
- package/dist/const.d.ts +8 -0
- package/dist/const.d.ts.map +1 -0
- package/dist/const.js +9 -0
- package/dist/core.d.ts +22 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +56 -0
- package/dist/dynamic.d.ts +4 -1
- package/dist/dynamic.d.ts.map +1 -1
- package/dist/dynamic.js +35 -11
- package/dist/handle/after-each-hooks.d.ts +3 -0
- package/dist/handle/after-each-hooks.d.ts.map +1 -0
- package/dist/handle/after-each-hooks.js +26 -0
- package/dist/handle/after-hooks.d.ts +3 -0
- package/dist/handle/after-hooks.d.ts.map +1 -0
- package/dist/handle/after-hooks.js +24 -0
- package/dist/handle/before-each-hooks.d.ts +3 -0
- package/dist/handle/before-each-hooks.d.ts.map +1 -0
- package/dist/handle/before-each-hooks.js +26 -0
- package/dist/handle/before-hooks.d.ts +3 -0
- package/dist/handle/before-hooks.d.ts.map +1 -0
- package/dist/handle/before-hooks.js +24 -0
- package/dist/handle/cleanup-hooks.d.ts +3 -0
- package/dist/handle/cleanup-hooks.d.ts.map +1 -0
- package/dist/handle/cleanup-hooks.js +34 -0
- package/dist/handle/specs.d.ts +3 -0
- package/dist/handle/specs.d.ts.map +1 -0
- package/dist/handle/specs.js +41 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/run.d.ts +7 -6
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +201 -239
- package/dist/symbol.d.ts +2 -0
- package/dist/symbol.d.ts.map +1 -0
- package/dist/symbol.js +2 -0
- package/dist/test-wrap.d.ts +37 -0
- package/dist/test-wrap.d.ts.map +1 -0
- package/dist/test-wrap.js +30 -0
- package/dist/utils/executor.d.ts +1 -1
- package/dist/utils/executor.js +20 -20
- package/dist/utils/executor.test.d.ts +7 -5
- package/dist/utils/executor.test.d.ts.map +1 -1
- package/dist/utils/executor.test.js +22 -49
- package/dist/utils/time_difference.d.ts +15 -6
- package/dist/utils/time_difference.d.ts.map +1 -1
- package/dist/utils/time_difference.js +22 -13
- package/dist/utils/time_difference.test.d.ts +5 -3
- package/dist/utils/time_difference.test.d.ts.map +1 -1
- package/dist/utils/time_difference.test.js +11 -24
- package/dist/utils/time_factor.d.ts +3 -3
- package/dist/utils/time_factor.d.ts.map +1 -1
- package/dist/utils/time_factor.js +26 -27
- package/dist/utils/time_factor.test.d.ts +5 -3
- package/dist/utils/time_factor.test.d.ts.map +1 -1
- package/dist/utils/time_factor.test.js +27 -42
- package/package.json +11 -8
- package/src/const.ts +11 -0
- package/src/core.ts +89 -0
- package/src/dynamic.ts +43 -1
- package/src/handle/after-each-hooks.ts +41 -0
- package/src/handle/after-hooks.ts +38 -0
- package/src/handle/before-each-hooks.ts +40 -0
- package/src/handle/before-hooks.ts +39 -0
- package/src/handle/cleanup-hooks.ts +55 -0
- package/src/handle/specs.ts +68 -0
- package/src/index.ts +3 -13
- package/src/run.ts +184 -256
- package/src/symbol.ts +1 -0
- package/src/{test.ts → test-wrap.ts} +13 -12
- package/src/utils/executor.test.ts +2 -5
- package/src/utils/executor.ts +1 -1
- package/src/utils/time_difference.test.ts +2 -3
- package/src/utils/time_factor.test.ts +2 -3
- package/src/utils/time_factor.ts +1 -3
- package/test/basic.test.ts +8 -9
- package/test/before.test.ts +14 -27
- package/test/clean-up.test.ts +12 -16
- package/test/dynamic-skip.test.ts +2 -4
- package/test/dynamic.test.ts +23 -8
- package/test/extend.test.ts +43 -0
- package/test/hook.test.ts +9 -10
- package/test/multi-dependency.test.ts +25 -27
- package/test/multiple-uppercased-chars.test.ts +8 -7
- package/test/skip-all.test.ts +4 -13
- package/test/turkish-chars.test.ts +8 -7
- package/tsconfig.json +9 -18
- package/dist/data.d.ts +0 -3
- package/dist/data.d.ts.map +0 -1
- package/dist/data.js +0 -9
- package/dist/data.js.map +0 -1
- package/dist/decorators.d.ts +0 -9
- package/dist/decorators.d.ts.map +0 -1
- package/dist/decorators.js +0 -118
- package/dist/decorators.js.map +0 -1
- package/dist/dynamic.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/run.js.map +0 -1
- package/dist/test.d.ts +0 -39
- package/dist/test.d.ts.map +0 -1
- package/dist/test.js +0 -25
- package/dist/test.js.map +0 -1
- package/dist/utils/executor.js.map +0 -1
- package/dist/utils/executor.test.js.map +0 -1
- package/dist/utils/time_difference.js.map +0 -1
- package/dist/utils/time_difference.test.js.map +0 -1
- package/dist/utils/time_factor.js.map +0 -1
- package/dist/utils/time_factor.test.js.map +0 -1
- package/src/data.ts +0 -13
- package/src/decorators.ts +0 -208
package/src/run.ts
CHANGED
|
@@ -1,331 +1,259 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
orderDebug: boolean;
|
|
19
|
-
}
|
|
1
|
+
import { HookType, TestWrap } from "./test-wrap.js";
|
|
2
|
+
import { BaseTest, type TestClassInfo } from "./core.js";
|
|
3
|
+
import { TEST_CLASS_KEY } from "./symbol.js";
|
|
4
|
+
import { handleBeforeHooks } from "./handle/before-hooks.js";
|
|
5
|
+
import { handleSpecs } from "./handle/specs.js";
|
|
6
|
+
import { handleAfterHooks } from "./handle/after-hooks.js";
|
|
7
|
+
import { handleCleanUp } from "./handle/cleanup-hooks.js";
|
|
8
|
+
import { colors, FAILED_TEXT } from "./const.js";
|
|
9
|
+
|
|
10
|
+
let allTests: Map<new () => BaseTest, TestWrap> = new Map();
|
|
11
|
+
let notTestedYet: Map<new () => BaseTest, TestWrap> = new Map();
|
|
12
|
+
|
|
13
|
+
export async function ManualRun(originalTests: Set<new () => BaseTest>) {
|
|
14
|
+
for (let test of originalTests) {
|
|
15
|
+
if (allTests.has(test)) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
const wrap = new TestWrap(test);
|
|
20
|
+
|
|
21
|
+
allTests.set(test, wrap);
|
|
22
|
+
notTestedYet.set(test, wrap);
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
extractInformationFromClasses(notTestedYet);
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
if (!notTestedYet.size) {
|
|
28
|
+
throw new Error("No specs found");
|
|
29
|
+
}
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
throw new Error("No specs found");
|
|
35
|
-
}
|
|
31
|
+
while (notTestedYet.size) {
|
|
32
|
+
let entry = pickNext(notTestedYet);
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
if (entry) {
|
|
35
|
+
let test = entry[1];
|
|
36
|
+
// console.log(colors.bold(colors.cyan(`Running test: ${test.name}`)));
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
HandleDependencies(test);
|
|
38
|
+
notTestedYet.delete(test.target);
|
|
39
|
+
createInstanceIfNotExists(test);
|
|
40
|
+
handleDependencies(test);
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
await handleBeforeHooks(test);
|
|
43
|
+
await handleSpecs(test);
|
|
44
|
+
await handleAfterHooks(test);
|
|
48
45
|
|
|
49
|
-
|
|
46
|
+
test.isFinished = true;
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
DependencyLock(hashMap);
|
|
56
|
-
}
|
|
48
|
+
if (test.dependents.length == 0) {
|
|
49
|
+
await handleCleanUp(test);
|
|
57
50
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
} catch (e) {
|
|
61
|
-
reject(e);
|
|
51
|
+
} else {
|
|
52
|
+
dependencyLock(notTestedYet);
|
|
62
53
|
}
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function PickNextTestFromHashMap(hashMap: Map<any, Test>) {
|
|
67
|
-
for (let test of hashMap.values()) {
|
|
68
|
-
if (test.isFinished) continue;
|
|
69
|
-
if (!test.dependencies.every((x) => x.dependency.isFinished)) continue;
|
|
70
|
-
|
|
71
|
-
return test;
|
|
72
54
|
}
|
|
73
55
|
}
|
|
74
56
|
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
function extractInformationFromClasses(
|
|
58
|
+
tests: Map<new () => BaseTest, TestWrap>,
|
|
59
|
+
) {
|
|
60
|
+
for (let [target, test] of tests.entries()) {
|
|
61
|
+
updateInformationForClass(target, test, tests);
|
|
78
62
|
}
|
|
79
63
|
}
|
|
80
64
|
|
|
81
|
-
function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
65
|
+
export function updateInformationForClass(
|
|
66
|
+
target: new () => BaseTest,
|
|
67
|
+
test: TestWrap,
|
|
68
|
+
tests: Map<new () => BaseTest, TestWrap>,
|
|
69
|
+
) {
|
|
70
|
+
const config = target[TEST_CLASS_KEY] as TestClassInfo;
|
|
71
|
+
|
|
72
|
+
if (config.skip) {
|
|
73
|
+
test.skipClass = { reason: config.skip };
|
|
85
74
|
}
|
|
86
|
-
}
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
76
|
+
test.dependencies = config.dependencies
|
|
77
|
+
? Array.from(
|
|
78
|
+
config.dependencies.entries().map(([key, dep]) => {
|
|
79
|
+
const actual = dep();
|
|
80
|
+
let testWrap = tests.get(actual);
|
|
91
81
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
if (!testWrap) {
|
|
83
|
+
testWrap = new TestWrap(actual);
|
|
84
|
+
tests.set(actual, testWrap);
|
|
85
|
+
allTests.set(actual, testWrap);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
testWrap.dependents.push(test);
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
propertyKey: key,
|
|
92
|
+
dependency: testWrap,
|
|
93
|
+
};
|
|
94
|
+
}),
|
|
96
95
|
)
|
|
97
|
-
|
|
96
|
+
: [];
|
|
97
|
+
|
|
98
|
+
if (config.before) {
|
|
99
|
+
const beforeTests = config.before();
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
await Executor(
|
|
102
|
-
test.testInstance[propertyKey].bind(test.testInstance),
|
|
103
|
-
hook.timeout
|
|
104
|
-
);
|
|
105
|
-
} else {
|
|
106
|
-
let timeText = TimeFactor(0, hook.timeout);
|
|
101
|
+
for (let i = 0; i < beforeTests.length; i++) {
|
|
102
|
+
const actual = beforeTests[i];
|
|
107
103
|
|
|
108
|
-
|
|
104
|
+
let testWrap = tests.get(actual);
|
|
105
|
+
|
|
106
|
+
if (!testWrap) {
|
|
107
|
+
testWrap = new TestWrap(actual);
|
|
108
|
+
tests.set(actual, testWrap);
|
|
109
|
+
allTests.set(actual, testWrap);
|
|
109
110
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
|
|
112
|
+
testWrap.dependencies.push({
|
|
113
|
+
propertyKey: "_before_" + i,
|
|
114
|
+
dependency: test,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test.dependents.push(testWrap);
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
|
-
}
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let
|
|
122
|
-
|
|
123
|
-
test.name +
|
|
124
|
-
(propertyKey != "beforeEach"
|
|
125
|
-
? `.${propertyKey}:beforeEach`
|
|
126
|
-
: ":beforeEach")
|
|
127
|
-
)
|
|
128
|
-
);
|
|
121
|
+
if (config.after) {
|
|
122
|
+
const afterTests = config.after();
|
|
123
|
+
|
|
124
|
+
for (let i = 0; i < afterTests.length; i++) {
|
|
125
|
+
const actual = afterTests[i];
|
|
129
126
|
|
|
130
|
-
|
|
131
|
-
if (!options.orderDebug) {
|
|
132
|
-
await Executor(
|
|
133
|
-
test.testInstance[propertyKey].bind(test.testInstance),
|
|
134
|
-
hook.timeout
|
|
135
|
-
);
|
|
136
|
-
} else {
|
|
137
|
-
let timeText = TimeFactor(0, hook.timeout);
|
|
127
|
+
let testWrap = tests.get(actual);
|
|
138
128
|
|
|
139
|
-
|
|
129
|
+
if (!testWrap) {
|
|
130
|
+
testWrap = new TestWrap(actual);
|
|
131
|
+
tests.set(actual, testWrap);
|
|
132
|
+
allTests.set(actual, testWrap);
|
|
140
133
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
134
|
+
|
|
135
|
+
test.dependencies.push({
|
|
136
|
+
propertyKey: "_after_" + i,
|
|
137
|
+
dependency: testWrap,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
testWrap.dependents.push(test);
|
|
145
141
|
}
|
|
146
142
|
}
|
|
147
143
|
}
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
for (let
|
|
151
|
-
|
|
145
|
+
function pickNext(tests: Map<new () => BaseTest, TestWrap>) {
|
|
146
|
+
for (let entry of tests.entries()) {
|
|
147
|
+
let test = entry[1];
|
|
148
|
+
if (test.isFinished) continue;
|
|
149
|
+
if (!test.dependencies.every((x) => x.dependency.isFinished)) continue;
|
|
152
150
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(propertyKey != "afterEach"
|
|
157
|
-
? `.${propertyKey}:afterEach`
|
|
158
|
-
: ":afterEach")
|
|
159
|
-
)
|
|
160
|
-
);
|
|
151
|
+
return entry;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
161
154
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
test.testInstance[propertyKey].bind(test.testInstance),
|
|
166
|
-
hook.timeout
|
|
167
|
-
);
|
|
168
|
-
} else {
|
|
169
|
-
let timeText = TimeFactor(0, hook.timeout);
|
|
155
|
+
export function createInstanceIfNotExists(test: TestWrap) {
|
|
156
|
+
if (!test.testInstance) {
|
|
157
|
+
const instance = new test.target();
|
|
170
158
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
159
|
+
test.testInstance = instance;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!test.specDetection) {
|
|
163
|
+
specDetection(test);
|
|
164
|
+
test.specDetection = true;
|
|
178
165
|
}
|
|
179
166
|
}
|
|
180
167
|
|
|
181
|
-
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
let testName = colors.bold(colors.yellow(test.name + "." + propertyKey));
|
|
186
|
-
|
|
187
|
-
const shouldPropertySkip = test.skip.has(propertyKey);
|
|
188
|
-
if (shouldPropertySkip || test.skipClass) {
|
|
189
|
-
let reason = shouldPropertySkip
|
|
190
|
-
? test.skip.get(propertyKey)!.reason
|
|
191
|
-
: test.skipClass!.reason;
|
|
192
|
-
log(
|
|
193
|
-
`${SKIP_TEXT} ${" ".repeat(9)} ${testName}() ${
|
|
194
|
-
reason ? "{" + reason + "}" : ""
|
|
195
|
-
}`
|
|
196
|
-
);
|
|
168
|
+
function specDetection(test: TestWrap) {
|
|
169
|
+
const instance = test.testInstance;
|
|
170
|
+
for (let key of getAllMethods(instance)) {
|
|
171
|
+
if (typeof key !== "string") {
|
|
197
172
|
continue;
|
|
198
173
|
}
|
|
199
174
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
let start = TimeDifference.begin();
|
|
175
|
+
let lowerKey = key.toLowerCase();
|
|
203
176
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
test.testInstance[propertyKey].bind(test.testInstance),
|
|
208
|
-
spec.timeout
|
|
209
|
-
);
|
|
210
|
-
}
|
|
177
|
+
if (lowerKey.startsWith("skip")) {
|
|
178
|
+
test.skip.set(key, { reason: "marked as skipped" });
|
|
179
|
+
}
|
|
211
180
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
181
|
+
if (
|
|
182
|
+
lowerKey.startsWith("hook") ||
|
|
183
|
+
lowerKey === "cleanup" ||
|
|
184
|
+
lowerKey === "before" ||
|
|
185
|
+
lowerKey === "after" ||
|
|
186
|
+
lowerKey === "beforeeach" ||
|
|
187
|
+
lowerKey === "aftereach"
|
|
188
|
+
) {
|
|
189
|
+
let type = HookType.Before;
|
|
190
|
+
|
|
191
|
+
if (lowerKey.endsWith("before")) {
|
|
192
|
+
type = HookType.Before;
|
|
193
|
+
} else if (lowerKey.endsWith("after")) {
|
|
194
|
+
type = HookType.After;
|
|
195
|
+
} else if (lowerKey.endsWith("beforeeach")) {
|
|
196
|
+
type = HookType.BeforeEach;
|
|
197
|
+
} else if (lowerKey.endsWith("aftereach")) {
|
|
198
|
+
type = HookType.AfterEach;
|
|
199
|
+
} else if (lowerKey.endsWith("cleanup")) {
|
|
200
|
+
type = HookType.CleanUp;
|
|
224
201
|
}
|
|
225
202
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.error(`${FAILED_TEXT} ${timeText} ${testName}()`);
|
|
229
|
-
console.error((e as any)?.stack ?? e);
|
|
230
|
-
throw e;
|
|
203
|
+
test.hooks.set(key, { type });
|
|
204
|
+
continue;
|
|
231
205
|
}
|
|
232
206
|
|
|
233
|
-
|
|
207
|
+
test.specs.set(key, {});
|
|
234
208
|
}
|
|
235
209
|
}
|
|
236
210
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
let hookName = colors.bold(
|
|
242
|
-
colors.yellow(
|
|
243
|
-
test.name +
|
|
244
|
-
(propertyKey != "after" ? `.${propertyKey}:after` : ":after")
|
|
245
|
-
)
|
|
246
|
-
);
|
|
211
|
+
function getAllMethods(instance) {
|
|
212
|
+
let props = new Set();
|
|
213
|
+
let currentObj = instance;
|
|
247
214
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
hook.timeout
|
|
253
|
-
);
|
|
254
|
-
} else {
|
|
255
|
-
let timeText = TimeFactor(0, hook.timeout);
|
|
256
|
-
|
|
257
|
-
options.log(`${OK_TEXT} ${timeText} ${hookName}()`);
|
|
215
|
+
while (currentObj && currentObj !== Object.prototype) {
|
|
216
|
+
Object.getOwnPropertyNames(currentObj).forEach((prop) => {
|
|
217
|
+
if (typeof currentObj[prop] === "function" && prop !== "constructor") {
|
|
218
|
+
props.add(prop);
|
|
258
219
|
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
console.error((e as any)?.stack ?? e);
|
|
262
|
-
throw e;
|
|
263
|
-
}
|
|
220
|
+
});
|
|
221
|
+
currentObj = Object.getPrototypeOf(currentObj);
|
|
264
222
|
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
async function HandleCleanUp(test: Test, options: Options) {
|
|
268
|
-
if (test.cleanUpCalled) return;
|
|
269
|
-
if (
|
|
270
|
-
!test.dependents.every(
|
|
271
|
-
(dependent) => dependent.isFinished && dependent.cleanUpCalled
|
|
272
|
-
)
|
|
273
|
-
)
|
|
274
|
-
return;
|
|
275
223
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const log = options.log;
|
|
279
|
-
|
|
280
|
-
for (let [propertyKey, hook] of test.hooks.entries()) {
|
|
281
|
-
if (hook.type != HookType.CleanUp) continue;
|
|
282
|
-
|
|
283
|
-
let hookName = colors.bold(
|
|
284
|
-
colors.yellow(
|
|
285
|
-
test.name +
|
|
286
|
-
(propertyKey != "cleanUp" ? `.${propertyKey}:cleanUp` : ":cleanUp")
|
|
287
|
-
)
|
|
288
|
-
);
|
|
289
|
-
let start = TimeDifference.begin();
|
|
290
|
-
|
|
291
|
-
try {
|
|
292
|
-
if (!options.orderDebug) {
|
|
293
|
-
await Executor(
|
|
294
|
-
test.testInstance[propertyKey].bind(test.testInstance),
|
|
295
|
-
hook.timeout
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
let timeText = TimeFactor(start.end(), hook.timeout);
|
|
300
|
-
|
|
301
|
-
log(`${OK_TEXT} ${timeText} ${hookName}()`);
|
|
302
|
-
} catch (e) {
|
|
303
|
-
console.error(`${HOOK_FAILED_TEXT} ${hookName}()`);
|
|
304
|
-
console.error((e as any)?.stack ?? e);
|
|
305
|
-
throw e;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
224
|
+
return Array.from(props);
|
|
225
|
+
}
|
|
308
226
|
|
|
309
|
-
|
|
310
|
-
|
|
227
|
+
function handleDependencies(test: TestWrap) {
|
|
228
|
+
for (let dependency of test.dependencies) {
|
|
229
|
+
test.testInstance[dependency.propertyKey] =
|
|
230
|
+
dependency.dependency.testInstance;
|
|
311
231
|
}
|
|
312
232
|
}
|
|
313
233
|
|
|
314
|
-
function
|
|
234
|
+
function dependencyLock(tests: Map<new () => BaseTest, TestWrap>) {
|
|
315
235
|
console.error(
|
|
316
236
|
FAILED_TEXT +
|
|
317
|
-
colors.red("Looks like there is confict issue for dependency resolving!")
|
|
237
|
+
colors.red("Looks like there is confict issue for dependency resolving!"),
|
|
318
238
|
);
|
|
319
239
|
|
|
320
240
|
console.error("Possible conflicts;");
|
|
321
|
-
for (let test of
|
|
241
|
+
for (let [, test] of tests) {
|
|
322
242
|
console.error(
|
|
323
243
|
`- class ${test.name} { ${test.dependencies
|
|
324
244
|
.filter((x) => !x.dependency.isFinished)
|
|
325
245
|
.map((x) => `@Dependency(${x.dependency.name}) ${x.propertyKey}`)
|
|
326
|
-
.join(", ")} }
|
|
246
|
+
.join(", ")} }`,
|
|
327
247
|
);
|
|
328
248
|
}
|
|
329
249
|
|
|
330
250
|
throw new Error("Dependency lock occurred!");
|
|
331
251
|
}
|
|
252
|
+
|
|
253
|
+
export function getTestMap() {
|
|
254
|
+
return allTests;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function getFutureTestMap() {
|
|
258
|
+
return notTestedYet;
|
|
259
|
+
}
|
package/src/symbol.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TEST_CLASS_KEY = Symbol("TEST_CLASS_KEY");
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
import { BaseTest, type TestClassInfo } from "./core.js";
|
|
2
|
+
import { TEST_CLASS_KEY } from "./symbol.js";
|
|
3
|
+
|
|
1
4
|
export interface IDependency {
|
|
2
5
|
propertyKey: string;
|
|
3
|
-
dependency:
|
|
6
|
+
dependency: TestWrap;
|
|
4
7
|
}
|
|
5
8
|
|
|
6
|
-
export interface ISpec {
|
|
7
|
-
timeout: number;
|
|
8
|
-
}
|
|
9
|
+
export interface ISpec {}
|
|
9
10
|
|
|
10
11
|
export interface IHook {
|
|
11
12
|
type: HookType;
|
|
12
|
-
timeout: number;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export interface ISkip {
|
|
16
16
|
reason: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
// Old code, but works fine, so I won't change it for now
|
|
20
|
+
export class TestWrap {
|
|
20
21
|
dependencies: IDependency[] = [];
|
|
21
|
-
dependents:
|
|
22
|
+
dependents: TestWrap[] = [];
|
|
22
23
|
skip = new Map<string, ISkip>();
|
|
23
24
|
skipClass: ISkip | null = null;
|
|
24
25
|
specs = new Map<string, ISpec>();
|
|
@@ -26,8 +27,12 @@ export class Test {
|
|
|
26
27
|
isFinished: boolean = false; // cleanup ignored
|
|
27
28
|
cleanUpCalled: boolean = false;
|
|
28
29
|
testInstance: any;
|
|
30
|
+
specDetection: boolean = false;
|
|
31
|
+
config: TestClassInfo;
|
|
29
32
|
|
|
30
|
-
constructor(public target:
|
|
33
|
+
constructor(public target: new () => BaseTest) {
|
|
34
|
+
this.config = target[TEST_CLASS_KEY];
|
|
35
|
+
}
|
|
31
36
|
|
|
32
37
|
get name() {
|
|
33
38
|
return this.target.name;
|
|
@@ -41,7 +46,3 @@ export enum HookType {
|
|
|
41
46
|
AfterEach, // Trigger after each spec
|
|
42
47
|
CleanUp, // Trigger after all dependents tested (You can safely remove connections etc.)
|
|
43
48
|
}
|
|
44
|
-
|
|
45
|
-
export interface ClassDefition<T> {
|
|
46
|
-
new (): T;
|
|
47
|
-
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import * as assert from "assert";
|
|
2
|
-
import { Spec } from "../index.js";
|
|
3
2
|
import { Executor } from "./executor.js";
|
|
3
|
+
import { Test } from "../index.js";
|
|
4
4
|
|
|
5
|
-
export class ExecutorTest {
|
|
6
|
-
@Spec()
|
|
5
|
+
export class ExecutorTest extends Test() {
|
|
7
6
|
async evaluate() {
|
|
8
7
|
await Executor(() => 1, 1);
|
|
9
8
|
await Executor(async () => 1, 1);
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
@Spec()
|
|
13
11
|
async throws() {
|
|
14
12
|
await assert.rejects(() => {
|
|
15
13
|
return Executor(() => {
|
|
@@ -18,7 +16,6 @@ export class ExecutorTest {
|
|
|
18
16
|
});
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
@Spec()
|
|
22
19
|
async timeout() {
|
|
23
20
|
await assert.rejects(() => {
|
|
24
21
|
return Executor(() => new Promise(() => {}), 10);
|
package/src/utils/executor.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import * as assert from "assert";
|
|
2
|
-
import {
|
|
2
|
+
import { Test } from "../index.js";
|
|
3
3
|
import { Executor } from "./executor.js";
|
|
4
4
|
import { TimeDifference } from "./time_difference.js";
|
|
5
5
|
|
|
6
|
-
export class TimeDifferenceTest {
|
|
7
|
-
@Spec()
|
|
6
|
+
export class TimeDifferenceTest extends Test() {
|
|
8
7
|
async evaluate() {
|
|
9
8
|
const td = TimeDifference.begin();
|
|
10
9
|
td.end();
|
package/src/utils/time_factor.ts
CHANGED
package/test/basic.test.ts
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Test } from "../dist/index.js";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
class BasicTest extends Test({ timeout: 750 }) {
|
|
4
4
|
variable = 1;
|
|
5
5
|
|
|
6
|
-
@Spec()
|
|
7
6
|
async checkEqual() {
|
|
8
7
|
await new Promise((resolve) => {
|
|
9
|
-
setTimeout(resolve,
|
|
8
|
+
setTimeout(resolve, 500);
|
|
10
9
|
});
|
|
11
10
|
}
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
export class DependencyTest {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
export class DependencyTest extends Test({
|
|
14
|
+
dependencies: {
|
|
15
|
+
basicTest: () => BasicTest,
|
|
16
|
+
},
|
|
17
|
+
}) {
|
|
19
18
|
async check() {
|
|
20
19
|
if (this.basicTest.variable !== 1) {
|
|
21
20
|
throw new Error("Dependency test failed!");
|