Skip to content

Commit 3838996

Browse files
committed
Inline CLI smoke into per-package tests, move orchestration to scripts/
1 parent 280f921 commit 3838996

12 files changed

Lines changed: 64 additions & 97 deletions

File tree

AGENTS.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ grammars/ # Tree-sitter grammars (6 dirs: 4 LSP + 2 highlight-onl
6363
binary/ # @bgforge/binary package: library + fgbin CLI (Fallout PRO/MAP, Infinity Engine ITM/SPL/EFF parser)
6464
format/ # @bgforge/format package: library + fgfmt CLI (Fallout/WeiDU formatters)
6565
plugins/ # TypeScript Language Service Plugins: tssl-plugin/, td-plugin/
66-
test/ # Cross-package tests: smoke + orchestration config for CLI integration tests
6766
editors/ # Editor-specific syntax definitions (generated by build-editors.sh)
6867
syntaxes/ # TextMate grammars (YAML source + JSON compiled)
6968
themes/ # Color themes (bgforge-monokai) + icon theme

binary/test/bin-cli.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ describe("bin CLI integration", () => {
6262
fs.rmSync(tmpDir, { recursive: true, force: true });
6363
});
6464

65+
describe("smoke", () => {
66+
// Subprocess execution doesn't propagate v8 coverage, so the published
67+
// CLI entry point cannot be gated by a coverage threshold. The smoke
68+
// checks substitute by asserting the bundle starts, parses flags, and
69+
// exits cleanly before any feature test runs.
70+
it("exits 0 with --help", () => {
71+
const { code } = run("--help");
72+
expect(code).toBe(0);
73+
});
74+
75+
it("prints a usage banner to stdout with --help", () => {
76+
const { stdout } = run("--help");
77+
expect(stdout).toContain("Usage: fgbin");
78+
});
79+
});
80+
6581
describe("stdout mode", () => {
6682
it("outputs parsed JSON to stdout", () => {
6783
const proFile = path.join(FIXTURES, "misc", "00000001.pro");

binary/vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default defineConfig({
1313
// package directory (pnpm test) and from the repo root (scripts/test.sh).
1414
include: [path.resolve(__dirname, "test/**/*.test.ts")],
1515
// CLI integration tests live alongside the unit tests but require the built
16-
// CLI bundle to exist; they run from test/vitest.cli.config.ts in a later phase.
16+
// CLI bundle to exist; they run from scripts/vitest.cli.config.ts in a later phase.
1717
exclude: [path.resolve(__dirname, "test/**/*-cli.test.ts")],
1818
// v8 coverage instrumentation slows the binary parser tests; the 5s
1919
// vitest default is too tight for them.

format/test/format-cli.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,24 @@ describe("format CLI integration", () => {
4040
fs.rmSync(tmpDir, { recursive: true, force: true });
4141
});
4242

43+
describe("smoke", () => {
44+
// Each release CLI ships as its own published artefact but cannot carry
45+
// a numeric v8 coverage gate - subprocess instrumentation via
46+
// child_process does not capture in-process coverage. The smoke checks
47+
// substitute by asserting the bundle starts, parses flags, and exits
48+
// cleanly. A broken shebang, missing bundle, or startup crash fails here
49+
// before any feature test runs.
50+
it("exits 0 with --help", () => {
51+
const { code } = run("--help");
52+
expect(code).toBe(0);
53+
});
54+
55+
it("prints a usage banner to stdout with --help", () => {
56+
const { stdout } = run("--help");
57+
expect(stdout).toContain("Usage: format-cli");
58+
});
59+
});
60+
4361
describe("stdout mode", () => {
4462
it("outputs formatted content to stdout", () => {
4563
// Valid BAF with wrong indentation (content is preserved, only whitespace changes)

format/vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default defineConfig({
1313
// package directory (pnpm test) and from the repo root (scripts/test.sh).
1414
include: [path.resolve(__dirname, "test/**/*.test.ts")],
1515
// CLI integration tests live alongside the unit tests but require the built
16-
// CLI bundle to exist; they run from test/vitest.cli.config.ts in a later phase.
16+
// CLI bundle to exist; they run from scripts/vitest.cli.config.ts in a later phase.
1717
exclude: [path.resolve(__dirname, "test/**/*-cli.test.ts")],
1818
testTimeout: 30000,
1919
coverage: {

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@
5757
"test:transpile-external": "./scripts/test-transpile-external.sh",
5858
"test:grammar": "./scripts/test-grammar.sh",
5959
"regenerate-expected": "./scripts/regenerate-expected.sh",
60-
"test:cli": "vitest run --config test/vitest.cli.config.ts",
61-
"test:cli:external": "RUN_EXTERNAL_CLI_TESTS=1 vitest run --config test/vitest.cli.config.ts",
60+
"test:cli": "vitest run --config scripts/vitest.cli.config.ts",
61+
"test:cli:external": "RUN_EXTERNAL_CLI_TESTS=1 vitest run --config scripts/vitest.cli.config.ts",
6262
"test:server:smoke": "cd server && pnpm exec vitest run test/smoke-stdio.test.ts",
6363
"test:e2e": "./scripts/test-e2e.sh",
6464
"test:coverage": "cd server && vitest run --coverage",

scripts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pnpm test:cli # Exit codes and diff output
8383
| `publish-server.sh` | Publish `@bgforge/mls-server` to npm. |
8484
| `publish-transpile.sh` | Publish `@bgforge/transpile` (library + fgtp bin) to npm. |
8585
| `vitest.config.ts` | Vitest configuration for script-level tests. |
86+
| `vitest.cli.config.ts` | Vitest configuration that re-includes the `*-cli.test.ts` files excluded by each package's unit-test config, so they run as a single phase after the CLI bundles are built. Invoked by `pnpm test:cli`. |
8687
| `vitest.smoke.config.ts` _(server/)_ | Vitest configuration for the server smoke test (separate because it requires a built bundle). |
8788
| `generate-data.sh` | Generate YAML data files from game engine sources. |
8889
| `regenerate-expected.sh` | Regenerate tree-sitter grammar sources and types. |
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
/**
22
* Vitest configuration for cross-package CLI integration tests.
33
*
4-
* These tests spawn each release CLI bundle as a child process to verify exit
5-
* codes, stdout output, and stderr diff reporting. They live next to their
6-
* owning packages but share an orchestration entry point so the suite can be
7-
* gated as a single phase that runs after the CLIs are built.
4+
* Each per-package vitest config (binary, format, transpilers) excludes its
5+
* own `*-cli.test.ts` from the unit-test phase because those tests spawn the
6+
* built CLI bundle as a child process and would fail before Phase 2 produces
7+
* the bundles. This config re-includes them so the suite can be gated as a
8+
* single phase that runs after the CLIs are built.
89
*
910
* No coverage thresholds: subprocess instrumentation via child_process does
10-
* not capture v8 in-process coverage. These tests substitute behavioural
11-
* verification for a numeric coverage gate.
11+
* not capture v8 in-process coverage. Per-package smoke `describe` blocks
12+
* substitute behavioural verification for a numeric coverage gate.
1213
*/
1314

1415
import { defineConfig } from "vitest/config";
@@ -23,7 +24,6 @@ export default defineConfig({
2324
path.resolve(root, "binary/test/bin-cli.test.ts"),
2425
path.resolve(root, "format/test/format-cli.test.ts"),
2526
path.resolve(root, "transpilers/test/transpile-cli.test.ts"),
26-
path.resolve(root, "test/smoke.test.ts"),
2727
],
2828
testTimeout: 30000,
2929
},

test/smoke.test.ts

Lines changed: 0 additions & 83 deletions
This file was deleted.

transpilers/test/transpile-cli.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ describe("transpile CLI integration", () => {
4343
fs.rmSync(tmpDir, { recursive: true, force: true });
4444
});
4545

46+
describe("smoke", () => {
47+
// Subprocess execution doesn't propagate v8 coverage, so the published
48+
// CLI entry point cannot be gated by a coverage threshold. The smoke
49+
// checks substitute by asserting the bundle starts, parses flags, and
50+
// exits cleanly before any feature test runs.
51+
it("exits 0 with --help", () => {
52+
const { code } = run("--help");
53+
expect(code).toBe(0);
54+
});
55+
56+
it("prints a usage banner to stdout with --help", () => {
57+
const { stdout } = run("--help");
58+
expect(stdout).toContain("Usage: fgtp");
59+
});
60+
});
61+
4662
describe("stdout mode", () => {
4763
it("outputs transpiled D content to stdout", () => {
4864
const sample = path.join(SAMPLES_DIR, "botsmith.td");

0 commit comments

Comments
 (0)