Skip to content

Commit 9490a7e

Browse files
committed
add more tests
1 parent 89c64c6 commit 9490a7e

File tree

14 files changed

+163
-7
lines changed

14 files changed

+163
-7
lines changed

exercises/03.custom-hooks/01.problem.function/README.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ For the types of that tuple, you may find this article helpful:
2929
going!
3030
</callout-info>
3131

32+
<callout-info class="aside">
33+
🚨 this is just a refactor so the tests are passing already, you just need to
34+
make sure they don't fail!
35+
</callout-info>
36+
3237
Good luck!

exercises/03.custom-hooks/01.problem.function/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { setGlobalSearchParams } from '#shared/utils'
1010
const getQueryParam = (params: URLSearchParams) => params.get('query') ?? ''
1111

1212
// 🐨 create a function called useSearchParams here and move much of what's
13-
// below into this hook
13+
// below into this hook.
1414

1515
function App() {
1616
// 🐨 move everything from here to the next 🐨 into the new function
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect, testStep, dtl } from '@epic-web/workshop-utils/test'
2+
const { screen, fireEvent } = dtl
3+
4+
window.history.pushState({}, '', '?query=dog')
5+
6+
await import('./index.tsx')
7+
8+
await testStep(
9+
'The search box is initialized with URL query parameter',
10+
async () => {
11+
const searchBox = await screen.findByRole('searchbox', { name: /search/i })
12+
expect(searchBox).toHaveValue('dog')
13+
},
14+
)
15+
16+
await testStep(
17+
'Updating the search box updates the URL search params',
18+
async () => {
19+
const searchBox = screen.getByRole('searchbox', { name: /search/i })
20+
fireEvent.change(searchBox, { target: { value: 'cat' } })
21+
22+
expect(searchBox).toHaveValue('cat')
23+
expect(window.location.search).toBe('?query=cat')
24+
},
25+
)

exercises/03.custom-hooks/02.problem.callback/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { setGlobalSearchParams } from '#shared/utils'
99

1010
const getQueryParam = (params: URLSearchParams) => params.get('query') ?? ''
1111

12-
function useSearchParams() {
12+
export function useSearchParams() {
1313
const [searchParams, setSearchParamsState] = useState(
1414
() => new URLSearchParams(window.location.search),
1515
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect, testStep } from '@epic-web/workshop-utils/test'
2+
import { useReducer } from 'react'
3+
import { createRoot } from 'react-dom/client'
4+
import { useSearchParams } from './index'
5+
6+
let setSearchParams: ReturnType<typeof useSearchParams>[1]
7+
let rerender: () => void
8+
function TestComponent() {
9+
const reducerTuple = useReducer((state) => state + 1, 0)
10+
const searchParamsTuple = useSearchParams()
11+
setSearchParams = searchParamsTuple[1]
12+
rerender = reducerTuple[1]
13+
return null
14+
}
15+
16+
await testStep('setSearchParams is memoized', async () => {
17+
const container = document.createElement('div')
18+
const root = createRoot(container)
19+
root.render(<TestComponent />)
20+
await new Promise((resolve) => setTimeout(resolve, 100))
21+
const firstSetSearchParams = setSearchParams
22+
rerender()
23+
await new Promise((resolve) => setTimeout(resolve, 100))
24+
expect(firstSetSearchParams).toBe(setSearchParams)
25+
})

exercises/03.custom-hooks/02.solution.callback/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { setGlobalSearchParams } from '#shared/utils'
99

1010
const getQueryParam = (params: URLSearchParams) => params.get('query') ?? ''
1111

12-
function useSearchParams() {
12+
export function useSearchParams() {
1313
const [searchParams, setSearchParamsState] = useState(
1414
() => new URLSearchParams(window.location.search),
1515
)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { expect, testStep, dtl } from '@epic-web/workshop-utils/test'
2+
const { screen, fireEvent } = dtl
3+
4+
window.history.pushState({}, '', '?query=dog')
5+
6+
await import('./index.tsx')
7+
8+
await testStep(
9+
'The search box is initialized with URL query parameter',
10+
async () => {
11+
const searchBox = await screen.findByRole('searchbox', { name: /search/i })
12+
expect(searchBox).toHaveValue('dog')
13+
},
14+
)
15+
16+
await testStep(
17+
'Updating the search box updates the URL search params',
18+
async () => {
19+
const searchBox = screen.getByRole('searchbox', { name: /search/i })
20+
fireEvent.change(searchBox, { target: { value: 'cat' } })
21+
22+
expect(searchBox).toHaveValue('cat')
23+
expect(window.location.search).toBe('?query=cat')
24+
},
25+
)

exercises/04.context/01.problem.provider/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { setGlobalSearchParams } from '#shared/utils'
1515
// [new URLSearchParams(window.location.search), setGlobalSearchParams]
1616

1717
// 🐨 change this to SearchParamsProvider and accept children
18-
function useSearchParams() {
18+
export function useSearchParams() {
1919
const [searchParams, setSearchParamsState] = useState(
2020
() => new URLSearchParams(window.location.search),
2121
)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect, testStep, dtl } from '@epic-web/workshop-utils/test'
2+
const { screen, fireEvent } = dtl
3+
4+
import './index.tsx'
5+
6+
const searchBox = await testStep(
7+
'The user can see the search box',
8+
async () => {
9+
const result = await screen.findByRole('searchbox', { name: /search/i })
10+
expect(result).toHaveValue('')
11+
return result
12+
},
13+
)
14+
15+
const catResult = await testStep('The user can see the results', async () => {
16+
const result = screen.getByText(/caring for your feline friend/i)
17+
expect(result).toBeInTheDocument()
18+
return result
19+
})
20+
21+
await testStep('The user can search for a term', async () => {
22+
fireEvent.change(searchBox, { target: { value: 'dog' } })
23+
})
24+
25+
await testStep('The results are filtered', async () => {
26+
await dtl.waitFor(() => {
27+
expect(catResult).not.toBeInTheDocument()
28+
})
29+
await screen.findByText(/the joy of owning a dog/i)
30+
})

exercises/04.context/01.solution.provider/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function SearchParamsProvider({ children }: { children: React.ReactNode }) {
5656
)
5757
}
5858

59-
function useSearchParams() {
59+
export function useSearchParams() {
6060
return use(SearchParamsContext)
6161
}
6262

0 commit comments

Comments
 (0)