syntaxai/tdd.md · main · src / c14_rust_graph_depth.test.ts
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
import {
computeRustGraphDepth,
parseCargoToml,
} from "./c14_rust_graph_depth.ts";
const FIXTURE = mkdtempSync(resolve(tmpdir(), "tdd-md-rust-graph-"));
const writeFile = (rel: string, content: string): void => {
const abs = resolve(FIXTURE, rel);
mkdirSync(abs.split("/").slice(0, -1).join("/"), { recursive: true });
writeFileSync(abs, content);
};
beforeAll(() => {
// Fixture: a workspace with a root crate + three member crates.
// Dependency chain: root → middle → leaf, with `core` standalone.
// root (top)
// └─→ middle (path)
// └─→ leaf (workspace = true)
// core (no internal deps)
writeFile(
"Cargo.toml",
`[package]
name = "rootcrate"
version = "0.1.0"
edition = "2021"
[workspace]
members = [
"crates/middle",
"crates/leaf",
"crates/core",
]
[workspace.dependencies]
leaf = { version = "0.1", path = "crates/leaf" }
[dependencies]
middle = { version = "0.1", path = "crates/middle" }
serde = "1.0"
`,
);
writeFile(
"crates/middle/Cargo.toml",
`[package]
name = "middle"
version = "0.1.0"
edition = "2021"
[dependencies]
leaf = { workspace = true }
anyhow = "1.0"
`,
);
writeFile(
"crates/leaf/Cargo.toml",
`[package]
name = "leaf"
version = "0.1.0"
edition = "2021"
[dependencies]
log = "0.4"
`,
);
writeFile(
"crates/core/Cargo.toml",
`[package]
name = "core"
version = "0.1.0"
edition = "2021"
[dependencies]
log = "0.4"
`,
);
});
afterAll(() => {
rmSync(FIXTURE, { recursive: true, force: true });
});
describe("parseCargoToml", () => {
test("extracts a simple [package] name", () => {
const doc = parseCargoToml(`[package]\nname = "myseg"\nversion = "0.1.0"\n`);
const pkg = doc.sections.get("package");
expect(pkg?.get("name")).toBe("myseg");
});
test("extracts a multi-line workspace.members array", () => {
const doc = parseCargoToml(`[workspace]
members = [
"crates/a",
"crates/b",
]
`);
const ws = doc.sections.get("workspace");
expect(ws?.get("members")).toEqual(["crates/a", "crates/b"]);
});
test("parses an inline-table dependency spec", () => {
const doc = parseCargoToml(`[dependencies]
mydep = { version = "0.1", path = "crates/mydep" }
`);
const deps = doc.sections.get("dependencies");
const spec = deps?.get("mydep") as Record<string, string>;
expect(spec.version).toBe("0.1");
expect(spec.path).toBe("crates/mydep");
});
test("parses workspace = true dep style", () => {
const doc = parseCargoToml(`[dependencies]
foo = { workspace = true }
`);
const deps = doc.sections.get("dependencies");
const spec = deps?.get("foo") as Record<string, string>;
expect(spec.workspace).toBe("true");
});
});
describe("computeRustGraphDepth — end-to-end on fixture", () => {
test("root → middle → leaf chain produces depth 3", () => {
const r = computeRustGraphDepth(FIXTURE);
expect(r.language).toBe("rust");
expect(r.workspaceName).toBe("rootcrate");
// 4 crates: rootcrate, middle, leaf, core.
expect(r.nodeCount).toBe(4);
// 2 internal edges: rootcrate → middle, middle → leaf.
// (core has no internal deps; serde/anyhow/log are external.)
expect(r.edgeCount).toBe(2);
expect(r.depth).toBe(3);
});
test("standalone core crate doesn't contribute to longest path", () => {
const r = computeRustGraphDepth(FIXTURE);
// core is included as a node (depth-1 leaf) but does not extend
// the longest chain. Longest is still rootcrate → middle → leaf.
expect(r.depth).toBe(3);
});
test("re-running on the same workspace produces identical numbers", () => {
const a = computeRustGraphDepth(FIXTURE);
const b = computeRustGraphDepth(FIXTURE);
expect(a).toEqual(b);
});
});
describe("computeRustGraphDepth — virtual workspace (no root [package])", () => {
const VW = mkdtempSync(resolve(tmpdir(), "tdd-md-rust-virtual-"));
const writeVW = (rel: string, content: string): void => {
const abs = resolve(VW, rel);
mkdirSync(abs.split("/").slice(0, -1).join("/"), { recursive: true });
writeFileSync(abs, content);
};
beforeAll(() => {
writeVW(
"Cargo.toml",
`[workspace]
members = ["crates/a", "crates/b"]
`,
);
writeVW(
"crates/a/Cargo.toml",
`[package]
name = "a"
version = "0.1.0"
edition = "2021"
[dependencies]
b = { path = "../b" }
`,
);
writeVW(
"crates/b/Cargo.toml",
`[package]
name = "b"
version = "0.1.0"
edition = "2021"
`,
);
});
afterAll(() => {
rmSync(VW, { recursive: true, force: true });
});
test("virtual workspace: 2 crates, 1 edge, depth 2", () => {
const r = computeRustGraphDepth(VW);
expect(r.nodeCount).toBe(2);
expect(r.edgeCount).toBe(1);
expect(r.depth).toBe(2);
});
});