testPackagesDependThroughReleases
packages depend on each other through their releases
import { codebase } from "#codebase/tcmts/cli/test/e2e/releases"; import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; export const testPackagesDependThroughReleases = () => { const a = codebase("two"); a.save(`// tcm: namespace geo\nexport const manifest = { name: "geo" };\nexport interface Point { x: number; y: number }\nexport const distance = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y);\n`, "add"); a.save(`// tcm: namespace atlas\nimport { distance, type Point } from "#codebase/geo";\nexport const manifest = { name: "atlas", bin: { atlas: "main" } };\nexport const length = (ps: Point[]): number => ps.slice(1).reduce((n, p, i) => n + distance(ps[i]!, p), 0);\nexport const main = (): number => (console.log(length([{ x: 0, y: 0 }, { x: 3, y: 4 }])), 0);\n`, "add"); assert.match(a.run("release").out, /which package\? atlas, geo/); assert.match(a.run("pack", "atlas").out, /this uses geo\.Point, geo\.distance from geo, which geo hasn't released yet: release geo first/); a.tcm("release", "geo"); a.tcm("release", "atlas"); // atlas imports what it uses of geo from geo's release, rather than carrying a copy assert.match(a.tcm("pack", "atlas@0.1.0"), /packed atlas@0\.1\.0 into \.tcm\/pack\/atlas: 2 module\(s\), depends on geo/); const dir = path.join(a.dir, ".tcm", "pack", "atlas"); assert.deepEqual(JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")).dependencies, { geo: "^0.1.0" }); const modules = fs.readdirSync(path.join(dir, "modules")).map((f) => fs.readFileSync(path.join(dir, "modules", f), "utf8")).join("\n"); assert.match(modules, /import \{ distance as distance \} from "geo";/); assert.match(modules, /import type \{ Point as Point \} from "geo";/); assert.doesNotMatch(modules, /Math\.hypot/, "geo's code isn't copied in"); // a change to geo is geo's: atlas's code didn't change, only what it uses a.save(`// tcm: namespace geo\nimport type { Point } from "#codebase/geo";\nexport const distance = (a: Point, b: Point, digits?: number): number => Number(Math.hypot(a.x - b.x, a.y - b.y).toFixed(digits ?? 10));\n`); assert.match(a.tcm("release", "check", "geo"), /geo's next release: 0\.1\.1 .*: additions/); assert.match(a.tcm("release", "check", "atlas"), /atlas's next release: 0\.1\.1 .*: no API changes[\s\S]*follow those changes \(atlas\.length/); assert.match(a.run("pack", "atlas").out, /geo@0\.1\.0 doesn't export as it is here: release geo first/); a.tcm("release", "geo"); a.tcm("pack", "atlas"); assert.deepEqual(JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")).dependencies, { geo: "^0.1.1" }); assert.match(a.tcm("releases"), /^atlas {2}atlas\n {2}0\.1\.0 [\s\S]*geo {2}geo\n {2}0\.1\.1 [\s\S]* {2}0\.1\.0 /m); }