Przeglądaj źródła

chore: Dialog, dom and errors unit tests

Sv443 3 tygodni temu
rodzic
commit
dd78273d02
3 zmienionych plików z 237 dodań i 0 usunięć
  1. 30 0
      lib/Dialog.spec.ts
  2. 194 0
      lib/dom.spec.ts
  3. 13 0
      lib/errors.spec.ts

+ 30 - 0
lib/Dialog.spec.ts

@@ -0,0 +1,30 @@
+import { describe, expect, it } from "vitest";
+import { Dialog } from "./Dialog.js";
+
+//TODO:FIXME: doesn't work because of random "DOMException {}"
+describe.skip("Dialog", () => {
+  it("Gets created, opened, closed and deleted properly", async () => {
+    const dialog = new Dialog({
+      id: "test-1",
+      height: 100,
+      width: 200,
+      renderBody: () => document.createElement("div"),
+    });
+
+    expect(document.querySelector(".uu-dialog-bg")).toBeNull();
+
+    await dialog.mount();
+
+    expect(document.querySelector(".uu-dialog-bg")).not.toBeNull();
+
+    expect(document.body.classList.contains("uu-no-select")).toBe(false);
+    await dialog.open();
+    expect(document.body.classList.contains("uu-no-select")).toBe(true);
+
+    dialog.close();
+    expect(document.body.classList.contains("uu-no-select")).toBe(false);
+
+    dialog.unmount();
+    expect(document.querySelector(".uu-dialog-bg")).toBeNull();
+  });
+});

+ 194 - 0
lib/dom.spec.ts

