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

> 73 lines of code and 0 definitions.

Tree: Codebase Testing
Language: typescript
Canonical: https://banes-lab.com/anatomy/testing#file-testing-test-rules-shared-analyzers-composition-analyzer-test-ts
Source text: https://banes-lab.com/source/testing/test.rules/shared/analyzers/composition.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/check.analyzer.test.ts](https://banes-lab.com/source/testing/test.rules/shared/analyzers/check.analyzer.test.ts.md) and before [test.rules/shared/analyzers/document.analyzer.test.ts](https://banes-lab.com/source/testing/test.rules/shared/analyzers/document.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 {
    commentOpenerOf,
    compositionFindingsOf,
    contentWordsOf,
    fieldRestates,
    fillerOf,
    overlapOf,
    partyOf,
    restates,
    withoutQuotes,
    withoutTags,
} from "@ssot/govlab/shared/analyzers/composition.analyzer.ts";
import { describe, expect, it } from "vitest";

describe("withoutTags and withoutQuotes", () => {
    it("drops markup but keeps its text, and drops quoted replies whole", () => {
        expect(withoutTags('the <a href="/x">loop</a> runs').split(" ").filter(Boolean)).toStrictEqual([
            "the",
            "loop",
            "runs",
        ]);
        expect(withoutQuotes("it reads <em>note that</em> here").includes("note")).toBe(false);
    });
});

describe("commentOpenerOf and fillerOf", () => {
    it("finds a pointing-back opener only at the start and a filler phrase anywhere", () => {
        expect(commentOpenerOf(["that", "is", "idempotency"])).toBe("that is");
        expect(commentOpenerOf(["the", "that", "is"])).toBeNull();
        expect(commentOpenerOf(["that", "is", "the", "loop"])).toBe("that is");
        expect(
            commentOpenerOf(["this", "is", "done", "by", "running", "the", "check", "on", "every", "change"]),
        ).toBeNull();
        expect(commentOpenerOf(["that", "makes", "the", "check", "fail", "on", "every", "change"])).toBe("that makes");
        expect(fillerOf(["the", "key", "point", "is", "x"])).toBe("the key point");
        expect(fillerOf(["the", "gate", "runs"])).toBeNull();
    });
});

describe("contentWordsOf, overlapOf, restates and fieldRestates", () => {
    it("compares sentences by their content words, folding plurals", () => {
        expect([...contentWordsOf("The checks run on every change.")]).toStrictEqual(["check", "run", "change"]);
        expect(overlapOf(new Set(["a"]), new Set(["a"]))).toBe(0);
        expect(
            restates(
                "Every check writes its report to disk after every run.",
                "After every run, every check writes its report to disk.",
            ),
        ).toBe(true);
        expect(
            restates("A word also matches its longer forms.", "A longer word also forgives one slip of spelling."),
        ).toBe(false);
        expect(
            fieldRestates(
                "A template carries the contract and a check reads the template slots.",
                "Read the template slots as the contract a check carries.",
            ),
        ).toBe(true);
    });
});

describe("partyOf", () => {
    it("names the unnamed actor, and passes the named parties", () => {
        expect(partyOf(["until", "someone", "reads", "it"])).toBe("someone");
        expect(partyOf(["nobody", "recalls", "it"])).toBe("nobody");
        expect(partyOf(["an", "await", "joins", "a", "reader"])).toBeNull();
        expect(partyOf(["the", "model", "and", "the", "developer"])).toBeNull();
    });
});

describe("compositionFindingsOf", () => {
    it("reports each kind once, and never a pointing-back opener on the first sentence", () => {
        const kinds = compositionFindingsOf(
            "That is fine. The gate runs. That is the gate. It is worth noting that it runs.",
        ).map((finding) => finding.kind);
        expect(kinds).toStrictEqual(["comment", "filler"]);
    });
});
```
