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.
Files changed (112) hide show
  1. package/README.md +142 -236
  2. package/bin/nole.js +44 -42
  3. package/dist/const.d.ts +8 -0
  4. package/dist/const.d.ts.map +1 -0
  5. package/dist/const.js +9 -0
  6. package/dist/core.d.ts +22 -0
  7. package/dist/core.d.ts.map +1 -0
  8. package/dist/core.js +56 -0
  9. package/dist/dynamic.d.ts +4 -1
  10. package/dist/dynamic.d.ts.map +1 -1
  11. package/dist/dynamic.js +35 -11
  12. package/dist/handle/after-each-hooks.d.ts +3 -0
  13. package/dist/handle/after-each-hooks.d.ts.map +1 -0
  14. package/dist/handle/after-each-hooks.js +26 -0
  15. package/dist/handle/after-hooks.d.ts +3 -0
  16. package/dist/handle/after-hooks.d.ts.map +1 -0
  17. package/dist/handle/after-hooks.js +24 -0
  18. package/dist/handle/before-each-hooks.d.ts +3 -0
  19. package/dist/handle/before-each-hooks.d.ts.map +1 -0
  20. package/dist/handle/before-each-hooks.js +26 -0
  21. package/dist/handle/before-hooks.d.ts +3 -0
  22. package/dist/handle/before-hooks.d.ts.map +1 -0
  23. package/dist/handle/before-hooks.js +24 -0
  24. package/dist/handle/cleanup-hooks.d.ts +3 -0
  25. package/dist/handle/cleanup-hooks.d.ts.map +1 -0
  26. package/dist/handle/cleanup-hooks.js +34 -0
  27. package/dist/handle/specs.d.ts +3 -0
  28. package/dist/handle/specs.d.ts.map +1 -0
  29. package/dist/handle/specs.js +41 -0
  30. package/dist/index.d.ts +3 -3
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +4 -4
  33. package/dist/run.d.ts +7 -6
  34. package/dist/run.d.ts.map +1 -1
  35. package/dist/run.js +201 -239
  36. package/dist/symbol.d.ts +2 -0
  37. package/dist/symbol.d.ts.map +1 -0
  38. package/dist/symbol.js +2 -0
  39. package/dist/test-wrap.d.ts +37 -0
  40. package/dist/test-wrap.d.ts.map +1 -0
  41. package/dist/test-wrap.js +30 -0
  42. package/dist/utils/executor.d.ts +1 -1
  43. package/dist/utils/executor.js +20 -20
  44. package/dist/utils/executor.test.d.ts +7 -5
  45. package/dist/utils/executor.test.d.ts.map +1 -1
  46. package/dist/utils/executor.test.js +22 -49
  47. package/dist/utils/time_difference.d.ts +15 -6
  48. package/dist/utils/time_difference.d.ts.map +1 -1
  49. package/dist/utils/time_difference.js +22 -13
  50. package/dist/utils/time_difference.test.d.ts +5 -3
  51. package/dist/utils/time_difference.test.d.ts.map +1 -1
  52. package/dist/utils/time_difference.test.js +11 -24
  53. package/dist/utils/time_factor.d.ts +3 -3
  54. package/dist/utils/time_factor.d.ts.map +1 -1
  55. package/dist/utils/time_factor.js +26 -27
  56. package/dist/utils/time_factor.test.d.ts +5 -3
  57. package/dist/utils/time_factor.test.d.ts.map +1 -1
  58. package/dist/utils/time_factor.test.js +27 -42
  59. package/package.json +11 -8
  60. package/src/const.ts +11 -0
  61. package/src/core.ts +89 -0
  62. package/src/dynamic.ts +43 -1
  63. package/src/handle/after-each-hooks.ts +41 -0
  64. package/src/handle/after-hooks.ts +38 -0
  65. package/src/handle/before-each-hooks.ts +40 -0
  66. package/src/handle/before-hooks.ts +39 -0
  67. package/src/handle/cleanup-hooks.ts +55 -0
  68. package/src/handle/specs.ts +68 -0
  69. package/src/index.ts +3 -13
  70. package/src/run.ts +184 -256
  71. package/src/symbol.ts +1 -0
  72. package/src/{test.ts → test-wrap.ts} +13 -12
  73. package/src/utils/executor.test.ts +2 -5
  74. package/src/utils/executor.ts +1 -1
  75. package/src/utils/time_difference.test.ts +2 -3
  76. package/src/utils/time_factor.test.ts +2 -3
  77. package/src/utils/time_factor.ts +1 -3
  78. package/test/basic.test.ts +8 -9
  79. package/test/before.test.ts +14 -27
  80. package/test/clean-up.test.ts +12 -16
  81. package/test/dynamic-skip.test.ts +2 -4
  82. package/test/dynamic.test.ts +23 -8
  83. package/test/extend.test.ts +43 -0
  84. package/test/hook.test.ts +9 -10
  85. package/test/multi-dependency.test.ts +25 -27
  86. package/test/multiple-uppercased-chars.test.ts +8 -7
  87. package/test/skip-all.test.ts +4 -13
  88. package/test/turkish-chars.test.ts +8 -7
  89. package/tsconfig.json +9 -18
  90. package/dist/data.d.ts +0 -3
  91. package/dist/data.d.ts.map +0 -1
  92. package/dist/data.js +0 -9
  93. package/dist/data.js.map +0 -1
  94. package/dist/decorators.d.ts +0 -9
  95. package/dist/decorators.d.ts.map +0 -1
  96. package/dist/decorators.js +0 -118
  97. package/dist/decorators.js.map +0 -1
  98. package/dist/dynamic.js.map +0 -1
  99. package/dist/index.js.map +0 -1
  100. package/dist/run.js.map +0 -1
  101. package/dist/test.d.ts +0 -39
  102. package/dist/test.d.ts.map +0 -1
  103. package/dist/test.js +0 -25
  104. package/dist/test.js.map +0 -1
  105. package/dist/utils/executor.js.map +0 -1
  106. package/dist/utils/executor.test.js.map +0 -1
  107. package/dist/utils/time_difference.js.map +0 -1
  108. package/dist/utils/time_difference.test.js.map +0 -1
  109. package/dist/utils/time_factor.js.map +0 -1
  110. package/dist/utils/time_factor.test.js.map +0 -1
  111. package/src/data.ts +0 -13
  112. package/src/decorators.ts +0 -208
