import { describe, test, expect } from "vitest"; import { buildFixtureGraph } from "./__fixtures__/build-graph"; import { resolveCarveSet, boundaryReport } from "./carve"; import type { Hcl2JsonTree } from "./types"; // #197 worked example: a bucket a Lambda reads, with a versioning sub-resource. const workedExample: Hcl2JsonTree = { resource: { aws_s3_bucket: { assets: [{ bucket: "myapp-assets-prod" }] }, aws_s3_bucket_versioning: { assets: [{ bucket: "${aws_s3_bucket.assets.id}", versioning_configuration: { status: "Enabled" } }], }, aws_lambda_function: { api: [ { environment: { variables: { ASSETS_BUCKET: "${aws_s3_bucket.assets.bucket}", ASSETS_ARN: "${aws_s3_bucket.assets.arn}", }, }, }, ], }, }, }; describe("resolveCarveSet", () => { test("selected node plus its folded sub-resources", () => { const set = resolveCarveSet(buildFixtureGraph(workedExample), "aws_s3_bucket.assets"); expect(set.map((m) => m.address).sort()).toEqual([ "aws_s3_bucket.assets", "aws_s3_bucket_versioning.assets", ]); const folded = set.find((m) => m.address === "aws_s3_bucket_versioning.assets"); expect(folded?.foldedInto).toBe("aws_s3_bucket.assets"); }); test("empty for an unknown address", () => { expect(resolveCarveSet(buildFixtureGraph(workedExample), "aws_s3_bucket.nope")).toEqual([]); }); }); describe("boundaryReport", () => { test("classifies the Lambda inbound edge; folds the versioning internal edge away", () => { const report = boundaryReport(buildFixtureGraph(workedExample), "aws_s3_bucket.assets")!; expect(report.target).toBe("aws_s3_bucket.assets"); expect(report.peelability).toBe(88); expect(report.reversible).toBe(true); // The only boundary edge is the Lambda → bucket inbound; the versioning → // bucket edge is internal to the carve set and dropped. expect(report.inbound).toEqual([ { direction: "inbound", survivor: "aws_lambda_function.api", carved: "aws_s3_bucket.assets", attrs: ["arn", "bucket"], via: ["environment"], bridge: "tf-data-source", required: "immediately", }, ]); expect(report.outbound).toEqual([]); }); test("outbound edges become deferred inputs", () => { const tree: Hcl2JsonTree = { resource: { aws_sns_topic: { alerts: [{ name: "a" }] }, aws_sqs_queue: { dlq: [{ name: "d", redrive: "${aws_sns_topic.alerts.arn}" }] }, }, }; // Carve the queue: it depends on the topic (a survivor) → outbound/deferred. const report = boundaryReport(buildFixtureGraph(tree), "aws_sqs_queue.dlq")!; expect(report.inbound).toEqual([]); expect(report.outbound).toEqual([ { direction: "outbound", survivor: "aws_sns_topic.alerts", carved: "aws_sqs_queue.dlq", attrs: ["arn"], via: ["redrive"], bridge: "deferred-input", required: "at-apply", }, ]); }); test("an output block is an inbound edge with its own bridge kind (#1638)", () => { const tree: Hcl2JsonTree = { resource: { aws_s3_bucket: { assets: [{ bucket: "b" }] } }, output: { assets_bucket: [{ value: "${aws_s3_bucket.assets.bucket}" }] }, }; const report = boundaryReport(buildFixtureGraph(tree), "aws_s3_bucket.assets")!; expect(report.inbound).toEqual([ { direction: "inbound", survivor: "output.assets_bucket", carved: "aws_s3_bucket.assets", attrs: ["bucket"], via: ["value"], bridge: "tf-output-rewrite", required: "immediately", }, ]); expect(report.peelability).toBe(96); // the cheaper output weight, not 88 }); test("an output on a folded sub-resource is still the parent's boundary work", () => { const tree: Hcl2JsonTree = { resource: { aws_s3_bucket: { assets: [{ bucket: "b" }] }, aws_s3_bucket_versioning: { assets: [{ bucket: "${aws_s3_bucket.assets.id}" }] }, }, output: { versioning_id: [{ value: "${aws_s3_bucket_versioning.assets.id}" }] }, }; const report = boundaryReport(buildFixtureGraph(tree), "aws_s3_bucket.assets")!; expect(report.inbound.map((e) => [e.survivor, e.carved, e.bridge])).toEqual([ ["output.versioning_id", "aws_s3_bucket_versioning.assets", "tf-output-rewrite"], ]); }); test("unsupported type is flagged in diagnostics", () => { const tree: Hcl2JsonTree = { resource: { random_pet: { n: [{ length: 2 }] } } }; const report = boundaryReport(buildFixtureGraph(tree), "random_pet.n")!; expect(report.diagnostics.join(" ")).toMatch(/no known native mapping/i); }); test("null for an unknown target", () => { expect(boundaryReport(buildFixtureGraph(workedExample), "aws_s3_bucket.nope")).toBeNull(); }); });