Initial Commit
This commit is contained in:
67
packages/api-stack/api/api-plugin/tests/property.test.ts
Normal file
67
packages/api-stack/api/api-plugin/tests/property.test.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { describe, expect, it } from "@suaveplan/testing/runner";
|
||||
import fc from "fast-check";
|
||||
import { topologicalSort } from "../src/topo-sort/topo-sort.js";
|
||||
import type { PluginNode } from "../src/types/api-plugin.js";
|
||||
|
||||
/** Generate an acyclic dep graph: each node's deps only point to earlier ids. */
|
||||
const acyclicGraphArb = fc
|
||||
.array(fc.string({ minLength: 1, maxLength: 4 }), {
|
||||
minLength: 1,
|
||||
maxLength: 20,
|
||||
})
|
||||
.map((rawIds) => {
|
||||
const ids = Array.from(new Set(rawIds));
|
||||
return ids;
|
||||
})
|
||||
.filter((ids) => ids.length > 0)
|
||||
.chain((ids) =>
|
||||
fc
|
||||
.tuple(
|
||||
...ids.map((_, i) =>
|
||||
fc.subarray(ids.slice(0, i), { maxLength: i })
|
||||
)
|
||||
)
|
||||
.map((depsPerNode) =>
|
||||
ids.map<PluginNode<null>>((id, i) => ({
|
||||
id,
|
||||
data: null,
|
||||
dependencies: depsPerNode[i] ?? [],
|
||||
}))
|
||||
)
|
||||
);
|
||||
|
||||
describe("topologicalSort — property tests", () => {
|
||||
it("sorted order satisfies dep invariant", { timeout: 30000 }, () => {
|
||||
fc.assert(
|
||||
fc.property(acyclicGraphArb, (nodes) => {
|
||||
const { sorted } = topologicalSort(nodes);
|
||||
const positions = new Map<string, number>();
|
||||
sorted.forEach((n, i) => positions.set(n.id, i));
|
||||
for (const node of sorted) {
|
||||
for (const dep of node.dependencies) {
|
||||
const depPos = positions.get(dep);
|
||||
const nodePos = positions.get(node.id);
|
||||
// dep must appear before node (if dep is in the graph)
|
||||
if (depPos !== undefined && nodePos !== undefined) {
|
||||
expect(depPos).toBeLessThan(nodePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
{ numRuns: 200 }
|
||||
);
|
||||
});
|
||||
|
||||
it("sort is deterministic across repeated calls", {
|
||||
timeout: 30000,
|
||||
}, () => {
|
||||
fc.assert(
|
||||
fc.property(acyclicGraphArb, (nodes) => {
|
||||
const a = topologicalSort(nodes).sorted.map((n) => n.id);
|
||||
const b = topologicalSort(nodes).sorted.map((n) => n.id);
|
||||
expect(a).toEqual(b);
|
||||
}),
|
||||
{ numRuns: 200 }
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user