|
42 | 42 |
|
43 | 43 | import { afterAll, beforeAll, describe, expect, it } from 'vitest'; |
44 | 44 | import { execFile } from 'node:child_process'; |
45 | | -import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; |
| 45 | +import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; |
46 | 46 | import { tmpdir } from 'node:os'; |
47 | 47 | import { join, resolve } from 'node:path'; |
48 | 48 | import { fileURLToPath } from 'node:url'; |
49 | 49 | import { childEnv } from './helpers/serve-process.js'; |
50 | 50 | import { linkSpec } from './helpers/define-stack-fixture.js'; |
| 51 | +import { consoleSduiManifestPath } from '../src/utils/sdui-manifest.js'; |
51 | 52 |
|
52 | 53 | const HERE = resolve(fileURLToPath(import.meta.url), '..'); |
53 | 54 | const CLI = resolve(HERE, '../bin/run-dev.js'); |
54 | 55 | const TSX = resolve(HERE, '../../../node_modules/.bin/tsx'); |
55 | 56 |
|
| 57 | +/** |
| 58 | + * Whether the manifest-less path is reachable in THIS checkout (#19922). With |
| 59 | + * no project manifest the CLI falls back to the copy its own |
| 60 | + * `@objectstack/console` dependency ships, located from the same module the |
| 61 | + * spawned CLI runs (`src/`, through `bin/run-dev.js`). In the workspace that is |
| 62 | + * `packages/console/dist/sdui.manifest.json`, which exists only where the |
| 63 | + * console has been built — never in the CI job that runs this file, often on a |
| 64 | + * developer's machine. Where it exists, a project without a manifest is fully |
| 65 | + * validated against it and the notice has nothing to report, so the cases that |
| 66 | + * need "no manifest anywhere" are SKIPPED, by name, rather than asserting a |
| 67 | + * state this checkout cannot produce. Every rule they pin is also pinned, |
| 68 | + * hermetically, in `src/utils/sdui-manifest.test.ts`. |
| 69 | + */ |
| 70 | +const CONSOLE_COPY = consoleSduiManifestPath(); |
| 71 | +const NO_MANIFEST_UNREACHABLE = CONSOLE_COPY !== undefined && existsSync(CONSOLE_COPY); |
| 72 | + |
56 | 73 | /** `JSX_PARSE_LEVEL_ONLY_RULE` in `src/utils/sdui-manifest.ts`, spelled out as the published anchor. */ |
57 | 74 | const RULE = 'sdui/jsx-parse-level-only'; |
58 | 75 |
|
@@ -259,7 +276,7 @@ afterAll(() => { |
259 | 276 | if (root) rmSync(root, { recursive: true, force: true }); |
260 | 277 | }); |
261 | 278 |
|
262 | | -describe('no manifest, kind:html pages — the notice, exit status unchanged', () => { |
| 279 | +describe.skipIf(NO_MANIFEST_UNREACHABLE)('no manifest, kind:html pages — the notice, exit status unchanged', () => { |
263 | 280 | it.each([ |
264 | 281 | ['validate', '--strict'], |
265 | 282 | ['build'], |
@@ -364,7 +381,7 @@ describe('[round 1] html pages carried only in packages[], beside a top-level pa |
364 | 381 | COMMANDS.map((command) => [layout, command, notice, malformed] as const), |
365 | 382 | ); |
366 | 383 |
|
367 | | - it.each(rows)('%s — os %s: the notice, counting the package page, exit 0', (_layout, command, notice) => { |
| 384 | + it.skipIf(NO_MANIFEST_UNREACHABLE).each(rows)('%s — os %s: the notice, counting the package page, exit 0', (_layout, command, notice) => { |
368 | 385 | const r = run(notice, command, '--json'); |
369 | 386 | expect(r.code, r.stdout + r.stderr).toBe(0); |
370 | 387 | const notices = noticesIn(payloadOf(r, `${notice} ${command}`)); |
|
0 commit comments