import { signal } from "@preact-signals/unified-signals";
import React, { useMemo } from "react";
import { describe, Mock, vi } from "vitest";
import { itRenderer } from "../../../__tests__/utils";
import { Match, Switch } from "../components";
describe.concurrent("Switch()", () => {
itRenderer("should render", async ({ reactRoot, root, expect }) => {
await reactRoot().render(
1}>
1
);
const content = root.firstChild;
expect(content).is.instanceOf(HTMLDivElement);
expect(content).has.property("textContent", "1");
});
itRenderer(
"should render only first match",
async ({ reactRoot, root, expect }) => {
await reactRoot().render(
1}>
1
2}>
2
);
const content = root.firstChild;
expect(content).is.instanceOf(HTMLDivElement);
expect(content).has.property("textContent", "1");
}
);
itRenderer(
"should render only first match",
async ({ reactRoot, root, expect }) => {
await reactRoot().render(
true}>
1
2}>
2
);
const content = root.firstChild;
expect(content).is.instanceOf(HTMLDivElement);
expect(content).has.property("textContent", "1");
}
);
itRenderer(
"should pass getter if children is function",
async ({ expect, reactRoot, root }) => {
const ref = {};
const children = vi.fn((value) =>
{ref === value() ? 1 : 0}
);
await reactRoot().render(
ref}>{children}
);
expect(children).toHaveBeenCalledOnce();
const content = root.firstChild;
expect(content).is.instanceOf(HTMLDivElement);
expect(content).has.property("textContent", "1");
}
);
itRenderer("should be reactive", async ({ reactRoot, act, expect, root }) => {
const sig = signal(0);
await reactRoot().render(
sig.value % 3 === 0}>220
sig.value % 3 === 1}>221
sig.value % 3 === 2}>222
);
const content = root.firstChild;
expect(content).is.instanceOf(Text);
expect(content).has.property("data", "220");
await act(() => {
sig.value = 1;
});
expect(content).is.instanceOf(Text);
expect(content).has.property("data", "221");
});
itRenderer(
"should use fallback in case of no match",
async ({ reactRoot, expect, root }) => {
await reactRoot().render(
fallback}>
false}>220
);
const content = root.firstChild;
expect(content).is.instanceOf(HTMLDivElement);
expect(content).has.property("textContent", "fallback");
}
);
itRenderer(
"should pass not explicit falsy values",
async ({ reactRoot, act, root, expect }) => {
const sig = signal(0);
const expectResult = () => {
const content = root.firstChild;
expect(content).is.instanceOf(Text);
expect(content).has.property("data", "220");
};
const expectFallback = () => {
const content = root.firstChild;
expect(content).is.instanceOf(Text);
expect(content).has.property("data", "fallback");
};
await reactRoot().render(
sig.value}>220
);
try {
expectResult();
await act(() => {
sig.value = false;
});
expectFallback();
await act(() => {
sig.value = 1;
});
expectResult();
await act(() => {
sig.value = null;
});
expectFallback();
await act(() => {
sig.value = undefined;
});
expectFallback();
await act(() => {
sig.value = [];
});
expectResult();
} catch (e) {
console.log("failed with: ", sig.peek());
throw e;
}
}
);
itRenderer(
"must reexecute child even if nothing changed",
async ({ act, expect, reactRoot, root }) => {
const sig = signal(0);
const matchWhen = vi.fn(() => 10);
const renderWhen = vi.fn(() => 220);
const Component = vi.fn(() => {
sig.value;
return (
{renderWhen}
);
});
await reactRoot().render();
const firstChild = root.firstChild;
expect(firstChild).is.instanceOf(Text);
expect(firstChild).has.property("data", "220");
expect(Component).toHaveBeenCalledTimes(1);
expect(matchWhen).toHaveBeenCalledTimes(1);
expect(renderWhen).toHaveBeenCalledTimes(1);
await act(() => {
sig.value++;
});
expect(Component).toHaveBeenCalledTimes(2);
expect(matchWhen).toHaveBeenCalledTimes(2);
expect(renderWhen).toHaveBeenCalledTimes(2);
}
);
});