diff --git a/tests/children-snippet/CardWithChildren.test.svelte b/tests/children-snippet/CardWithChildren.test.svelte new file mode 100644 index 0000000..fc65c5a --- /dev/null +++ b/tests/children-snippet/CardWithChildren.test.svelte @@ -0,0 +1,8 @@ + + + +

Hello World

+ Multiple elements +
diff --git a/tests/children-snippet/CardWithHeader.test.svelte b/tests/children-snippet/CardWithHeader.test.svelte new file mode 100644 index 0000000..1faafb1 --- /dev/null +++ b/tests/children-snippet/CardWithHeader.test.svelte @@ -0,0 +1,11 @@ + + + + {#snippet header()} + Card Title + {/snippet} + + Card body content + diff --git a/tests/children-snippet/CardWithoutHeader.test.svelte b/tests/children-snippet/CardWithoutHeader.test.svelte new file mode 100644 index 0000000..d28fac0 --- /dev/null +++ b/tests/children-snippet/CardWithoutHeader.test.svelte @@ -0,0 +1,7 @@ + + + + Just content + diff --git a/tests/children-snippet/Component.svelte b/tests/children-snippet/Component.svelte new file mode 100644 index 0000000..5b99cdd --- /dev/null +++ b/tests/children-snippet/Component.svelte @@ -0,0 +1,35 @@ + + + + +
+ {#if header} +
+ {@render header()} +
+ {/if} +
+ {@render children()} +
+
+ + diff --git a/tests/children-snippet/Reference.svelte b/tests/children-snippet/Reference.svelte new file mode 100644 index 0000000..5b99cdd --- /dev/null +++ b/tests/children-snippet/Reference.svelte @@ -0,0 +1,35 @@ + + + + +
+ {#if header} +
+ {@render header()} +
+ {/if} +
+ {@render children()} +
+
+ + diff --git a/tests/children-snippet/prompt.md b/tests/children-snippet/prompt.md new file mode 100644 index 0000000..0c14844 --- /dev/null +++ b/tests/children-snippet/prompt.md @@ -0,0 +1,5 @@ +# Card Component Task + +Create a Svelte 5 Card component that uses the children snippet pattern. + +The component should render any content passed to it inside a styled card wrapper. Use `$props` to destructure the `children` snippet and render it with `{@render children()}`. Optionally accept a `header` snippet prop that renders above the main content when provided. diff --git a/tests/children-snippet/test.ts b/tests/children-snippet/test.ts new file mode 100644 index 0000000..7d7f1d2 --- /dev/null +++ b/tests/children-snippet/test.ts @@ -0,0 +1,51 @@ +import { render, screen } from "@testing-library/svelte"; +import { expect, test, describe } from "vitest"; +import Card from "./Component.svelte"; + +// Helper component that uses the Card with children content +import CardWithChildren from "./CardWithChildren.test.svelte"; +import CardWithHeader from "./CardWithHeader.test.svelte"; +import CardWithoutHeader from "./CardWithoutHeader.test.svelte"; + +describe("Card component with children snippet", () => { + test("renders children content", () => { + render(CardWithChildren); + + const card = screen.getByTestId("card"); + const content = screen.getByTestId("card-content"); + + expect(card).toBeInTheDocument(); + expect(content).toBeInTheDocument(); + expect(content).toHaveTextContent("Hello World"); + }); + + test("renders header when provided", () => { + render(CardWithHeader); + + const header = screen.getByTestId("card-header"); + const content = screen.getByTestId("card-content"); + + expect(header).toBeInTheDocument(); + expect(header).toHaveTextContent("Card Title"); + expect(content).toHaveTextContent("Card body content"); + }); + + test("does not render header when not provided", () => { + render(CardWithoutHeader); + + const header = screen.queryByTestId("card-header"); + const content = screen.getByTestId("card-content"); + + expect(header).not.toBeInTheDocument(); + expect(content).toBeInTheDocument(); + expect(content).toHaveTextContent("Just content"); + }); + + test("renders multiple children elements", () => { + render(CardWithChildren); + + const content = screen.getByTestId("card-content"); + expect(content.querySelector("p")).toBeInTheDocument(); + expect(content.querySelector("span")).toBeInTheDocument(); + }); +}); diff --git a/tests/state-class/Component.svelte b/tests/state-class/Component.svelte new file mode 100644 index 0000000..72b9c82 --- /dev/null +++ b/tests/state-class/Component.svelte @@ -0,0 +1,57 @@ + + + + +
+ + {counter.count} + + +
+ + diff --git a/tests/state-class/Reference.svelte b/tests/state-class/Reference.svelte new file mode 100644 index 0000000..72b9c82 --- /dev/null +++ b/tests/state-class/Reference.svelte @@ -0,0 +1,57 @@ + + + + +
+ + {counter.count} + + +
+ + diff --git a/tests/state-class/prompt.md b/tests/state-class/prompt.md new file mode 100644 index 0000000..c510946 --- /dev/null +++ b/tests/state-class/prompt.md @@ -0,0 +1,11 @@ +# Reactive Class Counter Task + +Create a Svelte 5 component that uses a reactive class for state management. + +Define a Counter class with: +- A `count` field using `$state` initialized to 0 +- An `increment()` method that increases count by 1 +- A `decrement()` method that decreases count by 1 +- A `reset()` method that sets count back to 0 + +Instantiate the class and use it to build a counter UI with buttons for each action. diff --git a/tests/state-class/test.ts b/tests/state-class/test.ts new file mode 100644 index 0000000..8a9d799 --- /dev/null +++ b/tests/state-class/test.ts @@ -0,0 +1,87 @@ +import { render, screen } from "@testing-library/svelte"; +import { expect, test, describe } from "vitest"; +import userEvent from "@testing-library/user-event"; +import Counter from "./Component.svelte"; + +describe("Counter component with reactive class", () => { + test("renders with initial count of 0", () => { + render(Counter); + + const countElement = screen.getByTestId("count-value"); + expect(countElement).toHaveTextContent("0"); + }); + + test("increments count when + is clicked", async () => { + const user = userEvent.setup(); + render(Counter); + + const incrementButton = screen.getByTestId("increment-button"); + const countElement = screen.getByTestId("count-value"); + + await user.click(incrementButton); + expect(countElement).toHaveTextContent("1"); + + await user.click(incrementButton); + expect(countElement).toHaveTextContent("2"); + }); + + test("decrements count when - is clicked", async () => { + const user = userEvent.setup(); + render(Counter); + + const decrementButton = screen.getByTestId("decrement-button"); + const countElement = screen.getByTestId("count-value"); + + await user.click(decrementButton); + expect(countElement).toHaveTextContent("-1"); + + await user.click(decrementButton); + expect(countElement).toHaveTextContent("-2"); + }); + + test("resets count when reset is clicked", async () => { + const user = userEvent.setup(); + render(Counter); + + const incrementButton = screen.getByTestId("increment-button"); + const resetButton = screen.getByTestId("reset-button"); + const countElement = screen.getByTestId("count-value"); + + // Increment a few times + await user.click(incrementButton); + await user.click(incrementButton); + await user.click(incrementButton); + expect(countElement).toHaveTextContent("3"); + + // Reset + await user.click(resetButton); + expect(countElement).toHaveTextContent("0"); + }); + + test("reset works after decrementing", async () => { + const user = userEvent.setup(); + render(Counter); + + const decrementButton = screen.getByTestId("decrement-button"); + const resetButton = screen.getByTestId("reset-button"); + const countElement = screen.getByTestId("count-value"); + + // Decrement + await user.click(decrementButton); + await user.click(decrementButton); + expect(countElement).toHaveTextContent("-2"); + + // Reset should go back to 0 + await user.click(resetButton); + expect(countElement).toHaveTextContent("0"); + }); + + test("all buttons are present", () => { + render(Counter); + + expect(screen.getByTestId("increment-button")).toBeInTheDocument(); + expect(screen.getByTestId("decrement-button")).toBeInTheDocument(); + expect(screen.getByTestId("reset-button")).toBeInTheDocument(); + expect(screen.getByTestId("count-value")).toBeInTheDocument(); + }); +});