Skip to content

Commit

Permalink
test: query and mutation
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Mar 18, 2024
1 parent d767977 commit 619c920
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/tree-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class TreeMapNode<T = unknown> {
// -------------------------------------
// --- Below are debugging internals ---
// -------------------------------------
/* v8 ignore start */

/**
* Calculates the size of the node and all its children. Used in tests.
Expand All @@ -111,6 +112,13 @@ export function entryNodeSize(node: TreeMapNode): number {
)
}

/**
* Logs the tree to the console. Used in tests.
* @internal
*
* @param tree - tree to log
* @param log - function to log the tree
*/
export function logTree(
tree: TreeMapNode,
// eslint-disable-next-line no-console
Expand Down Expand Up @@ -160,3 +168,4 @@ function printTreeMap(

return treeStr
}
/* v8 ignore stop */
75 changes: 72 additions & 3 deletions src/use-mutation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,37 @@ describe('useMutation', () => {
)
})

it('invokes the "onSuccess" hook', async () => {
const onSuccess = vi.fn()
it('skips setting the error if "onError" throws', async () => {
const onError = vi.fn().mockRejectedValueOnce(new Error('onError'))
const { wrapper } = mountSimple({
onSuccess,
mutation: async () => {
throw new Error('mutation')
},
onError,
})

wrapper.vm.mutate()
await runTimers()
expect(onError).toHaveBeenCalled()
// couldn't be set
expect(wrapper.vm.error).toEqual(null)
})

it('awaits the "onMutate" hook before mutation', async () => {
const onMutate = vi.fn(() => delay(10))
const { wrapper, mutation } = mountSimple({ onMutate })

wrapper.vm.mutate()
expect(onMutate).toHaveBeenCalled()
expect(mutation).not.toHaveBeenCalled()
await runTimers()
expect(mutation).toHaveBeenCalled()
})

it('invokes the "onSuccess" hook', async () => {
const onSuccess = vi.fn()
const { wrapper } = mountSimple({ onSuccess })

wrapper.vm.mutate()
await runTimers()
expect(onSuccess).toHaveBeenCalledWith(
Expand All @@ -160,6 +185,38 @@ describe('useMutation', () => {
)
})

it('skips setting the data if "onSuccess" throws', async () => {
const onSuccess = vi.fn().mockRejectedValueOnce(new Error('onSuccess'))
const { wrapper, mutation } = mountSimple({ onSuccess })

wrapper.vm.mutate()
await runTimers()
expect(onSuccess).toHaveBeenCalled()
expect(mutation).toHaveBeenCalled()
// since it threw
expect(wrapper.vm.data).toBeUndefined()
})

it('sets the error if "onSuccess" throws', async () => {
const onSuccess = vi.fn().mockRejectedValueOnce(new Error('onSuccess'))
const { wrapper } = mountSimple({ onSuccess })

wrapper.vm.mutate()
await runTimers()
expect(onSuccess).toHaveBeenCalled()
expect(wrapper.vm.error).toEqual(new Error('onSuccess'))
})

it('sets the error if "onMutate" throws', async () => {
const onMutate = vi.fn().mockRejectedValueOnce(new Error('onMutate'))
const { wrapper } = mountSimple({ onMutate })

wrapper.vm.mutate()
await runTimers()
expect(onMutate).toHaveBeenCalled()
expect(wrapper.vm.error).toEqual(new Error('onMutate'))
})

describe('invokes the "onSettled" hook', () => {
it('on success', async () => {
const onSettled = vi.fn()
Expand Down Expand Up @@ -198,4 +255,16 @@ describe('useMutation', () => {
)
})
})

it('can reset the mutation', async () => {
const { wrapper } = mountSimple()

wrapper.vm.mutate()
await runTimers()
expect(wrapper.vm.data).toBe(42)
wrapper.vm.reset()
expect(wrapper.vm.data).toBeUndefined()
expect(wrapper.vm.error).toBeNull()
expect(wrapper.vm.status).toBe('pending')
})
})
35 changes: 35 additions & 0 deletions src/use-query.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,5 +500,40 @@ describe('useQuery', () => {
expect(query).toHaveBeenCalledTimes(0)
expect(wrapper.vm.data).toBe(2)
})

it('sets the error if the initial data is an error', async () => {
const pinia = createPinia()

const caches = shallowReactive(
new TreeMapNode<UseQueryEntry>(
['key'],
// fresh data
createQueryEntry(undefined, new Error('fail'), Date.now()),
),
)
pinia.state.value[QUERY_STORE_ID] = { caches }
const { wrapper } = mountSimple({ refetchOnMount: false }, { plugins: [pinia] })

expect(wrapper.vm.status).toBe('error')
expect(wrapper.vm.error).toEqual(new Error('fail'))
expect(wrapper.vm.data).toBe(undefined)
})

it('sets the initial error even with initialData', async () => {
const pinia = createPinia()

const caches = shallowReactive(
new TreeMapNode<UseQueryEntry>(
['key'],
// fresh data
createQueryEntry(undefined, new Error('fail'), Date.now()),
),
)
pinia.state.value[QUERY_STORE_ID] = { caches }
const { wrapper } = mountSimple({ refetchOnMount: false, initialData: () => 42 }, { plugins: [pinia] })

expect(wrapper.vm.status).toBe('error')
expect(wrapper.vm.error).toEqual(new Error('fail'))
})
})
})
2 changes: 1 addition & 1 deletion test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Mock } from 'vitest'
import { vi } from 'vitest'
import { nextTick } from 'vue'

export const delay = (ms: number) => new Promise((r) => setTimeout(r, ms))
export const delay = (ms: number) => new Promise<void>((r) => setTimeout(r, ms))

export type GlobalMountOptions = NonNullable<(Parameters<typeof mount>)[1]>['global']

Expand Down
2 changes: 1 addition & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
environment: 'happy-dom',
coverage: {
provider: 'v8',
reporter: ['text', 'lcov'],
reporter: ['text', 'lcovonly', 'html'],
all: true,
include: ['src'],
exclude: ['src/index.ts', 'src/**/*.test-d.ts'],
Expand Down

0 comments on commit 619c920

Please sign in to comment.