# test.govlab/context/core/validators/alias.validator.test.ts

> 96 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-govlab-context-core-validators-alias-validator-test-ts
Source text: https://banes-lab.com/source/testing/test.govlab/context/core/validators/alias.validator.test.ts.txt

Listed in [test.govlab/context/core/validators](https://banes-lab.com/api/source/testing/test.govlab/context/core/validators.md), after [test.govlab/context/core/validators/algorithm.validator.test.ts](https://banes-lab.com/source/testing/test.govlab/context/core/validators/algorithm.validator.test.ts.md) and before [test.govlab/context/core/validators/architecture.validator.test.ts](https://banes-lab.com/source/testing/test.govlab/context/core/validators/architecture.validator.test.ts.md).

## Contained in

- [test.govlab/context/core/validators](https://banes-lab.com/anatomy/testing/folder-testing-test-govlab-context-core-validators.md)

## Source

```typescript
import { aliasDefectsOf, aliasHoldersOf } from "@govlab/context/core/validators/alias.validator.ts";
import { describe, expect, it } from "vitest";
import type { AliasHolder } from "@govlab/context/types/validation.types.ts";
import { createGovlabContext } from "@govlab/context";

const holder = function holder(
    ref: string,
    names: readonly string[],
    aliases: readonly string[],
    distinct: readonly string[] = [],
): AliasHolder {
    return { aliases, collection: "architecture", distinct: new Set(distinct), names, ref };
};

const reasonsOf = function reasonsOf(holders: readonly AliasHolder[]): readonly string[] {
    return aliasDefectsOf(holders).map((defect) => `${defect.ref} ${defect.alias}: ${defect.reason}`);
};

describe("aliasDefectsOf", () => {
    it("accepts an acronym and a synonym no other record holds", () => {
        expect(
            reasonsOf([holder("architecture:god-object", ["god-object", "God Object"], ["God Class", "Blob"])]),
        ).toStrictEqual([]);
    });

    it("refuses an alias that repeats the record's own name or id", () => {
        expect(
            reasonsOf([holder("architecture:god-object", ["god-object", "God Object"], ["god object"])]),
        ).toStrictEqual(["architecture:god-object god object: repeats the record's own name or id"]);
    });

    it("refuses an alias that only adds a plural or a British spelling a lookup folds already", () => {
        expect(
            reasonsOf([holder("architecture:normalization", ["normalization", "Normalization"], ["normalisations"])]),
        ).toStrictEqual([
            "architecture:normalization normalisations: differs from the record's name only by a plural or a spelling, which every lookup folds already",
        ]);
    });

    it("refuses an alias with no letter or digit", () => {
        expect(reasonsOf([holder("architecture:a", ["a"], ["--"])])).toStrictEqual([
            "architecture:a --: holds no letter or digit, so it keys nothing",
        ]);
    });

    it("refuses one alias on two records of a collection unless each lists the other in distinctFrom", () => {
        const injection = "architecture:dependency-injection";
        const inversion = "architecture:dependency-inversion";
        expect(
            reasonsOf([
                holder(injection, ["Dependency Injection"], ["DI"]),
                holder(inversion, ["Dependency Inversion"], ["DI"]),
            ]),
        ).toStrictEqual([
            `${injection} DI: is also a name or alias of ${inversion}, and the records do not list each other in distinctFrom`,
            `${inversion} DI: is also a name or alias of ${injection}, and the records do not list each other in distinctFrom`,
        ]);
        expect(
            reasonsOf([
                holder(injection, ["Dependency Injection"], ["DI"], [inversion]),
                holder(inversion, ["Dependency Inversion"], ["DI"], [injection]),
            ]),
        ).toStrictEqual([]);
    });

    it("refuses two records of a collection whose names fold to one key, unless each lists the other in distinctFrom", () => {
        const single = "lexicon:breaking-change";
        const plural = "lexicon:breaking-changes";
        expect(
            reasonsOf([
                holder(single, ["breaking-change", "Breaking Change"], []),
                holder(plural, ["Breaking Changes"], []),
            ]),
        ).toStrictEqual([
            `${single} Breaking Change: is also a name or alias of ${plural}, and the records do not list each other in distinctFrom`,
            `${plural} Breaking Changes: is also a name or alias of ${single}, and the records do not list each other in distinctFrom`,
        ]);
        expect(
            reasonsOf([
                holder(single, ["Breaking Change"], [], [plural]),
                holder(plural, ["Breaking Changes"], [], [single]),
            ]),
        ).toStrictEqual([]);
    });

    it("lets two collections share a name, since one concept can be a principle and a contract", () => {
        const principle = holder("architecture:queuing-theory", ["Queuing Theory"], ["queueing theory"]);
        const contract: AliasHolder = {
            ...holder("algorithms:queuing-theory", ["Queuing Theory"], ["queueing theory"]),
            collection: "algorithms",
        };
        expect(reasonsOf([principle, contract])).toStrictEqual([]);
    });
});

describe("aliasHoldersOf", () => {
    it("gathers every record kind that can hold an alias from the bundled ontology", () => {
        const holders = aliasHoldersOf(createGovlabContext());
        const collections = new Set(holders.map((entry) => entry.collection));
        expect(collections).toContain("architecture");
        expect(collections).toContain("lexicon");
        expect(collections).toContain("algorithms");
        expect(collections).toContain("keyword");
        expect(collections).toContain("node");
    });
});
```
