test.build/core/converters/source.converter.test.ts
test.build/core/converters/source.converter.test.ts is a file in Codebase Testing. 185 lines of code and 0 definitions.
import type { AnatomyFile, AnatomyFolder, AnatomySnapshot } from "@banes-lab/web/types/anatomy.types.js";
import {
canonicalOf,
sourceFiles,
sourceLeaves,
summaryOf,
} from "@banes-lab/build-scripts/core/converters/source.converter.ts";
import { describe, expect, it } from "vitest";
import type { SourceTools } from "@banes-lab/build-scripts/types/source.types.ts";
import { createLinker } from "@banes-lab/build-scripts/core/resolvers/link.resolver.ts";
import { placementsOf } from "@banes-lab/build-scripts/core/converters/location.converter.ts";
import { sourceIndexPlans } from "@banes-lab/build-scripts/core/converters/index.source.converter.ts";
const SITE = "https://example.test";
const STATS = {
bytes: 10,
callable: 1,
definitions: 1,
edges: 0,
exported: 1,
files: 1,
findings: {},
flows: {},
lines: { blank: 0, code: 3, total: 3 },
};
const SLUG_SAFE = "abcdefghijklmnopqrstuvwxyz0123456789";
const slug = function slug(path: string): string {
let out = "";
for (let at = 0; at < path.length; at += 1) {
const char = path.charAt(at);
out += SLUG_SAFE.includes(char) ? char : "-";
}
return out;
};
const lineSuffix = function lineSuffix(line: number | null): string {
return line === null ? "" : `:${String(line)}`;
};
const TOOLS: SourceTools = {
definitionAnchor: "definition-",
fileId: (path) => `file-${slug(path)}`,
languageOf: () => "typescript",
lineInfix: ":",
localPath: (path) => path.slice(path.indexOf("~") + 1),
nodeHref: (path, line) => `/anatomy/build#file-${slug(path)}${lineSuffix(line)}`,
};
const file = function file(path: string, calls: readonly string[]): AnatomyFile {
return {
definitions: [
{
callable: true,
callees: calls.map((target) => ({ file: target, id: `${target}#x`, name: "x" })),
callers: [],
exported: true,
file: path,
flow: "entry",
id: `${path}#run`,
inDegree: 0,
kind: "function",
line: 1,
local: false,
name: "run",
outDegree: calls.length,
},
],
distribution: { invariants: [], variants: [] },
document: null,
findings: [],
generated: false,
id: path,
inherited: false,
layer: "processing",
name: path.slice(path.lastIndexOf("/") + 1),
path,
slots: null,
source: "source.a.generated.txt",
stats: STATS,
walk: null,
};
};
const folder = function folder(files: readonly AnatomyFile[]): AnatomyFolder {
return {
files,
findings: [],
folders: [],
id: "root",
layer: null,
name: "",
path: "",
role: "member",
stats: STATS,
walk: null,
};
};
const snapshot = function snapshot(files: readonly AnatomyFile[]): AnatomySnapshot {
const metrics = {
callable: 0,
definitions: 0,
edges: 0,
exported: 0,
findings: {},
flows: {},
maxInDegree: 0,
maxOutDegree: 0,
resolutionRate: 1,
unresolvedCalls: 0,
};
return { charts: [], findings: [], imports: [], metrics, states: [], tree: folder(files), unresolvedCalls: [] };
};
const TREE = {
label: "Build",
snapshot: snapshot([file("build~core/a.ts", ["build~core/b.ts"]), file("build~core/b.ts", [])]),
tab: "build",
};
describe("summaryOf", () => {
it("counts a file's lines of code and definitions, with the plural only past one", () => {
expect(summaryOf({ definitions: [], stats: STATS })).toBe("3 lines of code and 0 definitions.");
expect(summaryOf(file("a.ts", []))).toBe("3 lines of code and 1 definition.");
});
});
describe("canonicalOf", () => {
it("drops a line from a file anchor and maps a definition anchor to its file", () => {
const canonical = canonicalOf(SITE, TOOLS);
expect(canonical(`${SITE}/anatomy/build#file-x:12`)).toBe("/anatomy/build#file-x");
expect(canonical("/anatomy/build#definition-run:build~core/a.ts")).toBe("/anatomy/build#file-build-core-a-ts");
expect(canonical("/pag/guide#setup")).toBe("/pag/guide#setup");
});
});
describe("sourceFiles and sourceLeaves", () => {
it("addresses every file by its member-relative path and links the files it uses and is used by", async () => {
const files = sourceFiles([TREE], TOOLS);
expect(files.map((entry) => entry.identity.address.json)).toStrictEqual([
"/json/source/build/core/a.ts",
"/json/source/build/core/b.ts",
]);
const linker = createLinker(
files.map((entry) => entry.identity),
SITE,
canonicalOf(SITE, TOOLS),
);
const placements = placementsOf(
sourceIndexPlans(files, TOOLS.localPath).trees,
files.map((entry) => entry.identity),
SITE,
);
const leaves = await sourceLeaves(files, {
checks: () => [],
folder: (ref) =>
ref === files[0]?.identity.ref
? { containedIn: linker.link("root", files[1]?.identity.ref ?? ""), contains: [] }
: null,
grounds: async () => {
await Promise.resolve();
return [];
},
linkedBy: (ref) =>
ref === files[0]?.identity.ref ? [linker.link("core/b.ts", files[1]?.identity.ref ?? "")] : [],
linker,
placement: (ref) => placements.get(ref) ?? null,
textOf: () => "export const run = 1;",
tools: TOOLS,
});
expect(leaves[0]?.data).toMatchObject({
definitions: [{ name: "run", signature: "export const run = 1;" }],
path: "core/a.ts",
relations: [
{ links: [{ label: "root" }], relation: "contained-in" },
{ links: [{ label: "core/b.ts", markdown: `${SITE}/source/build/core/b.ts.md` }], relation: "uses" },
{ links: [{ label: "core/b.ts" }], relation: "linked-from" },
],
siblings: { next: { label: "core/b.ts" }, previous: null },
text: `${SITE}/source/build/core/a.ts.txt`,
tree: "build",
up: { json: `${SITE}/json/api/source/build`, ref: "api:source/build" },
});
expect(leaves[0]?.markdown).toContain("## Uses");
expect(leaves[1]?.data).toMatchObject({ siblings: { next: null, previous: { label: "core/a.ts" } } });
expect(JSON.stringify(leaves[1]?.data)).not.toContain("contained-in");
expect(leaves[0]?.text).toStrictEqual({
address: "/source/build/core/a.ts.txt",
body: "export const run = 1;",
});
expect(leaves[0]?.markdown).toContain(`Source text: ${SITE}/source/build/core/a.ts.txt`);
expect(leaves[0]?.markdown).toContain("```typescript\nexport const run = 1;\n```");
expect(JSON.stringify(leaves.map((leaf) => leaf.data))).not.toContain("build~");
});
});