package/src/run.ts CHANGED
@@ -1,331 +1,259 @@
1
- import { HashMap } from "./data.js";
2
- import { TimeDifference } from "./utils/time_difference.js";
3
- import { TimeFactor } from "./utils/time_factor.js";
4
- import * as clrs from "colors/safe.js";
5
- import { Executor } from "./utils/executor.js";
6
- import { HookType, Test } from "./test.js";
7
-
8
- const colors = (clrs as any).default;
9
-
10
- const OK_TEXT = colors.bold(colors.green(" (ok) "));
11
- const SKIP_TEXT = colors.bold(colors.yellow(" (skip) "));
12
- const DYNAMIC_SKIP_TEXT = colors.bold(colors.blue(" (dskip) "));
13
- const FAILED_TEXT = colors.bold(colors.red(" (failed) "));
14
- const HOOK_FAILED_TEXT = colors.bold(colors.red(" (hook failed) "));
15
-
16
- interface Options {
17
- log: Function;
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
- export function ManualRun(options: Options) {
22
- if (!options.log) {
23
- options.log = console.log.bind(console);
19
+ const wrap = new TestWrap(test);
20
+
21
+ allTests.set(test, wrap);
22
+ notTestedYet.set(test, wrap);
24
23
  }
25
24
 
26
- const log = options.log;
25
+ extractInformationFromClasses(notTestedYet);
27
26
 
28
- return new Promise<void>(async (resolve, reject) => {
29
- try {
30
- let hashMap = new Map(HashMap());
27
+ if (!notTestedYet.size) {
28
+ throw new Error("No specs found");
29
+ }
31
30
 
32
- if (!hashMap.size) {
33
- log(`${FAILED_TEXT} no specs found`);
34
- throw new Error("No specs found");
35
- }
31
+ while (notTestedYet.size) {
32
+ let entry = pickNext(notTestedYet);
36
33
 
37
- while (hashMap.size) {
38
- let test = PickNextTestFromHashMap(hashMap);
34
+ if (entry) {
35
+ let test = entry[1];
36
+ // console.log(colors.bold(colors.cyan(`Running test: ${test.name}`)));
39
37
 
40
- if (test) {
41
- hashMap.delete(test.target);
42
- CreateInstanceIfNotExists(test);
43
- HandleDependencies(test);
38
+ notTestedYet.delete(test.target);
39
+ createInstanceIfNotExists(test);
40
+ handleDependencies(test);
44
41
 
45
- await HandleBeforeHooks(test, options);
46
- await HandleSpecs(test, options);
47
- await HandleAfterHooks(test, options);
42
+ await handleBeforeHooks(test);
43
+ await handleSpecs(test);
44
+ await handleAfterHooks(test);
48
45
 
49
- test.isFinished = true;
46
+ test.isFinished = true;
50
47
 
51
- if (test.dependents.length == 0) {
52
- await HandleCleanUp(test, options);
53
- }
54
- } else {
55
- DependencyLock(hashMap);
56
- }
48
+ if (test.dependents.length == 0) {
49
+ await handleCleanUp(test);
57
50
  }
58
-
59
- resolve();
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 CreateInstanceIfNotExists(test: Test) {
76
- if (!test.testInstance) {
77
- test.testInstance = new test.target();
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 HandleDependencies(test: Test) {
82
- for (let dependency of test.dependencies) {
83
- test.testInstance[dependency.propertyKey] =
84
- dependency.dependency.testInstance;
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
- async function HandleBeforeHooks(test: Test, options: Options) {
89
- for (let [propertyKey, hook] of test.hooks.entries()) {
90
- if (hook.type != HookType.Before) continue;
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
- let hookName = colors.bold(
93
- colors.yellow(
94
- test.name +
95
- (propertyKey != "before" ? `.${propertyKey}:before` : ":before")
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
- try {
100
- if (!options.orderDebug) {
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
- options.log(`${OK_TEXT} ${timeText} ${hookName}()`);
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
- } catch (e) {
111
- console.error(`${HOOK_FAILED_TEXT} ${hookName}()`);
112
- console.error((e as any)?.stack ?? e);
113
- throw e;
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
- async function HandleBeforeEachHooks(test: Test, options: Options) {
119
- for (let [propertyKey, hook] of test.hooks.entries()) {
120
- if (hook.type != HookType.BeforeEach) continue;
121
- let hookName = colors.bold(
122
- colors.yellow(
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
- try {
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
- options.log(`${OK_TEXT} ${timeText} ${hookName}()`);
129
+ if (!testWrap) {
130
+ testWrap = new TestWrap(actual);
131
+ tests.set(actual, testWrap);
132
+ allTests.set(actual, testWrap);
140
133
  }
141
- } catch (e) {
142
- console.error(`${HOOK_FAILED_TEXT} ${hookName}()`);
143
- console.error((e as any)?.stack ?? e);
144
- throw e;
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
- async function HandleAfterEachHooks(test: Test, options: Options) {
150
- for (let [propertyKey, hook] of test.hooks.entries()) {
151
- if (hook.type != HookType.AfterEach) continue;
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
- let hookName = colors.bold(
154
- colors.yellow(
155
- test.name +
156
- (propertyKey != "afterEach"
157
- ? `.${propertyKey}:afterEach`
158
- : ":afterEach")
159
- )
160
- );
151
+ return entry;
152
+ }
153
+ }
161
154
 
162
- try {
163
- if (!options.orderDebug) {
164
- await Executor(
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
- options.log(`${OK_TEXT} ${timeText} ${hookName}()`);
172
- }
173
- } catch (e) {
174
- console.error(`${HOOK_FAILED_TEXT} ${hookName}()`);
175
- console.error((e as any)?.stack ?? e);
176
- throw e;
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
- async function HandleSpecs(test: Test, options: Options) {
182
- const log = options.log;
183
-
184
- for (let [propertyKey, spec] of test.specs.entries()) {
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
- await HandleBeforeEachHooks(test, options);
201
-
202
- let start = TimeDifference.begin();
175
+ let lowerKey = key.toLowerCase();
203
176
 
204
- try {
205
- if (!options.orderDebug) {
206
- await Executor(
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
- let timeText = TimeFactor(start.end(), spec.timeout);
213
-
214
- log(`${OK_TEXT} ${timeText} ${testName}()`);
215
- } catch (e) {
216
- if ((e as any)?._nole_anchor) {
217
- let reason = (e as any).reason;
218
- log(
219
- `${DYNAMIC_SKIP_TEXT} ${" ".repeat(8)} ${testName}() ${
220
- reason ? "{" + reason + "}" : ""
221
- }`
222
- );
223
- continue;
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
- let timeText = TimeFactor(start.end(), spec.timeout);
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
- await HandleAfterEachHooks(test, options);
207
+ test.specs.set(key, {});
234
208
  }
235
209
  }
236
210
 
237
- async function HandleAfterHooks(test: Test, options: Options) {
238
- for (let [propertyKey, hook] of test.hooks.entries()) {
239
- if (hook.type != HookType.After) continue;
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
- try {
249
- if (!options.orderDebug) {
250
- await Executor(
251
- test.testInstance[propertyKey].bind(test.testInstance),
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
- } catch (e) {
260
- console.error(`${HOOK_FAILED_TEXT} ${hookName}()`);
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
- test.cleanUpCalled = true;
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
- for (let tree of test.dependencies) {
310
- await HandleCleanUp(tree.dependency, options);
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 DependencyLock(hashMap: Map<any, Test>) {
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 hashMap.values()) {
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: Test;
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
- export class Test {
19
+ // Old code, but works fine, so I won't change it for now
20
+ export class TestWrap {
20
21
  dependencies: IDependency[] = [];
21
- dependents: Test[] = [];
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: any) {}
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);
@@ -1,6 +1,6 @@
1
1
  export function Executor(fn: Function, timeout: number): Promise<void> {
2
2
  return new Promise(async (resolve, reject) => {
3
- let _timeout = null;
3
+ let _timeout: NodeJS.Timeout | null = null;
4
4
 
5
5
  try {
6
6
  let expectPromise = fn();
@@ -1,10 +1,9 @@
1
1
  import * as assert from "assert";
2
- import { Spec } from "../index.js";
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();
@@ -1,8 +1,7 @@
1
- import { Spec } from "../index.js";
1
+ import { Test } from "../index.js";
2
2
  import { Delay, TimeFactor } from "./time_factor.js";
3
3
 
4
- export class TimeFactorTest {
5
- @Spec()
4
+ export class TimeFactorTest extends Test() {
6
5
  async evaluate() {
7
6
  await Delay(1);
8
7
 
@@ -1,6 +1,4 @@
1
- import * as clrs from "colors/safe.js";
2
-
3
- const colors = (clrs as any).default;
1
+ import { colors } from "../const.js";
4
2
 
5
3
  export function TimeFactor(diff: number, timeout: number) {
6
4
  if (diff < timeout / 5) {
@@ -1,21 +1,20 @@
1
- import { Spec, Dependency } from "../src/index.js";
1
+ import { Test } from "../dist/index.js";
2
2
 
3
- export class BasicTest {
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, 1010);
8
+ setTimeout(resolve, 500);
10
9
  });
11
10
  }
12
11
  }
13
12
 
14
- export class DependencyTest {
15
- @Dependency(BasicTest)
16
- basicTest!: BasicTest;
17
-
18
- @Spec()
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!");