fix(analysis): preserve artifact and selection error ownership

This commit is contained in:
morluto committed 2026-10-24 22:54:05 +08:00
1 parent 69f99c5198
commit 4f212c6a30
11 files changed
+527 -25

No files matched your search

@@ -160,6 +160,81 @@ describe("selected module trace workflow", () => {
});
});
describe("reported module context provenance", () => {
it.each(["", "not a URL", "https://user:password@app.test/main.js"])(
"retains unusable reported context as a capability limitation: %s",
async (reportedUrl) => {
const artifacts = webModuleArtifactsFixture();
const script = artifacts.manifest.scripts[0];
if (script === undefined) throw new Error("fixture script missing");
script.url = reportedUrl;
const service = new WebModuleTraceService(
{ load: () => Promise.resolve(ok(artifacts)) },
{
resolve: () => {
throw new Error("must not resolve without a usable context");
},
},
);
const response = await service.trace(args);
if (response.ok) throw new Error("expected unavailable context");
expect(projectAnalysisError(response.error)).toMatchObject({
code: "capability_unavailable",
message: expect.stringContaining("Select importer_url explicitly"),
details: { reason: "reported_source_context_unavailable" },
});
expect(projectAnalysisError(response.error).details).not.toHaveProperty(
"issues",
);
},
);
it("keeps an unsupported reported scheme distinct from malformed context", async () => {
const artifacts = webModuleArtifactsFixture();
const script = artifacts.manifest.scripts[0];
if (script === undefined) throw new Error("fixture script missing");
script.url = "file:///captured/main.js";
const response = await new WebModuleTraceService(
{ load: async () => ok(artifacts) },
webModuleResolverFixture,
).trace(args);
if (response.ok) throw new Error("expected unsupported context");
expect(projectAnalysisError(response.error)).toMatchObject({
code: "capability_unavailable",
message: expect.stringContaining("reported source URL"),
details: { reason: "unsupported_context_scheme" },
});
});
it("honors an explicit context while retaining the unusable reported source URL", async () => {
const artifacts = webModuleArtifactsFixture();
const script = artifacts.manifest.scripts[0];
if (script === undefined) throw new Error("fixture script missing");
script.url = "not a URL";
const result = await new WebModuleTraceService(
{ load: async () => ok(artifacts) },
webModuleResolverFixture,
).trace({ ...args, importer_url: "https://selected.test/base/main.js" });
if (!result.ok) throw result.error;
expect(result.value).toMatchObject({
parameters: { importer_url: "https://selected.test/base/main.js" },
normalized_result: {
source: { script: { url: "not a URL" } },
importer: {
url: "https://selected.test/base/main.js",
basis: "caller-selected",
},
imports: expect.arrayContaining([
expect.objectContaining({
resolution: {
state: "resolved",
url: "https://selected.test/base/dep.js",
},
}),
]),
},
});
});
});
it.each([null, { request: "opaque cancellation" }])(
"retains completed module Evidence and the exact late abort reason: %j",
async (reason) => {