import { describe, expect, it } from "vitest";
import {
  isPatternSyntaxCurrent,
  isPatternSyntaxForInput,
  type PatternSyntaxSnapshot,
} from "./pattern-syntax-freshness";

describe("pattern syntax freshness", () => {
  const snapshot: PatternSyntaxSnapshot<{ readonly accepted: boolean }> = {
    revision: 7,
    request: {
      flavour: "ecmascript",
      flavourVersion: "ECMAScript 2025",
      pattern: "(?<old>a)",
      flags: ["g", "u"],
      options: {},
    },
    result: { accepted: true },
  };

  it("rejects accepted syntax as soon as the input revision changes", () => {
    expect(isPatternSyntaxCurrent(snapshot, 8, snapshot.request)).toBe(false);
    expect(isPatternSyntaxCurrent(snapshot, 7, snapshot.request)).toBe(true);
  });

  it("rejects syntax produced for a different pattern or flag set", () => {
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        pattern: "(?<new>b)",
      }),
    ).toBe(false);
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        flags: ["g", "i"],
      }),
    ).toBe(false);
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        flags: ["u", "g"],
      }),
    ).toBe(false);
  });

  it("includes flavour, version, and engine options in syntax identity", () => {
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        flavour: "pcre2",
      }),
    ).toBe(false);
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        flavourVersion: "different",
      }),
    ).toBe(false);
    expect(
      isPatternSyntaxForInput(snapshot, {
        ...snapshot.request,
        options: { extended: true },
      }),
    ).toBe(false);
  });
});
