react-native-web-internals
Version:
React Native for Web
276 lines (275 loc) • 13.1 kB
JavaScript
import { createEventTarget } from "dom-event-testing-library";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { act } from "react-dom/test-utils";
import useEvent from "..";
import { jsx } from "react/jsx-runtime";
function createRoot(rootNode) {
return {
render(element) {
ReactDOM.render(element, rootNode);
}
};
}
describe("use-event", () => {
let root, rootNode;
beforeEach(() => {
rootNode = document.createElement("div"), document.body.appendChild(rootNode), root = createRoot(rootNode);
}), afterEach(() => {
root.render(null), document.body.removeChild(rootNode), rootNode = null, root = null;
}), describe("setListener()", () => {
test("event dispatched on target", () => {
const listener = jest.fn(), targetRef = React.createRef();
function Component() {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(targetRef.current, listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1);
}), test("event dispatched on parent", () => {
const listener = jest.fn(), listenerCapture = jest.fn(), targetRef = React.createRef(), parentRef = React.createRef();
function Component() {
const addClickListener = useEvent("click"), addClickCaptureListener = useEvent("click", { capture: !0 });
return React.useEffect(() => {
addClickListener(targetRef.current, listener), addClickCaptureListener(targetRef.current, listenerCapture);
}), /* @__PURE__ */ jsx("div", { ref: parentRef, children: /* @__PURE__ */ jsx("div", { ref: targetRef }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const parent = createEventTarget(parentRef.current);
act(() => {
parent.click();
}), expect(listener).toBeCalledTimes(0), expect(listenerCapture).toBeCalledTimes(0);
}), test("event dispatched on child", () => {
const log = [], listener = jest.fn(() => {
log.push("bubble");
}), listenerCapture = jest.fn(() => {
log.push("capture");
}), targetRef = React.createRef(), childRef = React.createRef();
function Component() {
const addClickListener = useEvent("click"), addClickCaptureListener = useEvent("click", { capture: !0 });
return React.useEffect(() => {
addClickListener(targetRef.current, listener), addClickCaptureListener(targetRef.current, listenerCapture);
}), /* @__PURE__ */ jsx("div", { ref: targetRef, children: /* @__PURE__ */ jsx("div", { ref: childRef }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const child = createEventTarget(childRef.current);
act(() => {
child.click();
}), expect(listenerCapture).toBeCalledTimes(1), expect(listener).toBeCalledTimes(1), expect(log).toEqual(["capture", "bubble"]);
}), test("event dispatched on text node", () => {
const listener = jest.fn(), targetRef = React.createRef(), childRef = React.createRef();
function Component() {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(targetRef.current, listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef, children: /* @__PURE__ */ jsx("div", { ref: childRef, children: "text" }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const text = createEventTarget(childRef.current.firstChild);
act(() => {
text.click();
}), expect(listener).toBeCalledTimes(1);
}), test("listener can be attached to document ", () => {
const listener = jest.fn(), targetRef = React.createRef();
function Component({ target: target2 }) {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(target2, listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, { target: document }));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1);
}), test("listener can be attached to window ", () => {
const listener = jest.fn(), targetRef = React.createRef();
function Component({ target: target2 }) {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(target2, listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, { target: window }));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1);
}), test("listener is replaceable", () => {
const listener = jest.fn(), listenerAlt = jest.fn(), targetRef = React.createRef();
function Component({ onClick }) {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(targetRef.current, onClick);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, { onClick: listener }));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1), act(() => {
root.render(/* @__PURE__ */ jsx(Component, { onClick: listenerAlt }));
}), act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1), expect(listenerAlt).toBeCalledTimes(1);
}), test("listener is removed when value is null", () => {
const listener = jest.fn(), targetRef = React.createRef();
function Component({ off }) {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(targetRef.current, off ? null : listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, { off: !1 }));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(listener).toBeCalledTimes(1), act(() => {
root.render(/* @__PURE__ */ jsx(Component, { off: !0 }));
}), listener.mockClear(), act(() => {
target.click();
}), expect(listener).toBeCalledTimes(0);
}), test("custom event dispatched on target", () => {
const listener = jest.fn(), targetRef = React.createRef();
function Component() {
const addMagicEventListener = useEvent("magic-event");
return React.useEffect(() => {
addMagicEventListener(targetRef.current, listener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
}), act(() => {
const event = new CustomEvent("magic-event", { bubbles: !0 });
targetRef.current.dispatchEvent(event);
}), expect(listener).toBeCalledTimes(1);
}), test("listeners can be set on multiple targets simultaneously", () => {
const log = [], targetRef = React.createRef(), parentRef = React.createRef(), childRef = React.createRef(), listener = jest.fn((e) => {
log.push(["bubble", e.currentTarget.id]);
}), listenerCapture = jest.fn((e) => {
log.push(["capture", e.currentTarget.id]);
});
function Component() {
const addClickListener = useEvent("click"), addClickCaptureListener = useEvent("click", { capture: !0 });
return React.useEffect(() => {
addClickListener(targetRef.current, listener), addClickListener(parentRef.current, listener), addClickCaptureListener(targetRef.current, listenerCapture), addClickCaptureListener(parentRef.current, listenerCapture);
}), /* @__PURE__ */ jsx("div", { id: "parent", ref: parentRef, children: /* @__PURE__ */ jsx("div", { id: "target", ref: targetRef, children: /* @__PURE__ */ jsx("div", { ref: childRef }) }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const child = createEventTarget(childRef.current);
act(() => {
child.click();
}), expect(listenerCapture).toBeCalledTimes(2), expect(listener).toBeCalledTimes(2), expect(log).toEqual([
["capture", "parent"],
["capture", "target"],
["bubble", "target"],
["bubble", "parent"]
]);
}), test("listeners are specific to each event handle", () => {
const log = [], targetRef = React.createRef(), childRef = React.createRef(), listener = jest.fn((e) => {
log.push(["bubble", "target"]);
}), listenerAlt = jest.fn((e) => {
log.push(["bubble", "target-alt"]);
}), listenerCapture = jest.fn((e) => {
log.push(["capture", "target"]);
}), listenerCaptureAlt = jest.fn((e) => {
log.push(["capture", "target-alt"]);
});
function Component() {
const addClickListener = useEvent("click"), addClickAltListener = useEvent("click"), addClickCaptureListener = useEvent("click", { capture: !0 }), addClickCaptureAltListener = useEvent("click", { capture: !0 });
return React.useEffect(() => {
addClickListener(targetRef.current, listener), addClickAltListener(targetRef.current, listenerAlt), addClickCaptureListener(targetRef.current, listenerCapture), addClickCaptureAltListener(targetRef.current, listenerCaptureAlt);
}), /* @__PURE__ */ jsx("div", { id: "target", ref: targetRef, children: /* @__PURE__ */ jsx("div", { ref: childRef }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const child = createEventTarget(childRef.current);
act(() => {
child.click();
}), expect(listenerCapture).toBeCalledTimes(1), expect(listenerCaptureAlt).toBeCalledTimes(1), expect(listener).toBeCalledTimes(1), expect(listenerAlt).toBeCalledTimes(1), expect(log).toEqual([
["capture", "target"],
["capture", "target-alt"],
["bubble", "target"],
["bubble", "target-alt"]
]);
});
}), describe("cleanup", () => {
test("removes all listeners for given event type from targets", () => {
const clickListener = jest.fn();
function Component() {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(document, clickListener);
}), /* @__PURE__ */ jsx("div", {});
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {})), root.render(null);
});
const target = createEventTarget(document);
act(() => {
target.click();
}), expect(clickListener).toBeCalledTimes(0);
});
}), describe("stopPropagation and stopImmediatePropagation", () => {
test("stopPropagation works as expected", () => {
const childListener = jest.fn((e) => {
e.stopPropagation();
}), targetListener = jest.fn(), targetRef = React.createRef(), childRef = React.createRef();
function Component() {
const addClickListener = useEvent("click");
return React.useEffect(() => {
addClickListener(childRef.current, childListener), addClickListener(targetRef.current, targetListener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef, children: /* @__PURE__ */ jsx("div", { ref: childRef }) });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const child = createEventTarget(childRef.current);
act(() => {
child.click();
}), expect(childListener).toBeCalledTimes(1), expect(targetListener).toBeCalledTimes(0);
}), test("stopImmediatePropagation works as expected", () => {
const firstListener = jest.fn((e) => {
e.stopImmediatePropagation();
}), secondListener = jest.fn(), targetRef = React.createRef();
function Component() {
const addFirstClickListener = useEvent("click"), addSecondClickListener = useEvent("click");
return React.useEffect(() => {
addFirstClickListener(targetRef.current, firstListener), addSecondClickListener(targetRef.current, secondListener);
}), /* @__PURE__ */ jsx("div", { ref: targetRef });
}
act(() => {
root.render(/* @__PURE__ */ jsx(Component, {}));
});
const target = createEventTarget(targetRef.current);
act(() => {
target.click();
}), expect(firstListener).toBeCalledTimes(1), expect(secondListener).toBeCalledTimes(0);
});
});
});
//# sourceMappingURL=index-test.js.map