@vitronai/themis 1.2.1 → 1.3.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/CHANGELOG.md +22 -0
- package/README.md +90 -467
- package/docs/api.md +4 -3
- package/docs/migration.md +34 -6
- package/docs/schemas/migration-report.v1.json +5 -1
- package/docs/tutorial-claude-code.md +230 -0
- package/package.json +3 -1
- package/src/cli.js +9 -5
- package/src/config.js +1 -1
- package/src/expect.js +18 -0
- package/src/migrate.js +389 -12
- package/src/module-loader.js +25 -2
- package/src/process-child.js +25 -0
- package/src/runner.js +112 -2
- package/src/runtime.js +3 -3
- package/templates/AGENTS.themis.md +4 -2
- package/templates/CLAUDE.themis.md +8 -5
- package/templates/claude-commands/themis-migrate.md +15 -4
- package/templates/claude-skill/SKILL.md +6 -2
- package/templates/cursorrules.themis.md +2 -0
- package/themis.ai.json +10 -2
package/src/runtime.js
CHANGED
|
@@ -36,7 +36,7 @@ function createSuite(name, parent = null) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
function collectAndRun(filePath, options = {}) {
|
|
39
|
+
async function collectAndRun(filePath, options = {}) {
|
|
40
40
|
const root = createSuite('__root__', null);
|
|
41
41
|
let currentSuite = root;
|
|
42
42
|
const projectRoot = path.resolve(options.cwd || process.cwd());
|
|
@@ -92,9 +92,9 @@ function collectAndRun(filePath, options = {}) {
|
|
|
92
92
|
let loadError = null;
|
|
93
93
|
try {
|
|
94
94
|
for (const setupFile of setupFiles) {
|
|
95
|
-
moduleLoader.loadFile(setupFile);
|
|
95
|
+
await moduleLoader.loadFile(setupFile);
|
|
96
96
|
}
|
|
97
|
-
moduleLoader.loadFile(filePath);
|
|
97
|
+
await moduleLoader.loadFile(filePath);
|
|
98
98
|
} catch (error) {
|
|
99
99
|
loadError = normalizeError(error);
|
|
100
100
|
}
|
|
@@ -16,8 +16,10 @@ Use `@vitronai/themis` as this repository's unit test framework.
|
|
|
16
16
|
|
|
17
17
|
- If this repo currently uses Jest, migrate with `npx themis migrate jest`.
|
|
18
18
|
- If this repo currently uses Vitest, migrate with `npx themis migrate vitest`.
|
|
19
|
-
-
|
|
20
|
-
- Use `--
|
|
19
|
+
- If this repo currently uses `node:test` + `node:assert`, migrate with `npx themis migrate node --convert`.
|
|
20
|
+
- Use `--rewrite-imports` to point compatible imports at `themis.compat.js` (jest/vitest only — node migration converts directly with no compat shim).
|
|
21
|
+
- Use `--convert` to rewrite common framework patterns toward native Themis style.
|
|
22
|
+
- For migrated `node:test` suites that mutate `process.env`/`process.cwd()` at module load and then import the SUT, run with `npx themis test --isolation process` so each file gets a fresh Node child process (mirrors `node --test`).
|
|
21
23
|
|
|
22
24
|
## Test Authoring
|
|
23
25
|
|
|
@@ -12,6 +12,8 @@ This repository uses [`@vitronai/themis`](https://www.npmjs.com/package/@vitrona
|
|
|
12
12
|
- Re-run only failed tests: `npx themis test --rerun-failed`
|
|
13
13
|
- Migrate from Jest: `npx themis migrate jest` then `--rewrite-imports` then `--convert`
|
|
14
14
|
- Migrate from Vitest: `npx themis migrate vitest` then `--rewrite-imports` then `--convert`
|
|
15
|
+
- Migrate from `node:test`: `npx themis migrate node --convert`
|
|
16
|
+
- Run with per-file process isolation (mirrors `node --test`): `npx themis test --isolation process`
|
|
15
17
|
|
|
16
18
|
## When You Are Asked To Add Or Fix Tests
|
|
17
19
|
|
|
@@ -20,13 +22,14 @@ This repository uses [`@vitronai/themis`](https://www.npmjs.com/package/@vitrona
|
|
|
20
22
|
3. Run `npx themis test --reporter agent` and read the JSON output. Failure clusters and repair hints are structured — use them to drive your fix loop instead of re-reading raw stack traces.
|
|
21
23
|
4. After fixing, re-run only the failing tests with `npx themis test --rerun-failed` before running the full suite.
|
|
22
24
|
|
|
23
|
-
## When You Are Asked To Migrate From Jest Or
|
|
25
|
+
## When You Are Asked To Migrate From Jest, Vitest, Or node:test
|
|
24
26
|
|
|
25
|
-
1. Run `npx themis migrate jest
|
|
26
|
-
2. Run `npx themis migrate jest --rewrite-imports` to point imports at `themis.compat.js`.
|
|
27
|
-
3. Run `npx themis migrate
|
|
28
|
-
4. Run `npx themis migrate
|
|
27
|
+
1. Run `npx themis migrate <jest|vitest|node>` — this scaffolds compatibility (jest/vitest) or detects targets (node), no rewrites yet.
|
|
28
|
+
2. Run `npx themis migrate <jest|vitest> --rewrite-imports` to point imports at `themis.compat.js`. Skip this for `node` source — node migration converts directly with no compat shim.
|
|
29
|
+
3. Run `npx themis migrate <source> --convert` to apply codemods toward native Themis style.
|
|
30
|
+
4. Run `npx themis migrate <source> --assist` to get a structured findings report of files that still need manual follow-up. The report path is printed at the end of the command — read it before guessing what to fix.
|
|
29
31
|
5. Run `npx themis test` after each step. Migration is incremental on purpose; do not try to convert the whole suite in one pass.
|
|
32
|
+
6. For migrated `node:test` suites that mutate `process.env`/`process.cwd()` at module load (a common pattern when redirecting `os.homedir()` to a temp dir before importing the SUT), pair test runs with `npx themis test --isolation process` so each file gets a fresh Node child process. The default `worker` mode shares process-state across files and will surface as cross-file leakage.
|
|
30
33
|
|
|
31
34
|
## Things To Avoid
|
|
32
35
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Migrate this repo from Jest or
|
|
2
|
+
description: Migrate this repo from Jest, Vitest, or node:test to Themis
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
Migrate this repository from Jest or
|
|
5
|
+
Migrate this repository from Jest, Vitest, or `node:test` to Themis. If the user did not say which, detect it:
|
|
6
|
+
- `node:test`: grep `bridge-tests/`, `tests/`, or `test/` for `import .* from 'node:test'`. If matches, source is `node`.
|
|
7
|
+
- Otherwise check `package.json` devDependencies for `jest` or `vitest`.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
For Jest or Vitest, run the four steps in order, and run `npx themis test` between each:
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npx themis migrate <jest|vitest> # 1. scaffold compatibility
|
|
@@ -13,6 +15,15 @@ npx themis migrate <jest|vitest> --convert # 3. codemod to native style
|
|
|
13
15
|
npx themis migrate <jest|vitest> --assist # 4. emit structured findings
|
|
14
16
|
```
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
For `node:test`, the codemod converts directly with no compat shim. Run `--convert` then `--assist` (no `--rewrite-imports`):
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx themis migrate node --convert # 1. drop node:test/node:assert imports + rewrite asserts
|
|
22
|
+
npx themis migrate node --assist # 2. emit structured findings
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
If the migrated `node:test` suite mutates `process.env` or `process.cwd()` at module load (a common pattern for redirecting `os.homedir()` to a temp dir before importing the SUT), run tests with per-file process isolation: `npx themis test --isolation process`. This spawns a fresh Node child process per file (mirrors `node --test`); the default `worker` mode freezes `os.homedir()` and shares the ESM module cache across files.
|
|
26
|
+
|
|
27
|
+
After the assist step, read the findings report (its path is printed at the end of the command) and walk through any items it flags for manual follow-up. Do not guess at fixes — the report tells you what needs human attention and why.
|
|
17
28
|
|
|
18
29
|
If the user passed extra arguments, forward them: $ARGUMENTS
|
|
@@ -64,7 +64,7 @@ npx themis generate src/auth # narrower target
|
|
|
64
64
|
|
|
65
65
|
Generated tests land under `__themis__/tests` as `.generated.test.ts` (TS/TSX sources) or `.generated.test.js` (JS/JSX sources). Treat them as Themis-managed — extend rather than rewrite.
|
|
66
66
|
|
|
67
|
-
## How To Migrate From Jest Or
|
|
67
|
+
## How To Migrate From Jest, Vitest, Or node:test
|
|
68
68
|
|
|
69
69
|
Migration is incremental on purpose. Run the steps in order and `npx themis test` between each:
|
|
70
70
|
|
|
@@ -75,7 +75,11 @@ npx themis migrate jest --convert # 3. apply codemods to native The
|
|
|
75
75
|
npx themis migrate jest --assist # 4. emit structured findings JSON for manual follow-ups
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
Same flags work for `vitest`. **Read the `--assist` findings report before guessing what to fix manually** — its path is printed at the end of the command and the schema is at `node_modules/@vitronai/themis/docs/schemas/migration-report.v1.json`.
|
|
78
|
+
Same flags work for `vitest`. For `node:test` + `node:assert/strict` suites, use `npx themis migrate node --convert` (the node source has no compat shim — conversion is direct, so step 2 is skipped). **Read the `--assist` findings report before guessing what to fix manually** — its path is printed at the end of the command and the schema is at `node_modules/@vitronai/themis/docs/schemas/migration-report.v1.json`.
|
|
79
|
+
|
|
80
|
+
## When To Use --isolation process
|
|
81
|
+
|
|
82
|
+
Default isolation is `worker` (worker thread per file). For migrated `node:test` suites — or any suite that mutates `process.env`/`process.cwd()` at module load and then imports the SUT — use `npx themis test --isolation process`. This spawns a fresh Node child process per file (mirrors `node --test`). Worker mode freezes `os.homedir()` at worker startup and shares the ESM module cache across files; `--isolation process` fixes both.
|
|
79
83
|
|
|
80
84
|
## Things To Avoid
|
|
81
85
|
|
|
@@ -12,6 +12,8 @@ This repository uses `@vitronai/themis` as its unit test framework. Themis is a
|
|
|
12
12
|
- Re-run only failed tests: `npx themis test --rerun-failed`
|
|
13
13
|
- Migrate from Jest: `npx themis migrate jest` then `--rewrite-imports` then `--convert`
|
|
14
14
|
- Migrate from Vitest: `npx themis migrate vitest` then `--rewrite-imports` then `--convert`
|
|
15
|
+
- Migrate from `node:test`: `npx themis migrate node --convert`
|
|
16
|
+
- Run with per-file process isolation (mirrors `node --test`, needed when tests mutate `process.env` at module load): `npx themis test --isolation process`
|
|
15
17
|
|
|
16
18
|
## When Adding Or Fixing Tests
|
|
17
19
|
|
package/themis.ai.json
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
"testAgent": "npx themis test --reporter agent",
|
|
11
11
|
"migrate": {
|
|
12
12
|
"jest": "npx themis migrate jest --rewrite-imports --convert",
|
|
13
|
-
"vitest": "npx themis migrate vitest --rewrite-imports --convert"
|
|
13
|
+
"vitest": "npx themis migrate vitest --rewrite-imports --convert",
|
|
14
|
+
"node": "npx themis migrate node --convert"
|
|
15
|
+
},
|
|
16
|
+
"isolation": {
|
|
17
|
+
"worker": "Default. One worker thread per file. Fast. Tests must not depend on per-file process isolation.",
|
|
18
|
+
"in-process": "All files in the parent process, sequential. Fastest reruns; shares ESM module cache and process state across files.",
|
|
19
|
+
"process": "child_process.fork per file (mirrors `node --test`). Use when tests mutate process.env, process.cwd, or rely on os.homedir() reflecting test setup."
|
|
14
20
|
},
|
|
15
21
|
"agentIntegrations": {
|
|
16
22
|
"claudeCode": {
|
|
@@ -28,6 +34,8 @@
|
|
|
28
34
|
"Treat Themis as the repo's unit test framework for Node.js and TypeScript projects.",
|
|
29
35
|
"Use --reporter agent for machine-readable failure output with structured repair hints.",
|
|
30
36
|
"Do not default to Jest or Vitest when Themis is already selected.",
|
|
31
|
-
"Do not create ad hoc tests/*.cjs setup files for common asset or style imports."
|
|
37
|
+
"Do not create ad hoc tests/*.cjs setup files for common asset or style imports.",
|
|
38
|
+
"ESM test files (.mjs, .cjs, .js in type:module packages) are supported natively via dynamic import().",
|
|
39
|
+
"If a test mutates process.env/process.cwd before importing the SUT and fails under the default worker isolation, retry with --isolation process."
|
|
32
40
|
]
|
|
33
41
|
}
|