@travetto/test 6.0.2 → 7.0.0-rc.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.
@@ -1,143 +0,0 @@
1
- import { Class, Runtime, classConstruct, describeFunction, asFull } from '@travetto/runtime';
2
- import { MetadataRegistry } from '@travetto/registry';
3
-
4
- import { SuiteConfig } from '../model/suite.ts';
5
- import { TestConfig, TestRun } from '../model/test.ts';
6
-
7
- /**
8
- * Test Suite registry
9
- */
10
- class $SuiteRegistry extends MetadataRegistry<SuiteConfig, TestConfig> {
11
-
12
- /**
13
- * Find all valid tests (ignoring abstract)
14
- */
15
- getValidClasses(): Class[] {
16
- return this.getClasses().filter(c => !describeFunction(c).abstract);
17
- }
18
-
19
- createPending(cls: Class): Partial<SuiteConfig> {
20
- const lines = describeFunction(cls)?.lines;
21
- return {
22
- class: cls,
23
- classId: cls.Ⲑid,
24
- tags: [],
25
- import: Runtime.getImport(cls),
26
- lineStart: lines?.[0],
27
- lineEnd: lines?.[1],
28
- tests: [],
29
- beforeAll: [],
30
- beforeEach: [],
31
- afterAll: [],
32
- afterEach: []
33
- };
34
- }
35
-
36
- override createPendingField(cls: Class, fn: Function): Partial<TestConfig> {
37
- const lines = describeFunction(cls)?.methods?.[fn.name].lines;
38
- return {
39
- class: cls,
40
- tags: [],
41
- import: Runtime.getImport(cls),
42
- lineStart: lines?.[0],
43
- lineEnd: lines?.[1],
44
- lineBodyStart: lines?.[2],
45
- methodName: fn.name
46
- };
47
- }
48
-
49
- /**
50
- * Add a new phase listeners
51
- */
52
- registerPendingListener<T>(cls: Class<T>, listener: Function, phase: 'beforeAll' | 'beforeEach' | 'afterAll' | 'afterEach'): void {
53
- const suiteConfig = this.getOrCreatePending(cls);
54
- suiteConfig[phase]!.push(listener);
55
- }
56
-
57
- /**
58
- * On finalize, collapse state with super classes to create
59
- * a full projection of all listeners and tests.
60
- */
61
- onInstallFinalize<T>(cls: Class<T>): SuiteConfig {
62
- const config = asFull(this.getOrCreatePending(cls));
63
- const tests = [...this.pendingFields.get(cls.Ⲑid)!.values()];
64
-
65
- const parent = this.getParentClass(cls);
66
-
67
- if (parent && this.has(parent)) {
68
- const pConf = this.get(parent);
69
- config.afterAll.push(...pConf.afterAll);
70
- config.beforeAll.push(...pConf.beforeAll);
71
- config.afterEach.push(...pConf.afterEach);
72
- config.beforeEach.push(...pConf.beforeEach);
73
- tests.push(...[...pConf.tests.values()].map(t => ({
74
- ...t,
75
- sourceImport: pConf.import,
76
- class: cls
77
- })));
78
- }
79
-
80
- config.instance = classConstruct(config.class);
81
- config.tests = tests!.map(x => asFull(x));
82
- config.description ||= config.classId;
83
-
84
- for (const t of config.tests) {
85
- t.classId = config.classId;
86
- t.import = config.import;
87
- t.tags = [...t.tags!, ...config.tags!];
88
- }
89
- return config;
90
- }
91
-
92
- /**
93
- * Get run parameters from provided input
94
- */
95
- getSuiteTests(run: TestRun): { suite: SuiteConfig, tests: TestConfig[] }[] {
96
- const clsId = run.classId;
97
- const imp = run.import;
98
- const methodNames = run.methodNames ?? [];
99
-
100
- if (clsId && /^\d+$/.test(clsId)) { // If we only have a line number
101
- const line = parseInt(clsId, 10);
102
- const suites = this.getValidClasses()
103
- .filter(cls => Runtime.getImport(cls) === imp)
104
- .map(x => this.get(x)).filter(x => !x.skip);
105
- const suite = suites.find(x => line >= x.lineStart && line <= x.lineEnd);
106
-
107
- if (suite) {
108
- const test = suite.tests.find(x => line >= x.lineStart && line <= x.lineEnd);
109
- return test ? [{ suite, tests: [test] }] : [{ suite, tests: suite.tests }];
110
- } else {
111
- return suites.map(x => ({ suite: x, tests: x.tests }));
112
- }
113
- } else { // Else lookup directly
114
- if (methodNames.length) {
115
- const cls = this.getValidClasses().find(x => x.Ⲑid === clsId)!;
116
- const suite = this.get(cls);
117
- const tests = suite.tests.filter(x => methodNames.includes(x.methodName))!;
118
- return [{ suite, tests }];
119
- } else if (clsId) {
120
- const cls = this.getValidClasses().find(x => x.Ⲑid === clsId)!;
121
- const suite = this.get(cls);
122
- return suite ? [{ suite, tests: suite.tests }] : [];
123
- } else {
124
- const suites = this.getValidClasses()
125
- .map(x => this.get(x))
126
- .filter(x => !describeFunction(x.class).abstract); // Do not run abstract suites
127
- return suites.map(x => ({ suite: x, tests: x.tests }));
128
- }
129
- }
130
- }
131
-
132
- /**
133
- * Find a test configuration given class and optionally a method
134
- */
135
- getByClassAndMethod(cls: Class, method: Function): TestConfig | undefined {
136
- if (this.has(cls)) {
137
- const conf = this.get(cls);
138
- return conf.tests.find(x => x.methodName === method.name);
139
- }
140
- }
141
- }
142
-
143
- export const SuiteRegistry = new $SuiteRegistry();