60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import {
|
|
type PasswordStrengthError,
|
|
PWSTRENGTH_CODES,
|
|
} from "../errors/error-codes.js";
|
|
import { AZERTY_GRAPH } from "./azerty/azerty.js";
|
|
import { DVORAK_GRAPH } from "./dvorak/dvorak.js";
|
|
import { QWERTY_GRAPH } from "./qwerty/qwerty.js";
|
|
import { validateGraph } from "./validate-graph.js";
|
|
|
|
describe("validateGraph", () => {
|
|
it("accepts QWERTY", { timeout: 5000 }, () => {
|
|
expect(() => validateGraph("qwerty", QWERTY_GRAPH)).not.toThrow();
|
|
});
|
|
|
|
it("accepts DVORAK", { timeout: 5000 }, () => {
|
|
expect(() => validateGraph("dvorak", DVORAK_GRAPH)).not.toThrow();
|
|
});
|
|
|
|
it("accepts AZERTY", { timeout: 5000 }, () => {
|
|
expect(() => validateGraph("azerty", AZERTY_GRAPH)).not.toThrow();
|
|
});
|
|
|
|
it("rejects self-adjacency", { timeout: 5000 }, () => {
|
|
try {
|
|
validateGraph("broken", { q: ["q"] });
|
|
} catch (e) {
|
|
expect((e as PasswordStrengthError).code).toBe(
|
|
PWSTRENGTH_CODES.GRAPH_INVALID
|
|
);
|
|
}
|
|
});
|
|
|
|
it("rejects asymmetric edges", { timeout: 5000 }, () => {
|
|
try {
|
|
validateGraph("asym", { a: ["b"], b: ["c"], c: ["b"] });
|
|
} catch (e) {
|
|
expect((e as PasswordStrengthError).code).toBe(
|
|
PWSTRENGTH_CODES.GRAPH_INVALID
|
|
);
|
|
}
|
|
});
|
|
|
|
it("skips null slots", { timeout: 5000 }, () => {
|
|
// graph with only null slots is trivially symmetric
|
|
expect(() =>
|
|
validateGraph("nullonly", { a: [null], b: [null] })
|
|
).not.toThrow();
|
|
});
|
|
|
|
it("skips empty adjacency lists", { timeout: 5000 }, () => {
|
|
expect(() => validateGraph("empty", { a: [] })).not.toThrow();
|
|
});
|
|
|
|
it("skips edges pointing to keys not in graph", { timeout: 5000 }, () => {
|
|
// x not in graph → neighbor undefined, skip
|
|
expect(() => validateGraph("dangling", { a: ["x"] })).not.toThrow();
|
|
});
|
|
});
|