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 5f02d5d commit 9b8fc17
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 11 deletions.
11 changes: 4 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@

Building blocks for UI applications at RISC Zero.

#### Before You Start
#### Prerequisites

- Install [Node](https://nodejs.org/en) (≥ v20.x.x)
- Install [bun](https://bun.sh/) (≥ v1.0.33)

> #### General
>
> [!TIP]
> When making code changes, please have the [Biome VSCode extension](https://marketplace.visualstudio.com/items?itemName=biomejs.biome) installed.
### 🧪 Tests Coverage
### Coverage

```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) |
```
| ![Statements](https://img.shields.io/badge/statements-28.26%25-red.svg?style=flat) | ![Branches](https://img.shields.io/badge/branches-68.33%25-red.svg?style=flat) | ![Functions](https://img.shields.io/badge/functions-41.37%25-red.svg?style=flat) | ![Lines](https://img.shields.io/badge/lines-28.26%25-red.svg?style=flat) |
58 changes: 58 additions & 0 deletions alert.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { render, screen } from '@testing-library/react';
import { Alert, AlertDescription, AlertTitle } from './alert';

describe('Alert', () => {
test('returns default class names when no variant is provided', () => {
render(<Alert />);
const alertElement = screen.getByRole('alert');
expect(alertElement.className).toContain('relative w-full rounded-lg border px-4 py-3 text-sm');
expect(alertElement.className).toContain('bg-background text-foreground');
});

test('returns correct class names when destructive variant is provided', () => {
render(<Alert variant="destructive" />);
const alertElement = screen.getByRole('alert');
expect(alertElement.className).toContain('relative w-full rounded-lg border px-4 py-3 text-sm');
expect(alertElement.className).toContain('border-destructive/50 text-destructive dark:border-destructive');
});
});

describe('AlertTitle', () => {
test('renders the correct text when children prop is provided', () => {
render(<AlertTitle>Test Title</AlertTitle>);
const titleElement = screen.getByText('Test Title');
expect(titleElement).toBeInTheDocument();
});

test('has correct default class names', () => {
render(<AlertTitle>Test Title</AlertTitle>);
const titleElement = screen.getByText('Test Title');
expect(titleElement.className).toContain('mb-1 font-medium leading-none');
});

test('properly forwards classnames', () => {
render(<AlertTitle className='text-xl'>Test Title</AlertTitle>);
const titleElement = screen.getByText('Test Title');
expect(titleElement.className).toContain('text-xl');
});
});

describe('AlertDescription', () => {
test('renders the correct text when children prop is provided', () => {
render(<AlertDescription>Test Description</AlertDescription>);
const descriptionElement = screen.getByText('Test Description');
expect(descriptionElement).toBeInTheDocument();
});

test('has correct default class names', () => {
render(<AlertDescription>Test Description</AlertDescription>);
const descriptionElement = screen.getByText('Test Description');
expect(descriptionElement.className).toContain('text-sm [&_p]:leading-relaxed');
});

test('properly forwards classnames', () => {
render(<AlertDescription className='text-xl'>Test Description</AlertDescription>);
const descriptionElement = screen.getByText('Test Description');
expect(descriptionElement.className).toContain('text-xl');
});
});
50 changes: 50 additions & 0 deletions button.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { render, screen } from '@testing-library/react';
import { Button } from './button';
import { createRef } from 'react';

describe('Button', () => {
test('renders without crashing', () => {
render(<Button />);
const buttonElement = screen.getByRole('button');
expect(buttonElement).toBeInTheDocument();
});

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

test('renders children correctly', () => {
render(<Button>Test Button</Button>);
const buttonElement = screen.getByText('Test Button');
expect(buttonElement).toBeInTheDocument();
});

test('renders startIcon correctly', () => {
const Icon = () => <span data-testid="start-icon"></span>;
render(<Button startIcon={<Icon />} />);
const iconElement = screen.getByTestId('start-icon');
expect(iconElement).toBeInTheDocument();
});

test('renders endIcon correctly', () => {
const Icon = () => <span data-testid="end-icon"></span>;
render(<Button endIcon={<Icon />} />);
const iconElement = screen.getByTestId('end-icon');
expect(iconElement).toBeInTheDocument();
});

test('renders Loader2Icon when isLoading is true', () => {
render(<Button isLoading />);
const loaderElement = screen.getByTestId('loader-icon');
expect(loaderElement).toBeInTheDocument();
});

test('reanders Loader2Icon, but hidden when isLoading is false', () => {
render(<Button isLoading={false} />);
const loaderElement = screen.getByTestId('loader-icon');
expect(loaderElement).toBeInTheDocument();
expect(loaderElement).toHaveClass("opacity-0")
});
});
1 change: 1 addition & 0 deletions button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
return (
<Component className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...rest}>
<Loader2Icon
data-testid="loader-icon"
className={cn(
iconVariants({}),
"animate-spin",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@risc0/ui",
"version": "0.0.68",
"version": "0.0.69",
"sideEffects": false,
"type": "module",
"scripts": {
Expand Down
41 changes: 41 additions & 0 deletions slider.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { render, screen } from '@testing-library/react';
import { Slider } from './slider';
import { createRef } from 'react';

describe('Slider', () => {
test('renders without crashing', () => {
render(<Slider />);
const sliderElement = screen.getByRole('slider');
expect(sliderElement).toBeInTheDocument();
});

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

test('applies correct class names to root element', () => {
render(<Slider />);
const sliderElement = screen.getByTestId('slider-root');
expect(sliderElement).toHaveClass('relative flex w-full touch-none select-none items-center');
});

test('applies correct class names to Track element', () => {
render(<Slider />);
const trackElement = screen.getByTestId('slider-track');
expect(trackElement).toHaveClass('relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20');
});

test('applies correct class names to Range element', () => {
render(<Slider />);
const rangeElement = screen.getByTestId('slider-range');
expect(rangeElement).toHaveClass('absolute h-full bg-primary');
});

test('applies correct class names to Thumb element', () => {
render(<Slider />);
const thumbElement = screen.getByTestId('slider-thumb');
expect(thumbElement).toHaveClass('block size-4 rounded-full border border-primary/50 bg-background shadow transition-colors disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring');
});
});
13 changes: 10 additions & 3 deletions slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ const Slider = forwardRef<
>(({ className, ...rest }, ref) => (
<SliderPrimitive.Root
ref={ref}
data-testid="slider-root"
className={cn("relative flex w-full touch-none select-none items-center", className)}
{...rest}
>
<SliderPrimitive.Track className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20">
<SliderPrimitive.Range className="absolute h-full bg-primary" />
<SliderPrimitive.Track
data-testid="slider-track"
className="relative h-1.5 w-full grow overflow-hidden rounded-full bg-primary/20"
>
<SliderPrimitive.Range data-testid="slider-range" className="absolute h-full bg-primary" />
</SliderPrimitive.Track>
<SliderPrimitive.Thumb className="block size-4 rounded-full border border-primary/50 bg-background shadow transition-colors disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring" />
<SliderPrimitive.Thumb
data-testid="slider-thumb"
className="block size-4 rounded-full border border-primary/50 bg-background shadow transition-colors disabled:pointer-events-none disabled:opacity-50 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
/>
</SliderPrimitive.Root>
));

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

describe('Switch', () => {
test('renders without crashing', () => {
render(<Switch />);
const switchElement = screen.getByRole('switch');
expect(switchElement).toBeInTheDocument();
});

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

test('applies correct class names based on state', () => {
render(<Switch />);
const switchElement = screen.getByRole('switch');
expect(switchElement).toHaveClass('peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors disabled:cursor-not-allowed data-[state=checked]:bg-primary data-[state=unchecked]:bg-input disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background');
});
});
17 changes: 17 additions & 0 deletions utils/sleep.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { sleep } from './sleep';

describe('sleep function', () => {
it('should return a Promise', () => {
expect(sleep(10)).toBeInstanceOf(Promise);
});

it('should resolve after specified time', async () => {
const time = 10;
const promise = sleep(time);

// Advance timers
global.performance.now = () => time;

await expect(promise).resolves.toBeUndefined();
});
});

0 comments on commit 9b8fc17

Please sign in to comment.