@react-native-harness/runtime 1.0.0-alpha.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/.babelrc.js +23 -0
- package/LICENSE +20 -0
- package/README.md +7 -0
- package/assets/logo.png +0 -0
- package/assets/moduleSystem.flow.js +1062 -0
- package/dist/bundler/bundle.d.ts +2 -0
- package/dist/bundler/bundle.d.ts.map +1 -0
- package/dist/bundler/bundle.js +16 -0
- package/dist/bundler/dev-server.d.ts +2 -0
- package/dist/bundler/dev-server.d.ts.map +1 -0
- package/dist/bundler/dev-server.js +5 -0
- package/dist/bundler/errors.d.ts +10 -0
- package/dist/bundler/errors.d.ts.map +1 -0
- package/dist/bundler/errors.js +18 -0
- package/dist/bundler/evaluate.d.ts +2 -0
- package/dist/bundler/evaluate.d.ts.map +1 -0
- package/dist/bundler/evaluate.js +18 -0
- package/dist/bundler/index.d.ts +3 -0
- package/dist/bundler/index.d.ts.map +1 -0
- package/dist/bundler/index.js +2 -0
- package/dist/client/factory.d.ts +2 -0
- package/dist/client/factory.d.ts.map +1 -0
- package/dist/client/factory.js +41 -0
- package/dist/client/getDeviceDescriptor.d.ts +8 -0
- package/dist/client/getDeviceDescriptor.d.ts.map +1 -0
- package/dist/client/getDeviceDescriptor.js +20 -0
- package/dist/client/getWSServer.d.ts +2 -0
- package/dist/client/getWSServer.d.ts.map +1 -0
- package/dist/client/getWSServer.js +7 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +1 -0
- package/dist/collector/errors.d.ts +8 -0
- package/dist/collector/errors.d.ts.map +1 -0
- package/dist/collector/errors.js +20 -0
- package/dist/collector/factory.d.ts +3 -0
- package/dist/collector/factory.d.ts.map +1 -0
- package/dist/collector/factory.js +25 -0
- package/dist/collector/functions.d.ts +22 -0
- package/dist/collector/functions.d.ts.map +1 -0
- package/dist/collector/functions.js +271 -0
- package/dist/collector/index.d.ts +5 -0
- package/dist/collector/index.d.ts.map +1 -0
- package/dist/collector/index.js +3 -0
- package/dist/collector/types.d.ts +10 -0
- package/dist/collector/types.d.ts.map +1 -0
- package/dist/collector/types.js +1 -0
- package/dist/collector/validation.d.ts +4 -0
- package/dist/collector/validation.d.ts.map +1 -0
- package/dist/collector/validation.js +15 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/expect/index.d.ts +9 -0
- package/dist/expect/index.d.ts.map +1 -0
- package/dist/expect/index.js +71 -0
- package/dist/expect/setup.d.ts +2 -0
- package/dist/expect/setup.d.ts.map +1 -0
- package/dist/expect/setup.js +5 -0
- package/dist/exports.d.ts +7 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +6 -0
- package/dist/getEntryComponent.d.ts +6 -0
- package/dist/getEntryComponent.d.ts.map +1 -0
- package/dist/getEntryComponent.js +6 -0
- package/dist/globals.d.ts +5 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/initialize.d.ts +2 -0
- package/dist/initialize.d.ts.map +1 -0
- package/dist/initialize.js +16 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +14 -0
- package/dist/mock.d.ts +15 -0
- package/dist/mock.d.ts.map +1 -0
- package/dist/mock.js +37 -0
- package/dist/mocker/index.d.ts +2 -0
- package/dist/mocker/index.d.ts.map +1 -0
- package/dist/mocker/index.js +1 -0
- package/dist/mocker/registry.d.ts +7 -0
- package/dist/mocker/registry.d.ts.map +1 -0
- package/dist/mocker/registry.js +41 -0
- package/dist/mocker/types.d.ts +6 -0
- package/dist/mocker/types.d.ts.map +1 -0
- package/dist/mocker/types.js +1 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +19 -0
- package/dist/module.web.d.ts +2 -0
- package/dist/module.web.d.ts.map +1 -0
- package/dist/module.web.js +12 -0
- package/dist/rntl/client.d.ts +3 -0
- package/dist/rntl/client.d.ts.map +1 -0
- package/dist/rntl/client.js +8 -0
- package/dist/rntl/describe.d.ts +2 -0
- package/dist/rntl/describe.d.ts.map +1 -0
- package/dist/rntl/describe.js +1 -0
- package/dist/rntl/expect.d.ts +128 -0
- package/dist/rntl/expect.d.ts.map +1 -0
- package/dist/rntl/expect.js +670 -0
- package/dist/rntl/fn.d.ts +2 -0
- package/dist/rntl/fn.d.ts.map +1 -0
- package/dist/rntl/fn.js +1 -0
- package/dist/rntl/mock.d.ts +2 -0
- package/dist/rntl/mock.d.ts.map +1 -0
- package/dist/rntl/mock.js +1 -0
- package/dist/rntl/render.d.ts +4 -0
- package/dist/rntl/render.d.ts.map +1 -0
- package/dist/rntl/render.js +11 -0
- package/dist/rntl/screen.d.ts +45 -0
- package/dist/rntl/screen.d.ts.map +1 -0
- package/dist/rntl/screen.js +31 -0
- package/dist/rntl/spies.d.ts +45 -0
- package/dist/rntl/spies.d.ts.map +1 -0
- package/dist/rntl/spies.js +553 -0
- package/dist/rntl/userEvent.d.ts +22 -0
- package/dist/rntl/userEvent.d.ts.map +1 -0
- package/dist/rntl/userEvent.js +19 -0
- package/dist/runner/errors.d.ts +9 -0
- package/dist/runner/errors.d.ts.map +1 -0
- package/dist/runner/errors.js +23 -0
- package/dist/runner/factory.d.ts +3 -0
- package/dist/runner/factory.d.ts.map +1 -0
- package/dist/runner/factory.js +17 -0
- package/dist/runner/hooks.d.ts +4 -0
- package/dist/runner/hooks.d.ts.map +1 -0
- package/dist/runner/hooks.js +39 -0
- package/dist/runner/index.d.ts +4 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +2 -0
- package/dist/runner/runSuite.d.ts +4 -0
- package/dist/runner/runSuite.d.ts.map +1 -0
- package/dist/runner/runSuite.js +147 -0
- package/dist/runner/types.d.ts +13 -0
- package/dist/runner/types.d.ts.map +1 -0
- package/dist/runner/types.js +1 -0
- package/dist/runner.d.ts +7 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +201 -0
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +44 -0
- package/dist/spy/index.d.ts +2 -0
- package/dist/spy/index.d.ts.map +1 -0
- package/dist/spy/index.js +2 -0
- package/dist/state.d.ts +25 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +37 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/ui/ReadyScreen.d.ts +2 -0
- package/dist/ui/ReadyScreen.d.ts.map +1 -0
- package/dist/ui/ReadyScreen.js +110 -0
- package/dist/ui/UI.d.ts +13 -0
- package/dist/ui/UI.d.ts.map +1 -0
- package/dist/ui/UI.js +121 -0
- package/dist/ui/WrongEnvironmentScreen.d.ts +2 -0
- package/dist/ui/WrongEnvironmentScreen.d.ts.map +1 -0
- package/dist/ui/WrongEnvironmentScreen.js +87 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/state.d.ts +7 -0
- package/dist/ui/state.d.ts.map +1 -0
- package/dist/ui/state.js +6 -0
- package/dist/utils/dev-server.d.ts +2 -0
- package/dist/utils/dev-server.d.ts.map +1 -0
- package/dist/utils/dev-server.js +5 -0
- package/dist/utils/emitter.d.ts +16 -0
- package/dist/utils/emitter.d.ts.map +1 -0
- package/dist/utils/emitter.js +39 -0
- package/eslint.config.mjs +16 -0
- package/package.json +38 -0
- package/src/__tests__/collector.test.ts +553 -0
- package/src/__tests__/error-handling.test.ts +132 -0
- package/src/__tests__/expect.test.ts +619 -0
- package/src/__tests__/spy.test.ts +538 -0
- package/src/bundler/bundle.ts +19 -0
- package/src/bundler/errors.ts +16 -0
- package/src/bundler/evaluate.ts +25 -0
- package/src/bundler/index.ts +2 -0
- package/src/client/factory.ts +56 -0
- package/src/client/getDeviceDescriptor.ts +30 -0
- package/src/client/getWSServer.ts +9 -0
- package/src/client/index.ts +1 -0
- package/src/collector/errors.ts +27 -0
- package/src/collector/factory.ts +32 -0
- package/src/collector/functions.ts +376 -0
- package/src/collector/index.ts +12 -0
- package/src/collector/types.ts +15 -0
- package/src/collector/validation.ts +21 -0
- package/src/constants.ts +2 -0
- package/src/errors.ts +12 -0
- package/src/expect/index.ts +117 -0
- package/src/expect/setup.ts +10 -0
- package/src/globals.ts +5 -0
- package/src/index.ts +7 -0
- package/src/initialize.ts +22 -0
- package/src/mocker/index.ts +1 -0
- package/src/mocker/metro-require.d.ts +5 -0
- package/src/mocker/registry.ts +58 -0
- package/src/mocker/types.ts +6 -0
- package/src/react-native.d.ts +16 -0
- package/src/runner/errors.ts +31 -0
- package/src/runner/factory.ts +21 -0
- package/src/runner/hooks.ts +51 -0
- package/src/runner/index.ts +7 -0
- package/src/runner/runSuite.ts +201 -0
- package/src/runner/types.ts +19 -0
- package/src/spy/index.ts +2 -0
- package/src/ui/ReadyScreen.tsx +151 -0
- package/src/ui/WrongEnvironmentScreen.tsx +113 -0
- package/src/ui/index.ts +3 -0
- package/src/ui/state.ts +13 -0
- package/src/utils/dev-server.ts +6 -0
- package/src/utils/emitter.ts +64 -0
- package/tsconfig.json +16 -0
- package/tsconfig.lib.json +33 -0
- package/tsconfig.spec.json +30 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/types/global.d.ts +2 -0
- package/types/index.d.ts +1 -0
- package/vite.config.ts +27 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import nx from '@nx/eslint-plugin';
|
|
2
|
+
import baseConfig from '../../eslint.config.mjs';
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
...baseConfig,
|
|
6
|
+
...nx.configs['flat/react'],
|
|
7
|
+
{
|
|
8
|
+
files: ['./src/rntl/**/*.ts'],
|
|
9
|
+
rules: {
|
|
10
|
+
'react-hooks/rules-of-hooks': 'off',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
ignores: ['public', '.cache', 'node_modules'],
|
|
15
|
+
},
|
|
16
|
+
];
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-native-harness/runtime",
|
|
3
|
+
"version": "1.0.0-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"./package.json": "./package.json",
|
|
10
|
+
".": {
|
|
11
|
+
"development": "./src/index.ts",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./moduleSystem": "./assets/moduleSystem.flow.js",
|
|
17
|
+
"./types": "./types/index.d.ts"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "~18.3.1",
|
|
21
|
+
"react-native": "~0.76.3"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@vitest/expect": "4.0.0-beta.8",
|
|
25
|
+
"@vitest/spy": "4.0.0-beta.8",
|
|
26
|
+
"chai": "^5.3.1",
|
|
27
|
+
"event-target-shim": "^6.0.2",
|
|
28
|
+
"react-native-url-polyfill": "^2.0.0",
|
|
29
|
+
"sinon": "^21.0.0",
|
|
30
|
+
"util": "^0.12.5",
|
|
31
|
+
"zustand": "^5.0.5",
|
|
32
|
+
"@react-native-harness/bridge": "1.0.0-alpha.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/chai": "^5.2.2",
|
|
36
|
+
"@types/sinon": "^17.0.4"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import * as collectorFunctions from '../collector/functions.js';
|
|
3
|
+
|
|
4
|
+
const noop = () => {
|
|
5
|
+
// Noop
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
describe('test collector - test case recognition', () => {
|
|
9
|
+
it('should collect basic test cases using it()', () => {
|
|
10
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
11
|
+
collectorFunctions.describe('Sample Suite', () => {
|
|
12
|
+
collectorFunctions.it('test 1', noop);
|
|
13
|
+
collectorFunctions.it('test 2', noop);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(1);
|
|
18
|
+
const sampleSuite = collectedSuite.testSuite.suites[0];
|
|
19
|
+
expect(sampleSuite.name).toBe('Sample Suite');
|
|
20
|
+
expect(sampleSuite.tests).toHaveLength(2);
|
|
21
|
+
expect(sampleSuite.tests[0].name).toBe('test 1');
|
|
22
|
+
expect(sampleSuite.tests[1].name).toBe('test 2');
|
|
23
|
+
expect(sampleSuite.tests[0].status).toBe('active');
|
|
24
|
+
expect(sampleSuite.tests[1].status).toBe('active');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should collect basic test cases using test()', () => {
|
|
28
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
29
|
+
collectorFunctions.describe('Sample Suite', () => {
|
|
30
|
+
collectorFunctions.test('test 1', noop);
|
|
31
|
+
collectorFunctions.test('test 2', noop);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(1);
|
|
36
|
+
const sampleSuite = collectedSuite.testSuite.suites[0];
|
|
37
|
+
expect(sampleSuite.tests).toHaveLength(2);
|
|
38
|
+
expect(sampleSuite.tests[0].name).toBe('test 1');
|
|
39
|
+
expect(sampleSuite.tests[1].name).toBe('test 2');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should collect async test functions', () => {
|
|
43
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
44
|
+
collectorFunctions.describe('Async Suite', () => {
|
|
45
|
+
collectorFunctions.it('async test', async () => {
|
|
46
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const asyncSuite = collectedSuite.testSuite.suites[0];
|
|
52
|
+
expect(asyncSuite.tests[0].name).toBe('async test');
|
|
53
|
+
expect(typeof asyncSuite.tests[0].fn).toBe('function');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should collect tests at root level', () => {
|
|
57
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
58
|
+
collectorFunctions.it('root test 1', noop);
|
|
59
|
+
collectorFunctions.test('root test 2', noop);
|
|
60
|
+
|
|
61
|
+
collectorFunctions.describe('Suite with tests', () => {
|
|
62
|
+
collectorFunctions.it('suite test', noop);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Collected root suite should have the root-level tests
|
|
67
|
+
expect(collectedSuite.testSuite.tests).toHaveLength(2);
|
|
68
|
+
expect(collectedSuite.testSuite.tests[0].name).toBe('root test 1');
|
|
69
|
+
expect(collectedSuite.testSuite.tests[1].name).toBe('root test 2');
|
|
70
|
+
expect(collectedSuite.testSuite.tests[0].status).toBe('active');
|
|
71
|
+
expect(collectedSuite.testSuite.tests[1].status).toBe('active');
|
|
72
|
+
|
|
73
|
+
// Should also have the describe suite
|
|
74
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(1);
|
|
75
|
+
expect(collectedSuite.testSuite.suites[0].tests).toHaveLength(1);
|
|
76
|
+
expect(collectedSuite.testSuite.suites[0].tests[0].name).toBe('suite test');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should collect tests with modifiers at root level', () => {
|
|
80
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
81
|
+
collectorFunctions.it('regular root test', noop);
|
|
82
|
+
collectorFunctions.test.skip('skipped root test', noop);
|
|
83
|
+
collectorFunctions.it.todo('todo root test');
|
|
84
|
+
collectorFunctions.test.only('focused root test', noop);
|
|
85
|
+
collectorFunctions.it('another root test', noop);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Collected root suite should have all the tests with correct statuses
|
|
89
|
+
expect(collectedSuite.testSuite.tests).toHaveLength(5);
|
|
90
|
+
expect(collectedSuite.testSuite.tests[0].name).toBe('regular root test');
|
|
91
|
+
expect(collectedSuite.testSuite.tests[0].status).toBe('skipped'); // Due to .only
|
|
92
|
+
expect(collectedSuite.testSuite.tests[1].name).toBe('skipped root test');
|
|
93
|
+
expect(collectedSuite.testSuite.tests[1].status).toBe('skipped');
|
|
94
|
+
expect(collectedSuite.testSuite.tests[2].name).toBe('todo root test');
|
|
95
|
+
expect(collectedSuite.testSuite.tests[2].status).toBe('todo');
|
|
96
|
+
expect(collectedSuite.testSuite.tests[3].name).toBe('focused root test');
|
|
97
|
+
expect(collectedSuite.testSuite.tests[3].status).toBe('active'); // The .only test
|
|
98
|
+
expect(collectedSuite.testSuite.tests[4].name).toBe('another root test');
|
|
99
|
+
expect(collectedSuite.testSuite.tests[4].status).toBe('skipped'); // Due to .only
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('test collector - suite recognition', () => {
|
|
104
|
+
it('should collect nested describe blocks', () => {
|
|
105
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
106
|
+
collectorFunctions.describe('Outer Suite', () => {
|
|
107
|
+
collectorFunctions.describe('Inner Suite 1', () => {
|
|
108
|
+
collectorFunctions.it('test 1', noop);
|
|
109
|
+
});
|
|
110
|
+
collectorFunctions.describe('Inner Suite 2', () => {
|
|
111
|
+
collectorFunctions.it('test 2', noop);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(1);
|
|
117
|
+
const outerSuite = collectedSuite.testSuite.suites[0];
|
|
118
|
+
expect(outerSuite.name).toBe('Outer Suite');
|
|
119
|
+
expect(outerSuite.suites).toHaveLength(2);
|
|
120
|
+
expect(outerSuite.suites[0].name).toBe('Inner Suite 1');
|
|
121
|
+
expect(outerSuite.suites[1].name).toBe('Inner Suite 2');
|
|
122
|
+
expect(outerSuite.suites[0].tests[0].name).toBe('test 1');
|
|
123
|
+
expect(outerSuite.suites[1].tests[0].name).toBe('test 2');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should collect multiple top-level describe blocks', () => {
|
|
127
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
128
|
+
collectorFunctions.describe('Suite 1', () => {
|
|
129
|
+
collectorFunctions.it('test 1', noop);
|
|
130
|
+
});
|
|
131
|
+
collectorFunctions.describe('Suite 2', () => {
|
|
132
|
+
collectorFunctions.it('test 2', noop);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(2);
|
|
137
|
+
expect(collectedSuite.testSuite.suites[0].name).toBe('Suite 1');
|
|
138
|
+
expect(collectedSuite.testSuite.suites[1].name).toBe('Suite 2');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should collect deeply nested suites', () => {
|
|
142
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
143
|
+
collectorFunctions.describe('Level 1', () => {
|
|
144
|
+
collectorFunctions.describe('Level 2', () => {
|
|
145
|
+
collectorFunctions.describe('Level 3', () => {
|
|
146
|
+
collectorFunctions.it('deep test', noop);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const level1 = collectedSuite.testSuite.suites[0];
|
|
153
|
+
const level2 = level1.suites[0];
|
|
154
|
+
const level3 = level2.suites[0];
|
|
155
|
+
|
|
156
|
+
expect(level1.name).toBe('Level 1');
|
|
157
|
+
expect(level2.name).toBe('Level 2');
|
|
158
|
+
expect(level3.name).toBe('Level 3');
|
|
159
|
+
expect(level3.tests[0].name).toBe('deep test');
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
describe('test collector - skip modifier recognition', () => {
|
|
164
|
+
it('should collect and mark skipped tests with test.skip()', () => {
|
|
165
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
166
|
+
collectorFunctions.describe('Skip Suite', () => {
|
|
167
|
+
collectorFunctions.it('active test', noop);
|
|
168
|
+
collectorFunctions.test.skip('skipped test', noop);
|
|
169
|
+
collectorFunctions.it.skip('another skipped test', noop);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const skipSuite = collectedSuite.testSuite.suites[0];
|
|
174
|
+
expect(skipSuite.tests).toHaveLength(3);
|
|
175
|
+
expect(skipSuite.tests[0].status).toBe('active');
|
|
176
|
+
expect(skipSuite.tests[1].status).toBe('skipped');
|
|
177
|
+
expect(skipSuite.tests[2].status).toBe('skipped');
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should collect and mark skipped suites with describe.skip()', () => {
|
|
181
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
182
|
+
collectorFunctions.describe('Active Suite', () => {
|
|
183
|
+
collectorFunctions.it('active test', noop);
|
|
184
|
+
});
|
|
185
|
+
collectorFunctions.describe.skip('Skipped Suite', () => {
|
|
186
|
+
collectorFunctions.it('test in skipped suite', noop);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(2);
|
|
191
|
+
expect(collectedSuite.testSuite.suites[0].status).toBe('active');
|
|
192
|
+
expect(collectedSuite.testSuite.suites[1].status).toBe('skipped');
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should collect nested skipped suites', () => {
|
|
196
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
197
|
+
collectorFunctions.describe.skip('Outer Skipped', () => {
|
|
198
|
+
collectorFunctions.describe('Inner Suite', () => {
|
|
199
|
+
collectorFunctions.it('test', noop);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
const outerSuite = collectedSuite.testSuite.suites[0];
|
|
205
|
+
expect(outerSuite.status).toBe('skipped');
|
|
206
|
+
expect(outerSuite.suites[0].tests[0].name).toBe('test');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
describe('test collector - only modifier recognition', () => {
|
|
211
|
+
it('should collect and mark only tests and skip others with test.only()', () => {
|
|
212
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
213
|
+
collectorFunctions.describe('Only Suite', () => {
|
|
214
|
+
collectorFunctions.it('regular test 1', noop);
|
|
215
|
+
collectorFunctions.test.only('focused test', noop);
|
|
216
|
+
collectorFunctions.it('regular test 2', noop);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
const onlySuite = collectedSuite.testSuite.suites[0];
|
|
221
|
+
expect(onlySuite.tests).toHaveLength(3);
|
|
222
|
+
expect(onlySuite.tests[0].status).toBe('skipped');
|
|
223
|
+
expect(onlySuite.tests[1].status).toBe('active');
|
|
224
|
+
expect(onlySuite.tests[2].status).toBe('skipped');
|
|
225
|
+
expect(onlySuite._hasFocused).toBe(true);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should collect multiple test.only() calls', () => {
|
|
229
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
230
|
+
collectorFunctions.describe('Multiple Only Suite', () => {
|
|
231
|
+
collectorFunctions.it('regular test', noop);
|
|
232
|
+
collectorFunctions.test.only('focused test 1', noop);
|
|
233
|
+
collectorFunctions.test.only('focused test 2', noop);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const multipleSuite = collectedSuite.testSuite.suites[0];
|
|
238
|
+
expect(multipleSuite.tests[0].status).toBe('skipped');
|
|
239
|
+
expect(multipleSuite.tests[1].status).toBe('active'); // First only stays active
|
|
240
|
+
expect(multipleSuite.tests[2].status).toBe('active'); // Second only also active
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should collect and mark only suites and skip others with describe.only()', () => {
|
|
244
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
245
|
+
collectorFunctions.describe('Regular Suite 1', () => {
|
|
246
|
+
collectorFunctions.it('test 1', noop);
|
|
247
|
+
});
|
|
248
|
+
collectorFunctions.describe.only('Focused Suite', () => {
|
|
249
|
+
collectorFunctions.it('focused test', noop);
|
|
250
|
+
});
|
|
251
|
+
collectorFunctions.describe('Regular Suite 2', () => {
|
|
252
|
+
collectorFunctions.it('test 2', noop);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
expect(collectedSuite.testSuite.suites).toHaveLength(3);
|
|
257
|
+
expect(collectedSuite.testSuite.suites[0].status).toBe('skipped');
|
|
258
|
+
expect(collectedSuite.testSuite.suites[1].status).toBe('active');
|
|
259
|
+
expect(collectedSuite.testSuite.suites[2].status).toBe('skipped');
|
|
260
|
+
expect(collectedSuite.testSuite.suites[1]._hasFocused).toBe(true);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
it('should collect nested describe.only()', () => {
|
|
264
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
265
|
+
collectorFunctions.describe('Outer Suite', () => {
|
|
266
|
+
collectorFunctions.describe('Regular Inner', () => {
|
|
267
|
+
collectorFunctions.it('test 1', noop);
|
|
268
|
+
});
|
|
269
|
+
collectorFunctions.describe.only('Focused Inner', () => {
|
|
270
|
+
collectorFunctions.it('focused test', noop);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const outerSuite = collectedSuite.testSuite.suites[0];
|
|
276
|
+
expect(outerSuite.status).toBe('active');
|
|
277
|
+
expect(outerSuite._hasFocused).toBe(true);
|
|
278
|
+
expect(outerSuite.suites[0].status).toBe('skipped');
|
|
279
|
+
expect(outerSuite.suites[1].status).toBe('active');
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
describe('test collector - todo test recognition', () => {
|
|
284
|
+
it('should collect and mark todo tests with test.todo()', () => {
|
|
285
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
286
|
+
collectorFunctions.describe('Todo Suite', () => {
|
|
287
|
+
collectorFunctions.it('regular test', noop);
|
|
288
|
+
collectorFunctions.test.todo('todo test');
|
|
289
|
+
collectorFunctions.it.todo('another todo test');
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
const todoSuite = collectedSuite.testSuite.suites[0];
|
|
294
|
+
expect(todoSuite.tests).toHaveLength(3);
|
|
295
|
+
expect(todoSuite.tests[0].status).toBe('active');
|
|
296
|
+
expect(todoSuite.tests[1].status).toBe('todo');
|
|
297
|
+
expect(todoSuite.tests[2].status).toBe('todo');
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should collect todo tests without function bodies', () => {
|
|
301
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
302
|
+
collectorFunctions.describe('Todo Suite', () => {
|
|
303
|
+
collectorFunctions.test.todo('implement this feature');
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const todoSuite = collectedSuite.testSuite.suites[0];
|
|
308
|
+
expect(todoSuite.tests[0].name).toBe('implement this feature');
|
|
309
|
+
expect(todoSuite.tests[0].status).toBe('todo');
|
|
310
|
+
expect(typeof todoSuite.tests[0].fn).toBe('function');
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
describe('test collector - hook recognition', () => {
|
|
315
|
+
it('should collect beforeAll hooks', () => {
|
|
316
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
317
|
+
collectorFunctions.describe('Hook Suite', () => {
|
|
318
|
+
collectorFunctions.beforeAll(() => {
|
|
319
|
+
// setup
|
|
320
|
+
});
|
|
321
|
+
collectorFunctions.beforeAll(async () => {
|
|
322
|
+
// async setup
|
|
323
|
+
});
|
|
324
|
+
collectorFunctions.it('test', noop);
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const hookSuite = collectedSuite.testSuite.suites[0];
|
|
329
|
+
expect(hookSuite.beforeAll).toHaveLength(2);
|
|
330
|
+
expect(typeof hookSuite.beforeAll[0]).toBe('function');
|
|
331
|
+
expect(typeof hookSuite.beforeAll[1]).toBe('function');
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it('should collect afterAll hooks', () => {
|
|
335
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
336
|
+
collectorFunctions.describe('Hook Suite', () => {
|
|
337
|
+
collectorFunctions.afterAll(() => {
|
|
338
|
+
// cleanup
|
|
339
|
+
});
|
|
340
|
+
collectorFunctions.it('test', noop);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
const hookSuite = collectedSuite.testSuite.suites[0];
|
|
345
|
+
expect(hookSuite.afterAll).toHaveLength(1);
|
|
346
|
+
expect(typeof hookSuite.afterAll[0]).toBe('function');
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it('should collect beforeEach hooks', () => {
|
|
350
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
351
|
+
collectorFunctions.describe('Hook Suite', () => {
|
|
352
|
+
collectorFunctions.beforeEach(() => {
|
|
353
|
+
// setup each
|
|
354
|
+
});
|
|
355
|
+
collectorFunctions.beforeEach(async () => {
|
|
356
|
+
// async setup each
|
|
357
|
+
});
|
|
358
|
+
collectorFunctions.it('test', noop);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
const hookSuite = collectedSuite.testSuite.suites[0];
|
|
363
|
+
expect(hookSuite.beforeEach).toHaveLength(2);
|
|
364
|
+
expect(typeof hookSuite.beforeEach[0]).toBe('function');
|
|
365
|
+
expect(typeof hookSuite.beforeEach[1]).toBe('function');
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
it('should collect afterEach hooks', () => {
|
|
369
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
370
|
+
collectorFunctions.describe('Hook Suite', () => {
|
|
371
|
+
collectorFunctions.afterEach(() => {
|
|
372
|
+
// cleanup each
|
|
373
|
+
});
|
|
374
|
+
collectorFunctions.it('test', noop);
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const hookSuite = collectedSuite.testSuite.suites[0];
|
|
379
|
+
expect(hookSuite.afterEach).toHaveLength(1);
|
|
380
|
+
expect(typeof hookSuite.afterEach[0]).toBe('function');
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('should collect all types of hooks together', () => {
|
|
384
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
385
|
+
collectorFunctions.describe('All Hooks Suite', () => {
|
|
386
|
+
collectorFunctions.beforeAll(noop);
|
|
387
|
+
collectorFunctions.afterAll(noop);
|
|
388
|
+
collectorFunctions.beforeEach(noop);
|
|
389
|
+
collectorFunctions.afterEach(noop);
|
|
390
|
+
collectorFunctions.it('test', noop);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
const allHooksSuite = collectedSuite.testSuite.suites[0];
|
|
395
|
+
expect(allHooksSuite.beforeAll).toHaveLength(1);
|
|
396
|
+
expect(allHooksSuite.afterAll).toHaveLength(1);
|
|
397
|
+
expect(allHooksSuite.beforeEach).toHaveLength(1);
|
|
398
|
+
expect(allHooksSuite.afterEach).toHaveLength(1);
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it('should collect hooks at root level', () => {
|
|
402
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
403
|
+
collectorFunctions.beforeAll(() => {
|
|
404
|
+
// root level setup
|
|
405
|
+
});
|
|
406
|
+
collectorFunctions.afterAll(() => {
|
|
407
|
+
// root level cleanup
|
|
408
|
+
});
|
|
409
|
+
collectorFunctions.beforeEach(() => {
|
|
410
|
+
// root level setup each
|
|
411
|
+
});
|
|
412
|
+
collectorFunctions.afterEach(() => {
|
|
413
|
+
// root level cleanup each
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
collectorFunctions.describe('Test Suite', () => {
|
|
417
|
+
collectorFunctions.it('test', noop);
|
|
418
|
+
});
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// Collected root suite should have the hooks
|
|
422
|
+
expect(collectedSuite.testSuite.beforeAll).toHaveLength(1);
|
|
423
|
+
expect(collectedSuite.testSuite.afterAll).toHaveLength(1);
|
|
424
|
+
expect(collectedSuite.testSuite.beforeEach).toHaveLength(1);
|
|
425
|
+
expect(collectedSuite.testSuite.afterEach).toHaveLength(1);
|
|
426
|
+
expect(typeof collectedSuite.testSuite.beforeAll[0]).toBe('function');
|
|
427
|
+
expect(typeof collectedSuite.testSuite.afterAll[0]).toBe('function');
|
|
428
|
+
expect(typeof collectedSuite.testSuite.beforeEach[0]).toBe('function');
|
|
429
|
+
expect(typeof collectedSuite.testSuite.afterEach[0]).toBe('function');
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it('should collect hooks at both root and suite levels', () => {
|
|
433
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
434
|
+
// Root level hooks
|
|
435
|
+
collectorFunctions.beforeAll(() => {
|
|
436
|
+
// global setup
|
|
437
|
+
});
|
|
438
|
+
collectorFunctions.beforeEach(() => {
|
|
439
|
+
// global setup each
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
collectorFunctions.describe('Suite with hooks', () => {
|
|
443
|
+
// Suite level hooks
|
|
444
|
+
collectorFunctions.beforeAll(() => {
|
|
445
|
+
// suite setup
|
|
446
|
+
});
|
|
447
|
+
collectorFunctions.beforeEach(() => {
|
|
448
|
+
// suite setup each
|
|
449
|
+
});
|
|
450
|
+
collectorFunctions.it('test', noop);
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
// Collected root suite should have its hooks
|
|
455
|
+
expect(collectedSuite.testSuite.beforeAll).toHaveLength(1);
|
|
456
|
+
expect(collectedSuite.testSuite.beforeEach).toHaveLength(1);
|
|
457
|
+
|
|
458
|
+
// Child suite should have its own hooks
|
|
459
|
+
const childSuite = collectedSuite.testSuite.suites[0];
|
|
460
|
+
expect(childSuite.beforeAll).toHaveLength(1);
|
|
461
|
+
expect(childSuite.beforeEach).toHaveLength(1);
|
|
462
|
+
});
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
describe('test collector - complex scenarios', () => {
|
|
466
|
+
it('should collect mix of tests, suites, hooks, and modifiers', () => {
|
|
467
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
468
|
+
collectorFunctions.describe('Complex Suite', () => {
|
|
469
|
+
collectorFunctions.beforeAll(noop);
|
|
470
|
+
collectorFunctions.beforeEach(noop);
|
|
471
|
+
|
|
472
|
+
collectorFunctions.it('regular test', noop);
|
|
473
|
+
collectorFunctions.test.skip('skipped test', noop);
|
|
474
|
+
collectorFunctions.test.todo('todo test');
|
|
475
|
+
|
|
476
|
+
collectorFunctions.describe.skip('Skipped Inner Suite', () => {
|
|
477
|
+
collectorFunctions.it('inner test', noop);
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
collectorFunctions.describe('Regular Inner Suite', () => {
|
|
481
|
+
collectorFunctions.beforeEach(noop);
|
|
482
|
+
collectorFunctions.it('inner test 1', noop);
|
|
483
|
+
collectorFunctions.test.only('focused inner test', noop);
|
|
484
|
+
collectorFunctions.it('inner test 2', noop);
|
|
485
|
+
collectorFunctions.afterEach(noop);
|
|
486
|
+
});
|
|
487
|
+
|
|
488
|
+
collectorFunctions.afterAll(noop);
|
|
489
|
+
});
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
const complexSuite = collectedSuite.testSuite.suites[0];
|
|
493
|
+
|
|
494
|
+
// Check hooks
|
|
495
|
+
expect(complexSuite.beforeAll).toHaveLength(1);
|
|
496
|
+
expect(complexSuite.afterAll).toHaveLength(1);
|
|
497
|
+
expect(complexSuite.beforeEach).toHaveLength(1);
|
|
498
|
+
|
|
499
|
+
// Check tests
|
|
500
|
+
expect(complexSuite.tests).toHaveLength(3);
|
|
501
|
+
expect(complexSuite.tests[0].status).toBe('active');
|
|
502
|
+
expect(complexSuite.tests[1].status).toBe('skipped');
|
|
503
|
+
expect(complexSuite.tests[2].status).toBe('todo');
|
|
504
|
+
|
|
505
|
+
// Check nested suites
|
|
506
|
+
expect(complexSuite.suites).toHaveLength(2);
|
|
507
|
+
expect(complexSuite.suites[0].status).toBe('skipped');
|
|
508
|
+
|
|
509
|
+
const innerSuite = complexSuite.suites[1];
|
|
510
|
+
expect(innerSuite.beforeEach).toHaveLength(1);
|
|
511
|
+
expect(innerSuite.afterEach).toHaveLength(1);
|
|
512
|
+
expect(innerSuite.tests).toHaveLength(3);
|
|
513
|
+
expect(innerSuite.tests[0].status).toBe('skipped'); // Due to .only
|
|
514
|
+
expect(innerSuite.tests[1].status).toBe('active'); // The .only test
|
|
515
|
+
expect(innerSuite.tests[2].status).toBe('skipped'); // Due to .only
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
it('should clear collector state between collectTests calls', () => {
|
|
519
|
+
const collectedSuite1 = collectorFunctions.collectTests(() => {
|
|
520
|
+
collectorFunctions.describe('Suite 1', () => {
|
|
521
|
+
collectorFunctions.it('test 1', noop);
|
|
522
|
+
});
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
const collectedSuite2 = collectorFunctions.collectTests(() => {
|
|
526
|
+
collectorFunctions.describe('Suite 2', () => {
|
|
527
|
+
collectorFunctions.it('test 2', noop);
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
expect(collectedSuite1.testSuite.suites).toHaveLength(1);
|
|
532
|
+
expect(collectedSuite2.testSuite.suites).toHaveLength(1);
|
|
533
|
+
expect(collectedSuite1.testSuite.suites[0].name).toBe('Suite 1');
|
|
534
|
+
expect(collectedSuite2.testSuite.suites[0].name).toBe('Suite 2');
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('should collect empty describe blocks', () => {
|
|
538
|
+
const collectedSuite = collectorFunctions.collectTests(() => {
|
|
539
|
+
collectorFunctions.describe('Empty Suite', () => {
|
|
540
|
+
// No tests or hooks
|
|
541
|
+
});
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
const emptySuite = collectedSuite.testSuite.suites[0];
|
|
545
|
+
expect(emptySuite.name).toBe('Empty Suite');
|
|
546
|
+
expect(emptySuite.tests).toHaveLength(0);
|
|
547
|
+
expect(emptySuite.suites).toHaveLength(0);
|
|
548
|
+
expect(emptySuite.beforeAll).toHaveLength(0);
|
|
549
|
+
expect(emptySuite.afterAll).toHaveLength(0);
|
|
550
|
+
expect(emptySuite.beforeEach).toHaveLength(0);
|
|
551
|
+
expect(emptySuite.afterEach).toHaveLength(0);
|
|
552
|
+
});
|
|
553
|
+
});
|