Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add testing for applications in docs #13

Merged
merged 4 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Run Unit Tests
name: 🌚 Run Unit Tests

on:
push:
Expand Down
1 change: 1 addition & 0 deletions apps/docs/components/accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function Accordion(): JSX.Element {
>
<button
type="button"
data-testid="accordion-button"
style={{
fontSize: "1.1em",
fontWeight: 500,
Expand Down
6 changes: 2 additions & 4 deletions apps/docs/components/search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export function Search(): JSX.Element {
Search Books
</label>
<input
data-testid="search-input"
id="searchInput"
placeholder="Harry Potter"
type="text"
Expand All @@ -146,10 +147,7 @@ export function Search(): JSX.Element {
>
{books
.filter(({ title }) =>
title
.toLowerCase()
.trim()
.includes(searchText.toLowerCase().trim()),
title.toLowerCase().trim().includes(searchText.toLowerCase().trim())
)
.map(({ id, title, imgSrc }) => (
<Book key={id} title={title} imgSrc={imgSrc} />
Expand Down
14 changes: 12 additions & 2 deletions apps/docs/components/todo-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ function shuffle<T>(array: T[]): T[] {
}

function TodoListItem({
testId,
todo,
setTodos,
}: {
testId: string;
todo: { id: string; text: string };
setTodos: Dispatch<SetStateAction<{ id: string; text: string }[]>>;
}): JSX.Element {
Expand All @@ -42,6 +44,7 @@ function TodoListItem({
type="button"
title="Delete this item"
className="nx-bg-black/[.02]"
data-testid={`${testId }-delete-button`}
onClick={() =>
setTodos((todos) => todos.filter((t) => t.id !== todo.id))
}
Expand Down Expand Up @@ -81,8 +84,13 @@ export function TodoList(): JSX.Element {
overflow: "hidden",
}}
>
{todos.map((todo) => (
<TodoListItem key={todo.id} todo={todo} setTodos={setTodos} />
{todos.map((todo, i) => (
<TodoListItem
testId={`todo-${i}`}
key={todo.id}
todo={todo}
setTodos={setTodos}
/>
))}
</ul>
<form
Expand All @@ -92,6 +100,7 @@ export function TodoList(): JSX.Element {
<input
ref={newTodoInput}
type="text"
data-testid="add-todo-input"
placeholder="Write a new todo 📝"
className="nx-bg-black/[.05] dark:nx-bg-gray-50/10"
style={{
Expand All @@ -104,6 +113,7 @@ export function TodoList(): JSX.Element {

<button
type="submit"
data-testid="add-todo-button"
title="Add a new todo"
style={{
whiteSpace: "nowrap",
Expand Down
4 changes: 3 additions & 1 deletion apps/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
"dev": "next dev --port 3001",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"test": "vitest run",
"test:watch": "vitest"
},
"dependencies": {
"@vercel/analytics": "^1.1.1",
Expand Down
100 changes: 100 additions & 0 deletions apps/docs/tests/components.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
act,
fireEvent,
getByTestId,
render,
waitFor,
} from "@testing-library/react";
import { describe, test, expect, beforeAll, vi } from "vitest";
import { TodoList } from "../components/todo-list";
import "@testing-library/jest-dom";
import { MagicMotion } from "../../../packages/react-magic-motion/magic-motion";
import { Accordion } from "../components/accordion";
import { Search } from "../components/search";

describe("Application Tests", () => {
beforeAll(() => {
Object.defineProperty(window, "matchMedia", {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: true,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
});
test("to do list component", async () => {
const { container } = render(
<MagicMotion>
<TodoList />
</MagicMotion>
);
expect(container).toHaveTextContent("🐕 Walk the dog");
expect(container).toHaveTextContent("🍔 Eat lunch");
expect(container).toHaveTextContent("📚 Study react");
expect(container).toHaveTextContent("🏀 Play basketball");
expect(container).toHaveTextContent("🔎 Study biology");
expect(container).toHaveTextContent("👟 Buy shoes");

const thirdDeleteButton = getByTestId(container, "todo-2-delete-button");
act(() => {
thirdDeleteButton.click();
});
await waitFor(() => {
expect(container).not.toHaveTextContent("📚 Study react");
});
const todoInput = getByTestId(container, "add-todo-input");
fireEvent.change(todoInput, { target: { value: "New To Do Item" } });
const todoSubmitButton = getByTestId(container, "add-todo-button");
act(() => {
todoSubmitButton.click();
});
await waitFor(() => {
expect(container).toHaveTextContent("New To Do Item");
});
});

test("accordion component", async () => {
const { container } = render(
<MagicMotion>
<Accordion />
</MagicMotion>
);
expect(container).toHaveTextContent("Click me to see my content");
expect(container).not.toHaveTextContent(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed gravida lobortis sem, vel blandit dolor ultrices nec. Donec dapibus tellus ut libero sagittis, a pharetra eros placerat. Aliquam erat volutpat. Nunc nec nisl ac turpis semper pharetra. Nullam pulvinar pellentesque mauris, sit amet tincidunt nisl convallis id."
);

const accordionButton = getByTestId(container, "accordion-button");
act(() => {
accordionButton.click();
});
await waitFor(() => {
expect(container).toHaveTextContent(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed gravida lobortis sem, vel blandit dolor ultrices nec. Donec dapibus tellus ut libero sagittis, a pharetra eros placerat. Aliquam erat volutpat. Nunc nec nisl ac turpis semper pharetra. Nullam pulvinar pellentesque mauris, sit amet tincidunt nisl convallis id."
);
});
});
test("search component", async () => {
const { container } = render(
<MagicMotion>
<Search />
</MagicMotion>
);
expect(container).toHaveTextContent("Dune");
expect(container).toHaveTextContent("Foundation");
expect(container).toHaveTextContent("Gone Girl");
const searchInput = getByTestId(container, "search-input");
fireEvent.change(searchInput, { target: { value: "Dune" } });
await waitFor(() => {
expect(container).toHaveTextContent("Dune");
expect(container).not.toHaveTextContent("Foundation");
expect(container).not.toHaveTextContent("Gone Girl");
});
});
});
1 change: 1 addition & 0 deletions apps/web/app/layout-container/toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function Toggle({
<button
onClick={() => setIsActive((prev) => !prev)}
className="toggle-button"
type="button"
style={{
display: "flex",
justifyContent: isActive ? "flex-end" : "flex-start",
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@
"format": "prettier --write \"**/*.{ts,tsx,md}\""
},
"devDependencies": {
"@babel/traverse": ">=7.23.2",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0",
"@vitejs/plugin-react": "^4.1.1",
"eslint": "^8.48.0",
"jsdom": "^22.1.0",
"prettier": "^3.0.3",
"tsconfig": "workspace:*",
"turbo": "^1.10.13",
"@babel/traverse": ">=7.23.2"
"vitest": "^0.34.6"
},
"packageManager": "[email protected]",
"name": "react-magic-motion",
Expand Down
11 changes: 10 additions & 1 deletion packages/react-magic-motion/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,16 @@ module.exports = {
files: ["*.test.tsx"],
"rules": {
"@typescript-eslint/no-unsafe-assignment" : 'off',
"@typescript-eslint/no-unsafe-call": "off"
"@typescript-eslint/no-unsafe-call": "off",
'import/no-extraneous-dependencies': [
1,
{
devDependencies: true,
includeInternal: false,
includeTypes: false,
packageDir: ['.', '../..'], // <--- the key addition
},
],
}
}
]
Expand Down
6 changes: 1 addition & 5 deletions packages/react-magic-motion/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,17 @@
"typescript"
],
"devDependencies": {
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.0.0",
"@turbo/gen": "^1.10.12",
"@types/node": "^20.5.2",
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/react-is": "^18.2.1",
"eslint-config-custom": "workspace:*",
"jsdom": "^22.1.0",
"react": "^18.2.0",
"react-is": "^18.2.0",
"tsconfig": "workspace:*",
"tsup": "^7.2.0",
"typescript": "^4.5.2",
"vitest": "^0.34.6"
"typescript": "^4.5.2"
},
"dependencies": {
"framer-motion": "^10.16.2"
Expand Down
14 changes: 12 additions & 2 deletions packages/react-magic-motion/tests/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type ReactNode, forwardRef, useRef } from "react";
import { forwardRef, useRef, cloneElement } from "react";
import type { ReactElement, ReactNode } from "react";

export function TestComponent({
customText,
Expand All @@ -15,7 +16,7 @@ export function ParentComponent(): JSX.Element {
}

interface ForwardedRefComponent {
children?: React.ReactNode;
children?: ReactNode;
}

const ForwardedRefComponent = forwardRef<
Expand All @@ -38,3 +39,12 @@ export function ForwardedRefParent(): JSX.Element {
<ForwardedRefComponent ref={buttonRef}>Click me!</ForwardedRefComponent>
);
}

export function cloneRootElem(rootElem: ReactElement): ReactNode {
return cloneElement(rootElem, {
...rootElem.props,
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
});
}
11 changes: 2 additions & 9 deletions packages/react-magic-motion/tests/magic-exit.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import "@testing-library/jest-dom";
import { describe, beforeAll, vi, test, expect } from "vitest";
import { cloneElement } from "react";
import { convertChildrenToMotionChildren } from "../utils/magic-animation";
import { cloneRootElem } from ".";

describe("<MagicExit> tests", () => {
beforeAll(() => {
Expand Down Expand Up @@ -34,13 +33,7 @@ describe("<MagicExit> tests", () => {
{
isRootNode: true,
rootNodeCallback: (rootElem) => {
const clonedRootElem = cloneElement(rootElem, {
...rootElem.props,
initial: { opacity: 0 },
animate: { opacity: 1 },
exit: { opacity: 0 },
});
return clonedRootElem;
return cloneRootElem(rootElem);
},
depth: 1,
}
Expand Down
2 changes: 1 addition & 1 deletion packages/react-magic-motion/utils/magic-animation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export function convertChildrenToMotionChildren(
}

// Checks if the child is a function component
let parent = null;
let parent:ReactNode = null;
while (typeof node.type === "function") {
if (isLoggingEnabled)
logSuccess(FUNCTIONCOMPONENTMESSAGE(node.type.name));
Expand Down
Loading