Skip to content

Commit

Permalink
tests: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nahoc committed May 7, 2024
1 parent d4f5323 commit 5f02d5d
Show file tree
Hide file tree
Showing 18 changed files with 238 additions and 84 deletions.
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ tsconfig.tsbuildinfo
*.test.*
*.spec.*
vitest.config.ts
setupTests.ts
setupTests.ts
coverage
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Building blocks for UI applications at RISC Zero.
>
> When making code changes, please have the [Biome VSCode extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) installed.
### Tests
### 🧪 Tests Coverage

All test files named with the pattern `*.spec.*` are ran using `bun test` while all files named `*.test.*` are ran through `vitest`.
```md
| Statements | Branches | Functions | Lines |
| --------------------------- | ----------------------- | ------------------------- | ----------------- |
| ![Statements](https://img.shields.io/badge/statements-19.05%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-58.18%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-33.33%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-19.05%25-red.svg?style=flat) |
```
37 changes: 37 additions & 0 deletions avatar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { render, screen } from '@testing-library/react';
import { createRef } from 'react';
import { Avatar, AvatarFallback } from './avatar';

describe('Avatar', () => {
test('renders without crashing', () => {
render(<Avatar />);
const avatarElement = screen.getByTestId('avatar');
expect(avatarElement).toBeInTheDocument();
});

test('forwards ref correctly', () => {
const ref = createRef<HTMLSpanElement>();
render(<Avatar ref={ref} />);
expect(ref.current).not.toBeNull();
});
});