@@ -0,0 +1,194 @@
+import { describe, expect, it } from "vitest";
+import { addGlobalStyle, addParent, getSiblingsFrame, getUnsafeWindow, interceptEvent, isDomLoaded, observeElementProp, preloadImages, probeElementStyle, setInnerHtmlUnsafe } from "./dom.js";
+
+//#region getUnsafeWindow
+describe("dom/getUnsafeWindow", () => {
+  it("Returns the correct window objects", () => {
+    expect(getUnsafeWindow()).toBe(window);
+    var unsafeWindow = window;
+    expect(getUnsafeWindow()).toBe(unsafeWindow);
+  });
+});
+
+//#region addParent
+describe("dom/addParent", () => {
+  it("Adds a parent to an element", () => {
+    const container = document.createElement("div");
+    container.id = "container";
+
+    const child = document.createElement("div");
+    child.id = "child";
+
+    document.body.appendChild(child);
+
+    addParent(child, container);
+
+    expect(child.parentNode).toBe(container);
+
+    container.remove();
+  });
+});
+
+//#region addGlobalStyle
+describe("dom/addGlobalStyle", () => {
+  it("Adds a global style to the document", () => {
+    const el = addGlobalStyle(`body { background-color: red; }`);
+    el.id = "test-style";
+
+    expect(document.querySelector("head #test-style")).toBe(el);
+  });
+});
+
+//#region preloadImages
+//TODO:FIXME: no workis
+describe.skip("dom/preloadImages", () => {
+  it("Preloads images", async () => {
+    const res = await preloadImages(["https://picsum.photos/50/50"]);
+
+    expect(Array.isArray(res)).toBe(true);
+    expect(res.every(r => r.status === "fulfilled")).toBe(true);
+  });
+});
+
+//#region openInNewTab
+describe.skip("dom/openInNewTab", () => {
+  // obviously cant test this
+});
+
+//#region interceptEvent
+describe("dom/interceptEvent", () => {
+  it("Intercepts an event", () => {
+    const el = document.createElement("div");
+    el.id = "test-intercept";
+    document.body.appendChild(el);
+    
+    let clickedTimes = 0;
+
+    el.addEventListener("click", () => ++clickedTimes);
+    interceptEvent(el, "click", () => true);
+    el.addEventListener("click", () => ++clickedTimes);
+
+    el.click();
+
+    expect(clickedTimes).toBe(1);
+
+    document.body.removeChild(el);
+  });
+});
+
+//#region interceptWindowEvent
+describe("dom/interceptWindowEvent", () => {
+  it("Intercepts a window event", () => {
+    let clickedTimes = 0;
+
+    const inc = () => clickedTimes++;
+
+    window.addEventListener("foo", inc);
+    interceptEvent(window, "foo", () => true);
+    window.addEventListener("foo", inc);
+
+    window.dispatchEvent(new Event("foo"));
+
+    expect(clickedTimes).toBe(1);
+
+    window.removeEventListener("foo", inc);
+  });
+});
+
+//#region observeElementProp
+//TODO:FIXME: no workio
+describe.skip("dom/observeElementProp", () => {
+  it("Observes an element property", () => {
+    const el = document.createElement("input");
+    el.type = "text";
+    document.body.appendChild(el);
+
+    let newVal = "";
+    observeElementProp(el, "value", (_oldVal, newVal) => {
+      newVal = newVal;
+    });
+
+    el.value = "foo";
+
+    expect(newVal).toBe("foo");
+  });
+});
+
+//#region getSiblingsFrame
+describe("dom/getSiblingsFrame", () => {
+  it("Returns the correct frame", () => {
+    const container = document.createElement("div");
+    for(let i = 0; i < 10; i++) {
+      const el = document.createElement("div");
+      el.id = `e${i}`;
+      container.appendChild(el);
+    }
+
+    const cntrEl = container.querySelector<HTMLElement>("#e5")!;
+
+    expect(getSiblingsFrame(cntrEl, 2).map(e => e.id)).toEqual(["e5", "e6"]);
+    expect(getSiblingsFrame(cntrEl, 2, "top", false).map(e => e.id)).toEqual(["e6", "e7"]);
+    expect(getSiblingsFrame(cntrEl, 2, "bottom", false).map(e => e.id)).toEqual(["e3", "e4"]);
+    expect(getSiblingsFrame(cntrEl, 2, "center-top", false).map(e => e.id)).toEqual(["e4", "e6"]);
+    expect(getSiblingsFrame(cntrEl, 3, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6"]);
+    expect(getSiblingsFrame(cntrEl, 4, "center-top", true).map(e => e.id)).toEqual(["e4", "e5", "e6", "e7"]);
+    expect(getSiblingsFrame(cntrEl, 4, "center-bottom", true).map(e => e.id)).toEqual(["e3", "e4", "e5", "e6"]);
+  });
+});
+
+//#region setInnerHtmlUnsafe
+describe("dom/setInnerHtmlUnsafe", () => {
+  it("Sets inner HTML", () => {
+    const el = document.createElement("div");
+    setInnerHtmlUnsafe(el, "<div>foo</div>");
+
+    expect(el.querySelector("div")?.textContent).toBe("foo");
+  });
+});
+
+//#region probeElementStyle
+//TODO:FIXME: no workiong
+describe.skip("dom/probeElementStyle", () => {
+  it("Resolves a CSS variable", async () => {
+    addGlobalStyle(`:root { --foo: #f00; --bar: var(--foo, #00f); }`);
+
+    const tryResolveCol = (i = 0) => new Promise<string>((res, rej) => {
+      if(i > 100)
+        return rej(new Error("Could not resolve color after 100 tries"));
+
+      const probedCol = probeElementStyle(
+        (style) => style.backgroundColor,
+        () => {
+          const elem = document.createElement("span");
+          elem.style.backgroundColor = "var(--foo, #000)";
+          return elem;
+        },
+        true,
+      );
+
+      if(probedCol.length === 0 || probedCol.match(/^rgba?\((?:(?:255,\s?255,\s?255)|(?:0,\s?0,\s?0))/) || probedCol.match(/^#(?:fff(?:fff)?|000(?:000)?)/))
+        return setTimeout(async () => res(await tryResolveCol(++i)), 100);
+
+      return res(probedCol);
+    });
+
+    const val = await tryResolveCol();
+
+    expect(val).toBe("rgb(255, 0, 0)");
+  });
+});
+
+const initialState = document.readyState;
+
+//#region isDomLoaded
+describe.skip("dom/isDomLoaded", () => {
+  it("Returns the correct state", () => {
+    // doesn't work cause the lib isn't loaded before DOMContentLoaded
+    expect(isDomLoaded()).toBe(initialState === "complete");
+  });
+});
+
+//#region onDomLoad
+describe.skip("dom/onDomLoad", () => {
+  // see above
+});

+ 13 - 0
lib/errors.spec.ts

@@ -0,0 +1,13 @@
+import { describe, expect, it } from "vitest";
+import { ChecksumMismatchError, MigrationError, PlatformError } from "./errors.js";
+
+describe("errors", () => {
+  it("Has a \"date\" property", () => {
+    expect(new ChecksumMismatchError("").name).toBe("ChecksumMismatchError");
+    expect(new MigrationError("").name).toBe("MigrationError");
+    expect(new PlatformError("").name).toBe("PlatformError");
+
+    expect(new PlatformError("").message).toBe("");
+    expect(new PlatformError("").date).toBeInstanceOf(Date);
+  });
+});