test: classify filesystem application workflows as boundaries

This commit is contained in:
morluto
2026-10-12 04:53:10 +08:00
parent 918713af37
commit 804c287e44
11 changed files with 71 additions and 69 deletions
@@ -3,8 +3,8 @@ import { dirname, join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../tests/fixtures/temporaryDirectory.js";
import { systemDoctorHost } from "./Doctor.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { systemDoctorHost } from "../../../src/application/Doctor.js";
it("threads the selected host and environment into system diagnostics", async () => {
const environment = {
@@ -25,7 +25,9 @@ it("threads the selected host and environment into system diagnostics", async ()
calls.push({ command, arguments: arguments_, environment: options?.env });
if (command === "sw_vers") return { stdout: "15.0\n", stderr: "" };
if (command === "ldd") return { stdout: "linux-vdso.so.1", stderr: "" };
return { stdout: "/selected/bin/rea\n", stderr: "" };
if (command === "which")
return { stdout: "/selected/bin/rea\n", stderr: "" };
throw new Error(`Unexpected diagnostic command: ${command}`);
},
});
@@ -114,7 +116,7 @@ it("reports no Homebrew Hopper when the cask has no receipt", async () => {
});
expect(await host.brewHopperPath()).toBeUndefined();
expect(
calls.every((arguments_) => arguments_.join(" ") === "--caskroom"),
).toBe(true);
expect(new Set(calls.map((arguments_) => arguments_.join(" ")))).toEqual(
new Set(["--caskroom"]),
);
});
@@ -5,12 +5,12 @@ import { Ajv2020 } from "ajv/dist/2020.js";
import { expect, it } from "vitest";
import { z } from "zod";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { matchJavaScriptApplicationVersions } from "../../domain/javascript/javascriptApplicationVersionKeys.js";
import { findApplicationFeatureSeeds } from "../../domain/javascript/javascriptFeatureSeed.js";
import { traceApplicationFeatureInputSchema } from "../../domain/javascript/javascriptFeatureTraceSchemas.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { matchJavaScriptApplicationVersions } from "../../../../src/domain/javascript/javascriptApplicationVersionKeys.js";
import { findApplicationFeatureSeeds } from "../../../../src/domain/javascript/javascriptFeatureSeed.js";
import { traceApplicationFeatureInputSchema } from "../../../../src/domain/javascript/javascriptFeatureTraceSchemas.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
const analyzeSource = async (
source: string,
@@ -3,9 +3,9 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
it.each([
{
@@ -3,15 +3,15 @@ import { join } from "node:path";
import { describe, expect, it } from "vitest";
import { z } from "zod";
import { parseEvidence } from "../../domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { writeJavaScriptSourceSelectionFixture } from "../../../tests/fixtures/javascriptSourceSelection.js";
import { parseEvidence } from "../../../../src/domain/evidence.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { writeJavaScriptSourceSelectionFixture } from "../../../fixtures/javascriptSourceSelection.js";
import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
import { scanCanonicalArtifactInventory } from "../../../tests/fixtures/artifactInventory.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { projectAnalysisError } from "../../domain/analysisErrorProjection.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { ArtifactReaderFailure } from "../../../../src/artifacts/ArtifactReader.js";
import { scanCanonicalArtifactInventory } from "../../../fixtures/artifactInventory.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { projectAnalysisError } from "../../../../src/domain/analysisErrorProjection.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
describe("Selected JavaScript source failure diagnostics", () => {
it("analyzes selected files in first-request order and reports only selected progress", async () => {
@@ -33,10 +33,18 @@ describe("Selected JavaScript source failure diagnostics", () => {
},
},
);
expect(result.ok).toBe(true);
if (!result.ok) throw result.error;
const analysis = javascriptApplicationAnalysisResultSchema.parse(
result.value.normalized_result,
);
expect(analysis.source_selection).toEqual({
requested_paths: ["z-later.mjs", "main.mjs", "z-later.mjs"],
unselected_files: 5,
});
expect(analysis.statistics.parsed_javascript_files).toBe(2);
expect(progress).toEqual([
"Parsing and projecting z-later.mjs (1/2)",
"Parsing and projecting main.mjs (2/2)",
expect.stringContaining("z-later.mjs"),
expect.stringContaining("main.mjs"),
]);
});
@@ -3,11 +3,11 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { javaScriptSemanticQueryResultSchema } from "../../domain/javascript/javascriptSemanticQuerySchemas.js";
import { queryJavaScriptSemanticGraph } from "../../domain/javascript/javascriptSemanticQuery.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { javaScriptSemanticQueryResultSchema } from "../../../../src/domain/javascript/javascriptSemanticQuerySchemas.js";
import { queryJavaScriptSemanticGraph } from "../../../../src/domain/javascript/javascriptSemanticQuery.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
it.each([
{
@@ -3,9 +3,9 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
const graphIdentities = async (source: string) => {
const inputPath = await createTestTempDirectory("rea-js-template-literal-");
@@ -3,11 +3,11 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { canonicalJson } from "../../domain/comparisonSemantics.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { parseJavaScriptSource } from "../../domain/javascript/javascriptSourceParser.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { canonicalJson } from "../../../../src/domain/comparisonSemantics.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { parseJavaScriptSource } from "../../../../src/domain/javascript/javascriptSourceParser.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
type ApplicationAnalysis = ReturnType<
typeof javascriptApplicationAnalysisResultSchema.parse
@@ -5,10 +5,10 @@ import { fileURLToPath, pathToFileURL } from "node:url";
import { parseExpression } from "@babel/parser";
import { describe, expect, it } from "vitest";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { staticPath } from "../../domain/javascript/javascriptStaticAnalysisHelpers.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { staticPath } from "../../../../src/domain/javascript/javascriptStaticAnalysisHelpers.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
const urlCases = [
["./preload%20name.cjs", "preload name.cjs", "main.mjs"],
@@ -4,11 +4,11 @@ import { mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { promisify } from "node:util";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import type { JavaScriptArtifactFile } from "../../domain/javascript/javascriptArtifactFiles.js";
import { resolveArtifactPathByContext } from "./JavaScriptArtifactPathResolution.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import type { JavaScriptArtifactFile } from "../../../../src/domain/javascript/javascriptArtifactFiles.js";
import { resolveArtifactPathByContext } from "../../../../src/application/javascript/JavaScriptArtifactPathResolution.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
const filesFor = (paths: readonly string[]) =>
new Map<string, JavaScriptArtifactFile>(
@@ -3,9 +3,9 @@ import { join } from "node:path";
import { expect, it } from "vitest";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../tests/support/javascriptApplicationScope.js";
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
import { javascriptApplicationAnalysisResultSchema } from "../../../../src/domain/javascript/javascriptApplicationAnalysis.js";
import { analyzeJavaScriptApplication } from "../../../support/javascriptApplicationScope.js";
it("classifies overloaded open calls from lexical receiver facts", async () => {
const inputPath = await createTestTempDirectory(
@@ -1,24 +1,13 @@
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { describe, expect, it } from "vitest";
import {
captureProcessScenarioFile,
projectProcessCliError,
} from "./ProcessCli.js";
import { JSON_BYTE_ORDER_MARK_MESSAGE } from "../Utf8JsonInput.js";
} from "../../../src/application/process/ProcessCli.js";
import { JSON_BYTE_ORDER_MARK_MESSAGE } from "../../../src/application/Utf8JsonInput.js";
const roots: string[] = [];
afterEach(async () => {
await Promise.all(
roots.splice(0).map((root) => rm(root, { recursive: true, force: true })),
);
});
const fixture = async (): Promise<string> => {
const root = await mkdtemp(join(tmpdir(), "rea-process-cli-diagnostics-"));
roots.push(root);
return root;
};
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
describe("process CLI input diagnostics", () => {
it("preserves local diagnostics for unexpected process failures", () => {
@@ -35,7 +24,7 @@ describe("process CLI input diagnostics", () => {
});
it("projects missing, malformed JSON, and invalid scenario files", async () => {
const root = await fixture();
const root = await createTestTempDirectory("rea-process-cli-diagnostics-");
const malformed = join(root, "malformed.json");
const invalid = join(root, "invalid.json");
const invalidUtf8 = join(root, "invalid-utf8.json");
@@ -90,7 +79,10 @@ describe("process CLI input diagnostics", () => {
});
it("names a leading byte-order mark instead of quoting it as a token", async () => {
const path = join(await fixture(), "scenario.json");
const path = join(
await createTestTempDirectory("rea-process-cli-diagnostics-"),
"scenario.json",
);
await writeFile(path, '\uFEFF{"executable":"/bin/echo"}');
expect(await captureProcessScenarioFile(path)).toEqual({
error: "Process command failed",