describe('AvatarFallback', () => {
test('renders without crashing', () => {
render(<Avatar><AvatarFallback /></Avatar>);
const avatarFallbackElement = screen.getByTestId('avatar-fallback');
expect(avatarFallbackElement).toBeInTheDocument();
});

test('forwards ref correctly', () => {
const ref = createRef<HTMLSpanElement>();
render(<Avatar><AvatarFallback ref={ref} /></Avatar>);
expect(ref.current).not.toBeNull();
});

test('displays the initials inside', () => {
render(<Avatar><AvatarFallback>CC</AvatarFallback></Avatar>);
const avatarFallbackText = screen.getByText('CC');
expect(avatarFallbackText).toBeInTheDocument();
});
});
2 changes: 2 additions & 0 deletions avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const Avatar = forwardRef<
>(({ className, ...rest }, ref) => (
<AvatarPrimitive.Root
ref={ref}
data-testid="avatar"
className={cn("relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full", className)}
{...rest}
/>
Expand All @@ -28,6 +29,7 @@ const AvatarFallback = forwardRef<
>(({ className, ...rest }, ref) => (
<AvatarPrimitive.Fallback
ref={ref}
data-testid="avatar-fallback"
className={cn("flex h-full w-full items-center justify-center rounded-full bg-muted", className)}
{...rest}
/>
Expand Down
22 changes: 22 additions & 0 deletions badge.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { render, screen } from '@testing-library/react';
import { Badge } from './badge';

describe('Badge', () => {
test('renders without crashing', () => {
render(<Badge />);
const badgeElement = screen.getByTestId('badge');
expect(badgeElement).toBeInTheDocument();
});

test('applies correct classes based on variant prop', () => {
render(<Badge variant="secondary" />);
const badgeElement = screen.getByTestId('badge');
expect(badgeElement).toHaveClass('border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80');
});

test('forwards additional props to rendered div element', () => {
render(<Badge data-testid="badge" />);
const badgeElement = screen.getByTestId('badge');
expect(badgeElement).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export interface BadgeProps extends HTMLAttributes<HTMLDivElement>, VariantProps
}

function Badge({ className, variant, ...rest }: BadgeProps) {
return <div className={cn(badgeVariants({ variant }), className)} {...rest} />;
return <div data-testid="badge" className={cn(badgeVariants({ variant }), className)} {...rest} />;
}

export { Badge, badgeVariants };
29 changes: 29 additions & 0 deletions checkbox.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { render, screen } from '@testing-library/react';
import { Checkbox } from './checkbox';
import { createRef } from 'react';

describe('Checkbox', () => {
test('renders without crashing', () => {
render(<Checkbox />);
const checkboxElement = screen.getByRole('checkbox');
expect(checkboxElement).toBeInTheDocument();
});

test('forwards ref correctly', () => {
const ref = createRef<HTMLButtonElement>();
render(<Checkbox ref={ref} />);
expect(ref.current).not.toBeNull();
});

test('applies correct class names', () => {
render(<Checkbox className="test-class" />);
const checkboxElement = screen.getByRole('checkbox');
expect(checkboxElement).toHaveClass('test-class');
});

test('renders CheckIcon when checked', () => {
render(<Checkbox checked />);
const checkIconElement = screen.getByTestId('check-icon');
expect(checkIconElement).toBeInTheDocument();
});
});
2 changes: 1 addition & 1 deletion checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Checkbox = forwardRef<
{...rest}
>
<CheckboxPrimitive.Indicator className={cn("flex items-center justify-center text-current")}>
<CheckIcon className="size-3" />
<CheckIcon data-testid="check-icon" className="size-3" />
</CheckboxPrimitive.Indicator>
</CheckboxPrimitive.Root>
));
Expand Down
13 changes: 13 additions & 0 deletions constants.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { RISC0_PRIVACY_POLICY_URL, RISC0_TERMS_OF_SERVICE_URL } from './constants';

describe('Constants', () => {
it('should have correct RISC0_PRIVACY_POLICY_URL', () => {
expect(typeof RISC0_PRIVACY_POLICY_URL).toBe('string');
expect(RISC0_PRIVACY_POLICY_URL).toBe('https://www.risczero.com/policy');
});

it('should have correct RISC0_TERMS_OF_SERVICE_URL', () => {
expect(typeof RISC0_TERMS_OF_SERVICE_URL).toBe('string');
expect(RISC0_TERMS_OF_SERVICE_URL).toBe('https://www.risczero.com/terms-of-service');
});
});
72 changes: 70 additions & 2 deletions hooks/use-event-listener.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { renderHook } from '@testing-library/react-hooks';
import type { RefObject } from 'react';
import { renderHook, act } from '@testing-library/react-hooks';
import { useRef, type RefObject } from 'react';
import { useEventListener } from './use-event-listener';
import { vi } from 'vitest';

Expand Down Expand Up @@ -29,4 +29,72 @@ describe('useEventListener', () => {

expect(handler).not.toHaveBeenCalled();
});

it('adds event listener to window when no element is provided', () => {
const handler = vi.fn();
const { unmount } = renderHook(() => useEventListener('click', handler));

act(() => {
window.dispatchEvent(new Event('click'));
});

expect(handler).toHaveBeenCalled();

unmount();
});

it('adds event listener to provided element', () => {
const handler = vi.fn();
const { result, unmount } = renderHook(() => {
const ref = useRef<HTMLDivElement>(document.createElement('div'));
useEventListener('click', handler, ref);
return ref;
});

act(() => {
result.current?.current?.dispatchEvent(new Event('click'));
});

expect(handler).toHaveBeenCalled();

unmount();
});

it('removes event listener when component unmounts', () => {
const handler = vi.fn();
const { unmount } = renderHook(() => useEventListener('click', handler));

unmount();

act(() => {
window.dispatchEvent(new Event('click'));
});

expect(handler).not.toHaveBeenCalled();
});

it('updates event listener when handler changes', () => {
const handler1 = vi.fn();
const handler2 = vi.fn();
const { rerender, unmount } = renderHook(
({ handler }) => useEventListener('click', handler),
{ initialProps: { handler: handler1 } }
);

act(() => {
window.dispatchEvent(new Event('click'));
});

expect(handler1).toHaveBeenCalled();

rerender({ handler: handler2 });

act(() => {
window.dispatchEvent(new Event('click'));
});

expect(handler2).toHaveBeenCalled();

unmount();
});
});
74 changes: 0 additions & 74 deletions hooks/use-local-storage.test.ts

This file was deleted.

31 changes: 31 additions & 0 deletions input.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { render, screen } from '@testing-library/react';
import { Input } from './input';
import { createRef } from 'react';

describe('Input', () => {
test('renders without crashing', () => {
render(<Input />);
const inputElement = screen.getByRole('textbox');
expect(inputElement).toBeInTheDocument();
});

test('forwards ref correctly', () => {
const ref = createRef<HTMLInputElement>();
render(<Input ref={ref} />);
expect(ref.current).not.toBeNull();
});

test('renders startIcon correctly', () => {
const StartIcon = () => <div data-testid="start-icon"></div>;
render(<Input startIcon={<StartIcon />} />);
const startIconElement = screen.getByTestId('start-icon');
expect(startIconElement).toBeInTheDocument();
});

test('renders endIcon correctly', () => {
const EndIcon = () => <div data-testid="end-icon"></div>;
render(<Input endIcon={<EndIcon />} />);
const endIconElement = screen.getByTestId('end-icon');
expect(endIconElement).toBeInTheDocument();
});
});
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@risc0/ui",
"version": "0.0.67",
"version": "0.0.68",
"sideEffects": false,
"type": "module",
"scripts": {
"bump:version": "bunx changelogen --bump --no-output",
"check": "tsc && bunx @biomejs/biome check . --apply-unsafe",
"prepare": "npx husky",
"sort-package": "bunx sort-package-json 'package.json'",
"test": "bun test spec && vitest run --silent"
"test": "vitest run --silent --coverage && istanbul-badges-readme"
},
"dependencies": {
"@radix-ui/react-avatar": "1.0.4",
Expand Down Expand Up @@ -50,7 +50,9 @@
"@types/jest": "29.5.12",
"@types/lodash-es": "4.17.12",
"@vitejs/plugin-react-swc": "3.6.0",
"@vitest/coverage-v8": "1.6.0",
"happy-dom": "14.10.1",
"istanbul-badges-readme": "1.9.0",
"vitest": "1.6.0"
},
"peerDependencies": {
Expand Down
Loading

0 comments on commit 5f02d5d

Please sign in to comment.