unitbob 0.2.2 → 0.2.4
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/dist/files/behavioral.js +19 -6
- package/dist/runner/bdd.js +14 -16
- package/dist/verbs/run.js +1 -1
- package/package.json +1 -1
package/dist/files/behavioral.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { mkdirSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { assertUnitbobPath } from "./artifactPath.js";
|
|
4
4
|
// The behavioral suite lives under its own root: the main `.feature` plus its
|
|
@@ -9,14 +9,21 @@ import { assertUnitbobPath } from "./artifactPath.js";
|
|
|
9
9
|
// blob only so `check` can execute it locally.
|
|
10
10
|
export const BEHAVIORAL_DIR = '.unitbob/behavioral';
|
|
11
11
|
// Write a behavioral artifact envelope (main file + support files) under the
|
|
12
|
-
// behavioral root, after checking every path is safe.
|
|
13
|
-
//
|
|
14
|
-
// path of the materialized main file.
|
|
15
|
-
export function materializeBehavioral(projectRoot, artifact) {
|
|
12
|
+
// behavioral root, after checking every path is safe. Stale suite artifacts are
|
|
13
|
+
// removed while the separately provisioned runner environment is preserved.
|
|
14
|
+
// Returns the absolute path of the materialized main file.
|
|
15
|
+
export function materializeBehavioral(projectRoot, artifact, runner) {
|
|
16
16
|
const files = [artifact, ...(artifact.support_files ?? [])];
|
|
17
17
|
for (const file of files)
|
|
18
18
|
assertUnitbobPath(file.path, BEHAVIORAL_DIR);
|
|
19
|
-
|
|
19
|
+
const behavioralRoot = join(projectRoot, BEHAVIORAL_DIR);
|
|
20
|
+
const runnerEntries = RUNNER_ENVIRONMENT_ENTRIES[runner] ?? EMPTY_ENTRIES;
|
|
21
|
+
mkdirSync(behavioralRoot, { recursive: true });
|
|
22
|
+
for (const entry of readdirSync(behavioralRoot)) {
|
|
23
|
+
if (!runnerEntries.has(entry)) {
|
|
24
|
+
rmSync(join(behavioralRoot, entry), { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
20
27
|
let mainPath = '';
|
|
21
28
|
for (const file of files) {
|
|
22
29
|
const dest = join(projectRoot, file.path);
|
|
@@ -27,3 +34,9 @@ export function materializeBehavioral(projectRoot, artifact) {
|
|
|
27
34
|
}
|
|
28
35
|
return { mainPath };
|
|
29
36
|
}
|
|
37
|
+
const EMPTY_ENTRIES = new Set();
|
|
38
|
+
const RUNNER_ENVIRONMENT_ENTRIES = {
|
|
39
|
+
cucumber: new Set(['.bundle', 'Gemfile', 'Gemfile.lock']),
|
|
40
|
+
'cucumber-js': new Set(['node_modules', 'package.json', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock']),
|
|
41
|
+
'pytest-bdd': new Set(['.venv']),
|
|
42
|
+
};
|
package/dist/runner/bdd.js
CHANGED
|
@@ -34,20 +34,18 @@ export function runBddSuite(projectRoot, runner, mainPath) {
|
|
|
34
34
|
async function runCucumberRuby(projectRoot) {
|
|
35
35
|
const features = join(BEHAVIORAL_ROOT, 'features');
|
|
36
36
|
const steps = join(BEHAVIORAL_ROOT, 'step_definitions');
|
|
37
|
-
const localBin = join(projectRoot, 'bin', 'cucumber');
|
|
38
37
|
const sidecarGemfile = join(projectRoot, BEHAVIORAL_ROOT, 'Gemfile');
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
38
|
+
if (!existsSync(sidecarGemfile)) {
|
|
39
|
+
throw missingRunner('Cucumber');
|
|
40
|
+
}
|
|
41
|
+
const command = 'bundle';
|
|
42
|
+
const args = ['exec', 'cucumber', features, '--require', steps, '--format', 'message', '--out', CUCUMBER_REPORT];
|
|
43
43
|
const env = {
|
|
44
44
|
...process.env,
|
|
45
45
|
RAILS_ENV: 'test',
|
|
46
46
|
UNITBOB_REPO_ROOT: projectRoot,
|
|
47
47
|
};
|
|
48
|
-
|
|
49
|
-
env.BUNDLE_GEMFILE = join(BEHAVIORAL_ROOT, 'Gemfile');
|
|
50
|
-
}
|
|
48
|
+
env.BUNDLE_GEMFILE = join(BEHAVIORAL_ROOT, 'Gemfile');
|
|
51
49
|
const result = await runProcess(command, args, {
|
|
52
50
|
cwd: projectRoot,
|
|
53
51
|
timeoutMs: BDD_TIMEOUT_MS,
|
|
@@ -55,16 +53,20 @@ async function runCucumberRuby(projectRoot) {
|
|
|
55
53
|
});
|
|
56
54
|
return finalize(result, command, args, projectRoot, CUCUMBER_REPORT);
|
|
57
55
|
}
|
|
56
|
+
function missingRunner(name) {
|
|
57
|
+
return new Error(`Behavioral runner missing (${name}). Run suite-prepare to provision it under ${BEHAVIORAL_ROOT}/, then run the checks again.`);
|
|
58
|
+
}
|
|
58
59
|
// JS/TS: `@cucumber/cucumber` (cucumber-js) with the message formatter written
|
|
59
60
|
// to a file.
|
|
60
61
|
async function runCucumberJs(projectRoot) {
|
|
61
62
|
const features = join(BEHAVIORAL_ROOT, 'features');
|
|
62
63
|
const steps = join(BEHAVIORAL_ROOT, 'step_definitions', '**', '*');
|
|
63
64
|
const sidecarBin = join(projectRoot, BEHAVIORAL_ROOT, 'node_modules', '.bin', 'cucumber-js');
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
if (!executable(sidecarBin)) {
|
|
66
|
+
throw missingRunner('Cucumber JS');
|
|
67
|
+
}
|
|
68
|
+
const command = sidecarBin;
|
|
66
69
|
const args = [
|
|
67
|
-
...baseArgs,
|
|
68
70
|
features,
|
|
69
71
|
'--require',
|
|
70
72
|
steps,
|
|
@@ -122,11 +124,7 @@ async function pickPython(projectRoot) {
|
|
|
122
124
|
if (executable(sidecarVenvPytest)) {
|
|
123
125
|
return sidecarVenvPytest;
|
|
124
126
|
}
|
|
125
|
-
|
|
126
|
-
cwd: projectRoot,
|
|
127
|
-
timeoutMs: 10_000,
|
|
128
|
-
}).catch(() => ({ stdout: '', stderr: '', code: 1 }));
|
|
129
|
-
return probe.code === 0 ? 'python3' : 'python';
|
|
127
|
+
throw missingRunner('pytest-bdd');
|
|
130
128
|
}
|
|
131
129
|
function executable(path) {
|
|
132
130
|
try {
|
package/dist/verbs/run.js
CHANGED
|
@@ -18,7 +18,7 @@ export async function run(config, _args, deps) {
|
|
|
18
18
|
suite_file: { path: item.suite_file.path, content: item.suite_file.content },
|
|
19
19
|
runner_manifest: item.runner_manifest,
|
|
20
20
|
}),
|
|
21
|
-
materializeBehavioral: (projectRoot, item) => materializeBehavioral(projectRoot, item.suite_file).mainPath,
|
|
21
|
+
materializeBehavioral: (projectRoot, item) => materializeBehavioral(projectRoot, item.suite_file, item.runner_manifest.runner).mainPath,
|
|
22
22
|
runStructural: runStructuralByRunner,
|
|
23
23
|
runBehavioral: runBddSuite,
|
|
24
24
|
validateStack,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unitbob",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Unitbob connector — thin local hands for the Unitbob Rails brain. Owns no domain logic: it runs tools, relays bytes over the wire, and prints what the server returns.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|