dimensionlab-website/apps/web/src/lib/workspace-boundary.test.ts

148 lines
5.5 KiB
TypeScript

import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, test } from "vitest";
const root = existsSync(join(process.cwd(), "turbo.json"))
? process.cwd()
: join(process.cwd(), "..", "..");
describe("workspace boundaries", () => {
test("declares the root as a turbo-managed bun workspace", () => {
const packageJson = JSON.parse(
readFileSync(join(root, "package.json"), "utf8"),
) as {
private?: boolean;
scripts?: Record<string, string>;
workspaces?: string[];
};
expect(packageJson.private).toBe(true);
expect(packageJson.workspaces).toEqual(["apps/*", "packages/*"]);
expect(packageJson.scripts?.build).toBe("turbo run build");
expect(existsSync(join(root, "turbo.json"))).toBe(true);
});
test("keeps release orchestration in the root turbo task graph", () => {
const rootPackage = JSON.parse(
readFileSync(join(root, "package.json"), "utf8"),
) as {
scripts?: Record<string, string>;
};
const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"),
) as { scripts?: Record<string, string> };
const turboConfig = JSON.parse(
readFileSync(join(root, "turbo.json"), "utf8"),
) as {
globalDependencies?: string[];
tasks?: Record<string, { env?: string[] }>;
};
expect(rootPackage.scripts?.["test:qa"]).toBe(
"turbo run check test:unit build @dimensionlab/ui#build-storybook @dimensionlab/web#test:e2e",
);
expect(webPackage.scripts).not.toHaveProperty("test:qa");
expect(turboConfig.tasks).not.toHaveProperty("test:qa");
expect(turboConfig.globalDependencies).toEqual(
expect.arrayContaining(["bun.lock", "tsconfig.base.json"]),
);
expect(turboConfig.tasks?.["test:e2e"]?.env).toEqual(
expect.arrayContaining([
"CI",
"PLAYWRIGHT_DATABASE_URL",
"PLAYWRIGHT_PORT",
"PLAYWRIGHT_STORYBOOK_PORT",
]),
);
});
test("lets turbo build app and Storybook artifacts before e2e serves them", () => {
const playwrightConfig = readFileSync(
join(root, "apps/web/playwright.config.ts"),
"utf8",
);
const turboConfig = JSON.parse(
readFileSync(join(root, "turbo.json"), "utf8"),
) as {
tasks?: Record<string, { dependsOn?: string[] }>;
};
expect(playwrightConfig).not.toContain("bun run build &&");
expect(playwrightConfig).not.toContain("bun run build-storybook");
expect(turboConfig.tasks?.["test:e2e"]?.dependsOn).toEqual(
expect.arrayContaining(["@dimensionlab/ui#build-storybook"]),
);
});
test("keeps the website app and reusable UI library as separate packages", () => {
const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"),
) as { dependencies?: Record<string, string>; name?: string };
const uiPackage = JSON.parse(
readFileSync(join(root, "packages/ui/package.json"), "utf8"),
) as { exports?: Record<string, unknown>; name?: string };
expect(webPackage.name).toBe("@dimensionlab/web");
expect(webPackage.dependencies?.["@dimensionlab/ui"]).toBe("workspace:*");
expect(uiPackage.name).toBe("@dimensionlab/ui");
expect(uiPackage.exports).toHaveProperty(".");
expect(uiPackage.exports).toHaveProperty("./styles.css");
});
test("keeps the dashboard model in a reusable internal package", () => {
const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"),
) as { dependencies?: Record<string, string> };
const modelPackage = JSON.parse(
readFileSync(join(root, "packages/dashboard-model/package.json"), "utf8"),
) as { exports?: Record<string, unknown>; name?: string };
const tsconfig = JSON.parse(
readFileSync(join(root, "tsconfig.json"), "utf8"),
) as { references?: Array<{ path: string }> };
expect(webPackage.dependencies?.["@dimensionlab/dashboard-model"]).toBe(
"workspace:*",
);
expect(modelPackage.name).toBe("@dimensionlab/dashboard-model");
expect(modelPackage.exports).toHaveProperty(".");
expect(modelPackage.exports).toHaveProperty("./fixtures");
expect(tsconfig.references).toEqual(
expect.arrayContaining([{ path: "./packages/dashboard-model" }]),
);
expect(existsSync(join(root, "apps/web/src/lib/model/index.ts"))).toBe(
false,
);
});
test("stages web workspace dependency manifests before container install", () => {
const webPackage = JSON.parse(
readFileSync(join(root, "apps/web/package.json"), "utf8"),
) as { dependencies?: Record<string, string> };
const workspacePackages = [
"packages/ui/package.json",
"packages/dashboard-model/package.json",
].map((manifestPath) => {
const packageJson = JSON.parse(
readFileSync(join(root, manifestPath), "utf8"),
) as { name?: string };
return [packageJson.name, manifestPath] as const;
});
const manifestsByPackageName = new Map(workspacePackages);
const containerfile = readFileSync(
join(root, "apps/web/Containerfile"),
"utf8",
);
const workspaceDependencyManifests = Object.entries(
webPackage.dependencies ?? {},
)
.filter(([, version]) => version.startsWith("workspace:"))
.map(([packageName]) => manifestsByPackageName.get(packageName));
expect(workspaceDependencyManifests).not.toContain(undefined);
for (const manifestPath of workspaceDependencyManifests) {
expect(containerfile).toContain(`COPY ${manifestPath} ${manifestPath}`);
}
});
});