# test.rules/shared/analyzers/liveness.analyzer.test.ts

> 51 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-rules-shared-analyzers-liveness-analyzer-test-ts
Source text: https://banes-lab.com/source/testing/test.rules/shared/analyzers/liveness.analyzer.test.ts.txt

Listed in [test.rules/shared/analyzers](https://banes-lab.com/api/source/testing/test.rules/shared/analyzers.md), after [test.rules/shared/analyzers/generator.analyzer.test.ts](https://banes-lab.com/source/testing/test.rules/shared/analyzers/generator.analyzer.test.ts.md) and before [test.rules/shared/analyzers/location.analyzer.test.ts](https://banes-lab.com/source/testing/test.rules/shared/analyzers/location.analyzer.test.ts.md).

## Contained in

- [test.rules/shared/analyzers](https://banes-lab.com/anatomy/testing/folder-testing-test-rules-shared-analyzers.md)

## Source

```typescript
import {
    buildImportGraph,
    computeDeadExports,
    findEntrypoints,
    walkReachable,
} from "@ssot/govlab/shared/analyzers/liveness.analyzer.ts";
import { describe, expect, it } from "vitest";
import type { ClosureGraph } from "@ssot/govlab/types/closure.types.ts";

const ENTRY = "site.entrypoint.ts";
const LIVE = "element.factory.ts";
const DEAD = "orphan.factory.ts";

const GRAPH: ClosureGraph = {
    consumers: [],
    emits: [],
    eventActivity: [],
    exports: [
        { file: LIVE, name: "createElement" },
        { file: LIVE, name: "unusedHelper" },
        { file: DEAD, name: "orphan" },
    ],
    externalConsumers: [],
    iconsExports: [],
    idsExports: [],
    imports: [{ file: ENTRY, from: `./${LIVE}`, names: ["createElement"] }],
    interfaces: [],
    registers: [],
    sideEffectImports: [],
    stringsExports: [],
    subscribes: [],
    version: 1,
};

describe("buildImportGraph, findEntrypoints and walkReachable", () => {
    const graph = buildImportGraph(GRAPH);
    const entrypoints = findEntrypoints(GRAPH, [".entrypoint.ts"], []);

    it("builds edges from the closure's imports and seeds the walk from the entrypoint files", () => {
        expect(graph.get(ENTRY)?.[0]?.target).toBe(LIVE);
        expect([...entrypoints]).toStrictEqual([ENTRY]);
    });

    it("reaches the imported export and the file it lives in, and nothing else", () => {
        const reached = walkReachable(entrypoints, graph);
        expect(reached.reachableFiles.has(LIVE)).toBe(true);
        expect(reached.reachableExports.has(`${LIVE}::createElement`)).toBe(true);
        expect(reached.reachableExports.has(`${LIVE}::unusedHelper`)).toBe(false);
    });
});

describe("computeDeadExports", () => {
    it("reports every export no entrypoint reaches, honoring the allowlist predicate", () => {
        const dead = computeDeadExports(GRAPH, [".entrypoint.ts"], [], (key) => key.endsWith("::orphan"));
        expect(dead.map((entry) => entry.name)).toStrictEqual(["unusedHelper"]);
    });
});
```
