import "jest";
import { buildNode, DovetailNodeFactory } from "../../../__specs__/buildEditorState";
import { canPlaceAttachment, closestAttachmentPlacement } from "../node";

describe(canPlaceAttachment.name, () => {
  function test(nodeFactory: DovetailNodeFactory, expected: boolean, posRef = "x") {
    const { node: doc, refMap } = buildNode(nodeFactory);
    expect(canPlaceAttachment(doc.resolve(refMap.get(posRef)!))).toBe(expected);
  }

  it("not supported in paragraph", () => test(({ doc, p }) => doc(p("{x}")), false));
  it("supported before paragraph", () => test(({ doc, p }) => doc("{x}", p()), true));
  it("supported after paragraph", () => test(({ doc, p }) => doc(p(), "{x}"), true));
});

describe(closestAttachmentPlacement.name, () => {
  function test(nodeFactory: DovetailNodeFactory, posRef = "x", expectedRef = "y") {
    const { node: doc, refMap } = buildNode(nodeFactory);
    const pos = refMap.get(posRef)!;
    const expected = refMap.get(expectedRef)!;
    expect(closestAttachmentPlacement(doc.resolve(pos)).pos).toBe(expected);
  }

  it("returns input position if valid", () => {
    test(({ doc, p }) => doc("{x}{y}", p()));
    test(({ doc, p }) => doc(p(), "{x}{y}"));
  });

  describe("searches forward for a valid location", () => {
    it("p", () => {
      test(({ doc, p }) => doc(p("{x}"), "{y}"));
      test(({ doc, p }) => doc(p("_{x}_"), "{y}"));
      test(({ doc, p }) => doc(p("{x}"), "{y}", p()));
      test(({ doc, p }) => doc(p("_{x}_"), "{y}", p()));
    });

    it("bq", () => {
      test(({ doc, bq, p }) => doc(bq(p("_{x}_")), "{y}"));
      test(({ doc, bq, p }) => doc(bq(p("_{x}_"), p()), "{y}"));
    });

    it("list", () => {
      test(({ doc, ul, li, p }) => doc(ul(li(p("_{x}_"))), "{y}"));
      test(({ doc, ul, li, p }) => doc(ul(li(p("_{x}_")), li(p())), "{y}"));
    });

    it("table", () => {
      test(({ doc, tbl, tr, td, p }) => doc(tbl(tr(td(p("_{x}_"), "{y}")))));
      test(({ doc, tbl, tr, td, p }) => doc(tbl(tr(td(p("_{x}_"), "{y}"), td(p())))));
    });

    it("hr", () => {
      test(({ doc, hr, p }) => doc(hr(), "{x}{y}", p()));
    });
  });
});
