-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: added defer and useLoaderData wrappers with type support
- improved documentation
- Loading branch information
1 parent
a730ddf
commit 26b1193
Showing
5 changed files
with
157 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
/* c8 ignore start */ | ||
export * from './tests/libs/react-router'; | ||
export * from './utils/react-router'; | ||
/* c8 ignore end */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { vi, describe, it, expect } from 'vitest'; | ||
import { defer, useLoaderData } from '../react-router'; | ||
import { useLoaderData as innerUseLoaderData } from 'react-router-dom'; | ||
import { render, screen } from '@testing-library/react'; | ||
|
||
vi.mock('react-router-dom', async (importOriginal: any) => ({ | ||
...(await importOriginal()), | ||
useLoaderData: vi.fn(), | ||
})); | ||
const useLoaderDataMocked = vi.mocked(innerUseLoaderData); | ||
|
||
describe('React Router Utils', () => { | ||
describe('fn(defer)', () => { | ||
it('should map the type correctly', () => { | ||
const deferred = defer({ | ||
test: ['hello world'], | ||
other_test: 1234, | ||
}); | ||
|
||
expect(deferred.data.test).toEqual(['hello world']); | ||
expect(deferred.data.other_test).toEqual(1234); | ||
}); | ||
}); | ||
|
||
describe('fn(useLoaderData)', () => { | ||
it('should support basic data', async () => { | ||
const loader = () => ({ | ||
hello: 'world', | ||
}); | ||
|
||
useLoaderDataMocked.mockReturnValue(loader()); | ||
|
||
const MyComponent = () => { | ||
const data = useLoaderData<typeof loader>(); | ||
|
||
return data.hello; | ||
}; | ||
|
||
render(<MyComponent />); | ||
|
||
await expect(screen.findByText('world')).resolves.toBeTruthy(); | ||
}); | ||
|
||
it('should support basic promises', async () => { | ||
const loader = async () => ({ | ||
hello: await Promise.resolve('world'), | ||
}); | ||
|
||
useLoaderDataMocked.mockReturnValue(await loader()); | ||
|
||
const MyComponent = () => { | ||
const data = useLoaderData<typeof loader>(); | ||
|
||
return data.hello; | ||
}; | ||
|
||
render(<MyComponent />); | ||
|
||
await expect(screen.findByText('world')).resolves.toBeTruthy(); | ||
}); | ||
|
||
it('should support deferring', async () => { | ||
const loader = () => { | ||
return defer({ | ||
hello: 'world', | ||
}); | ||
}; | ||
|
||
useLoaderDataMocked.mockReturnValue(loader().data); | ||
|
||
const MyComponent = () => { | ||
const data = useLoaderData<typeof loader>(); | ||
|
||
return data.hello; | ||
}; | ||
|
||
render(<MyComponent />); | ||
|
||
await expect(screen.findByText('world')).resolves.toBeTruthy(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { LoaderFunction, defer as innerDefer, useLoaderData as innerUseLoaderData } from 'react-router-dom'; | ||
|
||
export type DeferredData<T extends Record<string, any>> = Omit<ReturnType<typeof innerDefer>, 'data'> & { | ||
data: T; | ||
}; | ||
|
||
export type DeferFunction = <T extends Record<string, any>>(data: T, init?: number | ResponseInit) => DeferredData<T>; | ||
|
||
export type UseLoaderDataFunction = <T extends LoaderFunction>() => Awaited<ReturnType<T>> extends DeferredData<any> | ||
? Awaited<ReturnType<T>>['data'] | ||
: Awaited<ReturnType<T>>; | ||
|
||
export const defer = innerDefer as DeferFunction; | ||
export const useLoaderData = innerUseLoaderData as UseLoaderDataFunction; |