11import { render , screen , fireEvent } from '@testing-library/react' ;
22import { describe , it , expect , vi } from 'vitest' ;
33import { AddTodo } from '../add-todo' ;
4+ import { createMemoryRouter , RouterProvider } from 'react-router-dom' ;
5+
6+ function renderWithRouter ( ui : React . ReactElement ) {
7+ const router = createMemoryRouter ( [
8+ { path : '/' , element : ui }
9+ ] , { initialEntries : [ '/' ] } ) ;
10+ return render ( < RouterProvider router = { router } /> ) ;
11+ }
12+
13+ // hoist regex literals to top-level to satisfy biome's useTopLevelRegex
14+ const ADD_REGEX = / a d d / i;
415
516// hoist regex literals to top-level to satisfy biome's useTopLevelRegex
617const ADD_REGEX = / a d d / i;
718
819describe ( 'AddTodo' , ( ) => {
920 it ( 'renders input and button' , ( ) => {
1021 const mockOnAdd = vi . fn ( ) ;
11- render ( < AddTodo onAdd = { mockOnAdd } /> ) ;
12-
22+ renderWithRouter ( < AddTodo onAdd = { mockOnAdd } /> ) ;
23+
1324 expect ( screen . getByPlaceholderText ( 'Add a new todo...' ) ) . toBeInTheDocument ( ) ;
1425 expect ( screen . getByRole ( 'button' , { name : ADD_REGEX } ) ) . toBeInTheDocument ( ) ;
1526 } ) ;
1627
1728 it ( 'calls onAdd when form is submitted with text' , ( ) => {
1829 const mockOnAdd = vi . fn ( ) ;
19- render ( < AddTodo onAdd = { mockOnAdd } /> ) ;
20-
30+ renderWithRouter ( < AddTodo onAdd = { mockOnAdd } /> ) ;
31+
2132 const input = screen . getByPlaceholderText ( 'Add a new todo...' ) ;
2233 const button = screen . getByRole ( 'button' , { name : ADD_REGEX } ) ;
2334
2435 fireEvent . change ( input , { target : { value : 'New todo' } } ) ;
2536 fireEvent . click ( button ) ;
26-
37+
2738 expect ( mockOnAdd ) . toHaveBeenCalledWith ( 'New todo' ) ;
2839 } ) ;
2940
3041 it ( 'clears input after adding todo' , ( ) => {
3142 const mockOnAdd = vi . fn ( ) ;
32- render ( < AddTodo onAdd = { mockOnAdd } /> ) ;
33-
43+ renderWithRouter ( < AddTodo onAdd = { mockOnAdd } /> ) ;
44+
3445 const input = screen . getByPlaceholderText ( 'Add a new todo...' ) as HTMLInputElement ;
3546 const button = screen . getByRole ( 'button' , { name : ADD_REGEX } ) ;
3647
3748 fireEvent . change ( input , { target : { value : 'New todo' } } ) ;
3849 fireEvent . click ( button ) ;
39-
50+
4051 expect ( input . value ) . toBe ( '' ) ;
4152 } ) ;
4253
@@ -46,20 +57,20 @@ describe('AddTodo', () => {
4657
4758 const button = screen . getByRole ( 'button' , { name : ADD_REGEX } ) ;
4859 fireEvent . click ( button ) ;
49-
60+
5061 expect ( mockOnAdd ) . not . toHaveBeenCalled ( ) ;
5162 } ) ;
5263
5364 it ( 'trims whitespace from input' , ( ) => {
5465 const mockOnAdd = vi . fn ( ) ;
55- render ( < AddTodo onAdd = { mockOnAdd } /> ) ;
56-
66+ renderWithRouter ( < AddTodo onAdd = { mockOnAdd } /> ) ;
67+
5768 const input = screen . getByPlaceholderText ( 'Add a new todo...' ) ;
5869 const button = screen . getByRole ( 'button' , { name : ADD_REGEX } ) ;
5970
6071 fireEvent . change ( input , { target : { value : ' New todo ' } } ) ;
6172 fireEvent . click ( button ) ;
62-
73+
6374 expect ( mockOnAdd ) . toHaveBeenCalledWith ( 'New todo' ) ;
6475 } ) ;
6576} ) ;
0 commit comments