Skip to content

Commit 23b74ba

Browse files
authored
test: simplify react testing code (#44)
1 parent bfcf193 commit 23b74ba

File tree

1 file changed

+64
-36
lines changed

1 file changed

+64
-36
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,88 @@
1-
import { render, waitFor } from "@testing-library/preact";
1+
import { render } from "@testing-library/preact";
22
import { Duration } from "luxon";
33
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from "vitest";
44

55
import { App, Component, MarkdownRenderer } from "@/lib/obsidian/types";
66

7-
import { ObsidianMarkdown, ObsidianMarkdownProps } from "../obsidian";
7+
import { ObsidianMarkdown } from "../obsidian";
88

99
vi.mock("@/lib/obsidian/types");
10+
afterEach(() => vi.restoreAllMocks());
1011

1112
describe(`${ObsidianMarkdown.name}`, () => {
12-
const app = new App();
13-
const component = new Component();
14-
const markdown = "Hello World";
15-
const sourcePath = "/vault/diary.md";
16-
const tagName = "span";
17-
const delay = Duration.fromMillis(500);
18-
1913
beforeAll(() => vi.useFakeTimers());
20-
afterEach(() => vi.resetAllMocks());
2114
afterAll(() => vi.useRealTimers());
2215

23-
it("should invoke render with the provided props", async () => {
24-
const props: ObsidianMarkdownProps = { app, component, markdown, sourcePath, tagName, delay };
25-
26-
render(<ObsidianMarkdown {...props} />);
16+
it("should rerender when markdown changes stay stable for a while", async () => {
17+
const props = {
18+
app: new App(),
19+
component: new Component(),
20+
sourcePath: "/vault/diary.md",
21+
delay: Duration.fromMillis(500),
22+
} as const;
2723

24+
const { rerender } = render(<ObsidianMarkdown {...props} markdown="Apple" />);
2825
await vi.runAllTimersAsync();
26+
rerender(<ObsidianMarkdown {...props} markdown="Banana" />);
27+
await vi.advanceTimersByTimeAsync(300);
28+
rerender(<ObsidianMarkdown {...props} markdown="Banana" />);
29+
await vi.advanceTimersByTimeAsync(300);
2930

30-
await waitFor(() =>
31-
expect(MarkdownRenderer.render).toHaveBeenCalledWith(
32-
app,
33-
markdown,
34-
expect.any(HTMLSpanElement),
35-
sourcePath,
36-
component,
37-
),
31+
const anySpanElement = expect.any(HTMLSpanElement);
32+
expect(MarkdownRenderer.render).toHaveBeenCalledTimes(2);
33+
expect(MarkdownRenderer.render).toHaveBeenCalledWith(
34+
props.app,
35+
"Apple",
36+
anySpanElement,
37+
props.sourcePath,
38+
props.component,
39+
);
40+
expect(MarkdownRenderer.render).toHaveBeenCalledWith(
41+
props.app,
42+
"Banana",
43+
anySpanElement,
44+
props.sourcePath,
45+
props.component,
3846
);
3947
});
4048

41-
it("should rerender after a delay when the markdown value changes", async () => {
42-
const delay = Duration.fromMillis(300);
43-
const props: ObsidianMarkdownProps = { markdown: "Hello, World!", app, component, sourcePath, tagName, delay };
49+
it("should not rerender when markdown changes too frequently", async () => {
50+
const props = {
51+
app: new App(),
52+
component: new Component(),
53+
sourcePath: "/vault/diary.md",
54+
delay: Duration.fromMillis(500),
55+
} as const;
4456

45-
const { rerender } = render(<ObsidianMarkdown {...props} />);
57+
const { rerender } = render(<ObsidianMarkdown {...props} markdown="Apple" />);
4658
await vi.runAllTimersAsync();
59+
rerender(<ObsidianMarkdown {...props} markdown="Banana" />);
60+
await vi.advanceTimersByTimeAsync(300);
61+
rerender(<ObsidianMarkdown {...props} markdown="Cherry" />);
62+
await vi.advanceTimersByTimeAsync(300);
4763

64+
const anySpanElement = expect.any(HTMLSpanElement);
4865
expect(MarkdownRenderer.render).toHaveBeenCalledTimes(1);
49-
50-
rerender(<ObsidianMarkdown {...{ ...props, markdown: "Hello, Planet" }} />);
51-
await vi.advanceTimersByTimeAsync(299);
52-
53-
expect(MarkdownRenderer.render).toHaveBeenCalledTimes(1);
54-
55-
rerender(<ObsidianMarkdown {...{ ...props, markdown: "Hello, Planet" }} />);
56-
await vi.advanceTimersByTimeAsync(1);
57-
58-
expect(MarkdownRenderer.render).toHaveBeenCalledTimes(2);
66+
expect(MarkdownRenderer.render).toHaveBeenCalledWith(
67+
props.app,
68+
"Apple",
69+
anySpanElement,
70+
props.sourcePath,
71+
props.component,
72+
);
73+
expect(MarkdownRenderer.render).not.toHaveBeenCalledWith(
74+
props.app,
75+
"Banana",
76+
anySpanElement,
77+
props.sourcePath,
78+
props.component,
79+
);
80+
expect(MarkdownRenderer.render).not.toHaveBeenCalledWith(
81+
props.app,
82+
"Cherry",
83+
anySpanElement,
84+
props.sourcePath,
85+
props.component,
86+
);
5987
});
6088
});

0 commit comments

Comments
 (0)