testMutualRecursionHashesAsACycle
Mutually recursive definitions hash as a cycle, independent of source order.
import { analyze } from "#codebase/tcmts/core/test/hash"; import assert from "node:assert/strict"; export const testMutualRecursionHashesAsACycle = () => { const a = analyze(` function isEven(n: number): boolean { return n === 0 ? true : isOdd(n - 1) } function isOdd(n: number): boolean { return n === 0 ? false : isEven(n - 1) }`).defs; const b = analyze(` function isOdd(k: number): boolean { return k === 0 ? false : isEven(k - 1) } function isEven(k: number): boolean { return k === 0 ? true : isOdd(k - 1) }`).defs; assert.equal(a[0]!.componentSize, 2); assert.equal(a[0]!.componentHash, b[0]!.componentHash); const byName = (ds: typeof a) => Object.fromEntries(ds.map((d) => [d.nameHint, d.hash])); assert.equal(byName(a).isEven, byName(b).isEven); assert.equal(byName(a).isOdd, byName(b).isOdd); assert.notEqual(byName(a).isEven, byName(a).isOdd); }