@vitronai/themis 0.1.0-beta.0 → 0.1.0-beta.2
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/CHANGELOG.md +16 -1
- package/README.md +173 -11
- package/docs/api.md +272 -4
- package/docs/schemas/agent-result.v1.json +7 -4
- package/docs/schemas/fix-handoff.v1.json +105 -0
- package/docs/schemas/generate-backlog.v1.json +117 -0
- package/docs/schemas/generate-handoff.v1.json +191 -0
- package/docs/schemas/generate-map.v1.json +95 -0
- package/docs/schemas/generate-result.v1.json +341 -0
- package/docs/vscode-extension.md +6 -0
- package/docs/why-themis.md +1 -1
- package/globals.d.ts +31 -1
- package/index.d.ts +405 -2
- package/index.js +14 -0
- package/package.json +1 -1
- package/src/artifacts.js +180 -2
- package/src/assets/exampleThemisReport.png +0 -0
- package/src/cli.js +390 -11
- package/src/config.js +21 -3
- package/src/discovery.js +32 -3
- package/src/expect.js +33 -4
- package/src/generate.js +5313 -0
- package/src/migrate.js +280 -0
- package/src/module-loader.js +22 -3
- package/src/reporter.js +4 -3
- package/src/runner.js +74 -13
- package/src/runtime.js +175 -66
- package/src/test-utils.js +607 -1
- package/src/watch.js +9 -0
- package/src/worker.js +1 -2
- package/src/snapshots.js +0 -90
package/src/runtime.js
CHANGED
|
@@ -3,7 +3,6 @@ const path = require('path');
|
|
|
3
3
|
const { createExpect } = require('./expect');
|
|
4
4
|
const { createModuleLoader } = require('./module-loader');
|
|
5
5
|
const { installTestEnvironment } = require('./environment');
|
|
6
|
-
const { createSnapshotState } = require('./snapshots');
|
|
7
6
|
const { createTestUtils } = require('./test-utils');
|
|
8
7
|
|
|
9
8
|
const INTENT_PHASE_ALIASES = {
|
|
@@ -40,16 +39,32 @@ function collectAndRun(filePath, options = {}) {
|
|
|
40
39
|
let currentSuite = root;
|
|
41
40
|
const projectRoot = path.resolve(options.cwd || process.cwd());
|
|
42
41
|
const setupFiles = resolveSetupFiles(options.setupFiles, projectRoot);
|
|
42
|
+
const environment = installTestEnvironment(options.environment || 'node');
|
|
43
|
+
const runtimeBindings = {
|
|
44
|
+
api: null,
|
|
45
|
+
testUtils: null
|
|
46
|
+
};
|
|
43
47
|
const moduleLoader = createModuleLoader({
|
|
44
48
|
cwd: projectRoot,
|
|
45
|
-
tsconfigPath: options.tsconfigPath
|
|
46
|
-
|
|
47
|
-
const environment = installTestEnvironment(options.environment || 'node');
|
|
48
|
-
const snapshotState = createSnapshotState(path.resolve(filePath), {
|
|
49
|
-
updateSnapshots: Boolean(options.updateSnapshots)
|
|
49
|
+
tsconfigPath: options.tsconfigPath,
|
|
50
|
+
virtualModules: buildCompatibilityVirtualModules(runtimeBindings)
|
|
50
51
|
});
|
|
51
52
|
const testUtils = createTestUtils({ moduleLoader });
|
|
52
|
-
const runtimeExpect = createExpect(
|
|
53
|
+
const runtimeExpect = createExpect();
|
|
54
|
+
const runtimeApi = buildRuntimeApi({
|
|
55
|
+
root,
|
|
56
|
+
options,
|
|
57
|
+
testUtils,
|
|
58
|
+
runtimeExpect,
|
|
59
|
+
getCurrentSuite() {
|
|
60
|
+
return currentSuite;
|
|
61
|
+
},
|
|
62
|
+
setCurrentSuite(nextSuite) {
|
|
63
|
+
currentSuite = nextSuite;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
runtimeBindings.api = runtimeApi;
|
|
67
|
+
runtimeBindings.testUtils = testUtils;
|
|
53
68
|
|
|
54
69
|
if (typeof environment.beforeEach === 'function') {
|
|
55
70
|
root.hooks.beforeEach.push(environment.beforeEach);
|
|
@@ -58,51 +73,7 @@ function collectAndRun(filePath, options = {}) {
|
|
|
58
73
|
root.hooks.afterEach.push(environment.afterEach);
|
|
59
74
|
}
|
|
60
75
|
|
|
61
|
-
const previousGlobals = installGlobals(
|
|
62
|
-
describe(name, fn) {
|
|
63
|
-
if (typeof fn !== 'function') {
|
|
64
|
-
throw new Error(`describe(${name}) requires a callback`);
|
|
65
|
-
}
|
|
66
|
-
const suite = createSuite(name, currentSuite);
|
|
67
|
-
currentSuite.suites.push(suite);
|
|
68
|
-
const parent = currentSuite;
|
|
69
|
-
currentSuite = suite;
|
|
70
|
-
try {
|
|
71
|
-
fn();
|
|
72
|
-
} finally {
|
|
73
|
-
currentSuite = parent;
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
test(name, fn) {
|
|
77
|
-
if (typeof fn !== 'function') {
|
|
78
|
-
throw new Error(`test(${name}) requires a callback`);
|
|
79
|
-
}
|
|
80
|
-
currentSuite.tests.push({ name, fn });
|
|
81
|
-
},
|
|
82
|
-
intent(name, define) {
|
|
83
|
-
if (typeof define !== 'function') {
|
|
84
|
-
throw new Error(`intent(${name}) requires a callback`);
|
|
85
|
-
}
|
|
86
|
-
const intentTest = createIntentTest(name, define, {
|
|
87
|
-
noMemes: Boolean(options.noMemes)
|
|
88
|
-
});
|
|
89
|
-
currentSuite.tests.push(intentTest);
|
|
90
|
-
},
|
|
91
|
-
beforeAll(fn) {
|
|
92
|
-
currentSuite.hooks.beforeAll.push(fn);
|
|
93
|
-
},
|
|
94
|
-
beforeEach(fn) {
|
|
95
|
-
currentSuite.hooks.beforeEach.push(fn);
|
|
96
|
-
},
|
|
97
|
-
afterEach(fn) {
|
|
98
|
-
currentSuite.hooks.afterEach.push(fn);
|
|
99
|
-
},
|
|
100
|
-
afterAll(fn) {
|
|
101
|
-
currentSuite.hooks.afterAll.push(fn);
|
|
102
|
-
},
|
|
103
|
-
expect: runtimeExpect,
|
|
104
|
-
...testUtils
|
|
105
|
-
});
|
|
76
|
+
const previousGlobals = installGlobals(runtimeApi);
|
|
106
77
|
|
|
107
78
|
let loadError = null;
|
|
108
79
|
try {
|
|
@@ -136,15 +107,11 @@ function collectAndRun(filePath, options = {}) {
|
|
|
136
107
|
const results = [];
|
|
137
108
|
const runOptions = {
|
|
138
109
|
matchRegex: options.match ? new RegExp(options.match) : null,
|
|
139
|
-
allowedFullNames: toSet(options.allowedFullNames)
|
|
140
|
-
snapshotState
|
|
110
|
+
allowedFullNames: toSet(options.allowedFullNames)
|
|
141
111
|
};
|
|
142
112
|
|
|
143
113
|
return runSuite(root, [root], results, runOptions)
|
|
144
|
-
.then(() => {
|
|
145
|
-
snapshotState.save();
|
|
146
|
-
return { file: filePath, tests: results };
|
|
147
|
-
})
|
|
114
|
+
.then(() => ({ file: filePath, tests: results }))
|
|
148
115
|
.finally(() => {
|
|
149
116
|
restoreGlobals(previousGlobals);
|
|
150
117
|
testUtils.restoreAllMocks();
|
|
@@ -153,6 +120,129 @@ function collectAndRun(filePath, options = {}) {
|
|
|
153
120
|
});
|
|
154
121
|
}
|
|
155
122
|
|
|
123
|
+
function buildRuntimeApi({ root, options, testUtils, runtimeExpect, getCurrentSuite, setCurrentSuite }) {
|
|
124
|
+
return {
|
|
125
|
+
describe(name, fn) {
|
|
126
|
+
if (typeof fn !== 'function') {
|
|
127
|
+
throw new Error(`describe(${name}) requires a callback`);
|
|
128
|
+
}
|
|
129
|
+
const suite = createSuite(name, getCurrentSuite());
|
|
130
|
+
getCurrentSuite().suites.push(suite);
|
|
131
|
+
const parent = getCurrentSuite();
|
|
132
|
+
setCurrentSuite(suite);
|
|
133
|
+
try {
|
|
134
|
+
fn();
|
|
135
|
+
} finally {
|
|
136
|
+
setCurrentSuite(parent);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
test(name, fn) {
|
|
140
|
+
if (typeof fn !== 'function') {
|
|
141
|
+
throw new Error(`test(${name}) requires a callback`);
|
|
142
|
+
}
|
|
143
|
+
getCurrentSuite().tests.push({ name, fn });
|
|
144
|
+
},
|
|
145
|
+
intent(name, define) {
|
|
146
|
+
if (typeof define !== 'function') {
|
|
147
|
+
throw new Error(`intent(${name}) requires a callback`);
|
|
148
|
+
}
|
|
149
|
+
const intentTest = createIntentTest(name, define, {
|
|
150
|
+
noMemes: Boolean(options.noMemes)
|
|
151
|
+
});
|
|
152
|
+
getCurrentSuite().tests.push(intentTest);
|
|
153
|
+
},
|
|
154
|
+
beforeAll(fn) {
|
|
155
|
+
getCurrentSuite().hooks.beforeAll.push(fn);
|
|
156
|
+
},
|
|
157
|
+
beforeEach(fn) {
|
|
158
|
+
getCurrentSuite().hooks.beforeEach.push(fn);
|
|
159
|
+
},
|
|
160
|
+
afterEach(fn) {
|
|
161
|
+
getCurrentSuite().hooks.afterEach.push(fn);
|
|
162
|
+
},
|
|
163
|
+
afterAll(fn) {
|
|
164
|
+
getCurrentSuite().hooks.afterAll.push(fn);
|
|
165
|
+
},
|
|
166
|
+
expect: runtimeExpect,
|
|
167
|
+
...testUtils
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function buildCompatibilityVirtualModules(bindings) {
|
|
172
|
+
return {
|
|
173
|
+
'@jest/globals': () => buildJestGlobals(bindings.api, bindings.testUtils),
|
|
174
|
+
vitest: () => buildVitestGlobals(bindings.api, bindings.testUtils),
|
|
175
|
+
'@testing-library/react': () => buildTestingLibraryCompat(bindings.api)
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function buildJestGlobals(api, testUtils) {
|
|
180
|
+
const jestLike = buildJestLikeApi(api, testUtils);
|
|
181
|
+
return {
|
|
182
|
+
describe: api.describe,
|
|
183
|
+
test: api.test,
|
|
184
|
+
it: api.test,
|
|
185
|
+
expect: api.expect,
|
|
186
|
+
beforeAll: api.beforeAll,
|
|
187
|
+
beforeEach: api.beforeEach,
|
|
188
|
+
afterEach: api.afterEach,
|
|
189
|
+
afterAll: api.afterAll,
|
|
190
|
+
jest: jestLike
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function buildVitestGlobals(api, testUtils) {
|
|
195
|
+
const jestLike = buildJestLikeApi(api, testUtils);
|
|
196
|
+
return {
|
|
197
|
+
describe: api.describe,
|
|
198
|
+
test: api.test,
|
|
199
|
+
it: api.test,
|
|
200
|
+
expect: api.expect,
|
|
201
|
+
beforeAll: api.beforeAll,
|
|
202
|
+
beforeEach: api.beforeEach,
|
|
203
|
+
afterEach: api.afterEach,
|
|
204
|
+
afterAll: api.afterAll,
|
|
205
|
+
vi: jestLike
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function buildTestingLibraryCompat(api) {
|
|
210
|
+
return {
|
|
211
|
+
render: api.render,
|
|
212
|
+
screen: api.screen,
|
|
213
|
+
fireEvent: api.fireEvent,
|
|
214
|
+
waitFor: api.waitFor,
|
|
215
|
+
cleanup: api.cleanup,
|
|
216
|
+
act: async (callback) => {
|
|
217
|
+
if (typeof callback !== 'function') {
|
|
218
|
+
return undefined;
|
|
219
|
+
}
|
|
220
|
+
return callback();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function buildJestLikeApi(api, testUtils) {
|
|
226
|
+
return {
|
|
227
|
+
fn: api.fn,
|
|
228
|
+
spyOn: api.spyOn,
|
|
229
|
+
mock: api.mock,
|
|
230
|
+
unmock: api.unmock,
|
|
231
|
+
clearAllMocks: api.clearAllMocks,
|
|
232
|
+
resetAllMocks: api.resetAllMocks,
|
|
233
|
+
restoreAllMocks: api.restoreAllMocks,
|
|
234
|
+
useFakeTimers: api.useFakeTimers,
|
|
235
|
+
useRealTimers: api.useRealTimers,
|
|
236
|
+
advanceTimersByTime: api.advanceTimersByTime,
|
|
237
|
+
runAllTimers: api.runAllTimers,
|
|
238
|
+
resetModules() {
|
|
239
|
+
if (testUtils && typeof testUtils.resetAllMocks === 'function') {
|
|
240
|
+
testUtils.resetAllMocks();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
156
246
|
function resolveSetupFiles(setupFiles, cwd) {
|
|
157
247
|
if (!Array.isArray(setupFiles) || setupFiles.length === 0) {
|
|
158
248
|
return [];
|
|
@@ -195,10 +285,6 @@ async function runSuite(suite, lineage, results, options) {
|
|
|
195
285
|
continue;
|
|
196
286
|
}
|
|
197
287
|
|
|
198
|
-
if (options.snapshotState) {
|
|
199
|
-
options.snapshotState.setCurrentTestName(testName);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
288
|
try {
|
|
203
289
|
const beforeEachHooks = collectHooks(nextLineage, 'beforeEach', false);
|
|
204
290
|
for (const hook of beforeEachHooks) {
|
|
@@ -211,9 +297,6 @@ async function runSuite(suite, lineage, results, options) {
|
|
|
211
297
|
status = 'failed';
|
|
212
298
|
error = normalizeError(err);
|
|
213
299
|
} finally {
|
|
214
|
-
if (options.snapshotState) {
|
|
215
|
-
options.snapshotState.clearCurrentTestName();
|
|
216
|
-
}
|
|
217
300
|
if (beforeEachSucceeded) {
|
|
218
301
|
const afterEachHooks = collectHooks(nextLineage, 'afterEach', true);
|
|
219
302
|
for (const hook of afterEachHooks) {
|
|
@@ -279,7 +362,20 @@ function installGlobals(api) {
|
|
|
279
362
|
'unmock',
|
|
280
363
|
'clearAllMocks',
|
|
281
364
|
'resetAllMocks',
|
|
282
|
-
'restoreAllMocks'
|
|
365
|
+
'restoreAllMocks',
|
|
366
|
+
'render',
|
|
367
|
+
'screen',
|
|
368
|
+
'fireEvent',
|
|
369
|
+
'waitFor',
|
|
370
|
+
'cleanup',
|
|
371
|
+
'useFakeTimers',
|
|
372
|
+
'useRealTimers',
|
|
373
|
+
'advanceTimersByTime',
|
|
374
|
+
'runAllTimers',
|
|
375
|
+
'flushMicrotasks',
|
|
376
|
+
'mockFetch',
|
|
377
|
+
'restoreFetch',
|
|
378
|
+
'resetFetchMocks'
|
|
283
379
|
];
|
|
284
380
|
const previous = {};
|
|
285
381
|
for (const name of names) {
|
|
@@ -302,6 +398,19 @@ function installGlobals(api) {
|
|
|
302
398
|
global.clearAllMocks = api.clearAllMocks;
|
|
303
399
|
global.resetAllMocks = api.resetAllMocks;
|
|
304
400
|
global.restoreAllMocks = api.restoreAllMocks;
|
|
401
|
+
global.render = api.render;
|
|
402
|
+
global.screen = api.screen;
|
|
403
|
+
global.fireEvent = api.fireEvent;
|
|
404
|
+
global.waitFor = api.waitFor;
|
|
405
|
+
global.cleanup = api.cleanup;
|
|
406
|
+
global.useFakeTimers = api.useFakeTimers;
|
|
407
|
+
global.useRealTimers = api.useRealTimers;
|
|
408
|
+
global.advanceTimersByTime = api.advanceTimersByTime;
|
|
409
|
+
global.runAllTimers = api.runAllTimers;
|
|
410
|
+
global.flushMicrotasks = api.flushMicrotasks;
|
|
411
|
+
global.mockFetch = api.mockFetch;
|
|
412
|
+
global.restoreFetch = api.restoreFetch;
|
|
413
|
+
global.resetFetchMocks = api.resetFetchMocks;
|
|
305
414
|
|
|
306
415
|
return previous;
|
|
307
416
|
}
|