# test.build/core/converters/layer.converter.test.ts

> 67 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-build-core-converters-layer-converter-test-ts
Source text: https://banes-lab.com/source/testing/test.build/core/converters/layer.converter.test.ts.txt

Listed in [test.build/core/converters](https://banes-lab.com/api/source/testing/test.build/core/converters.md), after [test.build/core/converters/journal.converter.test.ts](https://banes-lab.com/source/testing/test.build/core/converters/journal.converter.test.ts.md) and before [test.build/core/converters/layer.reference.converter.test.ts](https://banes-lab.com/source/testing/test.build/core/converters/layer.reference.converter.test.ts.md).

## Contained in

- [test.build/core/converters](https://banes-lab.com/anatomy/testing/folder-testing-test-build-core-converters.md)

## Source

```typescript
import { describe, expect, it } from "vitest";
import {
    forceNames,
    forcesOf,
    kindsOf,
    layersOf,
    rangesOf,
} from "@banes-lab/build-scripts/core/converters/layer.converter.ts";
import { createGovlabContext } from "@govlab/context";
import { createResolver } from "@banes-lab/build-scripts/core/resolvers/ontology.resolver.ts";

const context = createGovlabContext();
const resolve = createResolver(context);

describe("layersOf", () => {
    const layers = layersOf(context, resolve);

    it("renders every layer node as a contract link with the categories that belong to it", () => {
        expect(layers.nodes).toHaveLength(context.layers().length);
        for (const layer of layers.nodes) {
            expect(layer.contract.ref).toBe(`algorithms:${layer.id}`);
        }
        expect(layers.nodes.some((layer) => layer.members.length > 0)).toBe(true);
        expect(layers.topology).toHaveLength(context.topology().length);
        expect(
            layers.topology.every(
                (edge) => edge.from.ref?.startsWith("layer:") === true && edge.to.ref?.startsWith("layer:") === true,
            ),
        ).toBe(true);
    });

    it("gives each layer the topology edges that leave it and the ones that reach it, so the page derives neither", () => {
        for (const layer of layers.nodes) {
            const ref = `layer:${layer.id}`;
            expect(layer.outgoing).toStrictEqual(layers.topology.filter((edge) => edge.from.ref === ref));
            expect(layer.incoming).toStrictEqual(layers.topology.filter((edge) => edge.to.ref === ref));
        }
        const placed = layers.nodes.reduce((total, layer) => total + layer.outgoing.length, 0);
        expect(placed).toBe(layers.topology.length);
    });

    it("maps every principle category and every extra term category to a layer link, and ids every resolution", () => {
        const archCategories = new Set(context.arch.all().map((principle) => principle.category));
        expect(layers.membership.length).toBeGreaterThanOrEqual(archCategories.size);
        expect(layers.membership.every((entry) => entry.category.ref !== null)).toBe(true);
        expect(
            layers.resolutions.every(
                (tension) => tension.id.length > 0 && tension.scopeA.ref?.startsWith("layer:") === true,
            ),
        ).toBe(true);
        expect(new Set(layers.resolutions.map((tension) => tension.id)).size).toBe(layers.resolutions.length);
    });
});

describe("kindsOf, rangesOf, forceNames and forcesOf", () => {
    it("counts the principles and terms of each kind and links each range to its kinds", () => {
        const kinds = kindsOf(context);
        expect(kinds.reduce((total, kind) => total + kind.principles, 0)).toBe(context.arch.ids().length);
        expect(kinds.reduce((total, kind) => total + kind.terms, 0)).toBe(context.lex.ids().length);
        const ranges = rangesOf(resolve);
        expect(ranges.length).toBeGreaterThan(0);
        expect(ranges.every((range) => range.kinds.every((kind) => kind.ref === `kind:${kind.label}`))).toBe(true);
    });

    it("keeps only the canonical forces and joins each to its contracts and principles", () => {
        const names = forceNames(context);
        expect(names.has("modularity")).toBe(true);
        expect([...names].some((force) => force.includes("("))).toBe(false);
        const forces = forcesOf(context, resolve);
        expect(forces.map((force) => force.force)).toStrictEqual([...names]);
        expect(forces.some((force) => force.principles.length > 0)).toBe(true);
        expect(forces.every((force) => force.contracts.every((contract) => contract.ref !== null))).toBe(true);
    });
});
```
