snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
41
packages/svelte-query/tests/useMutationState/Base.svelte
Normal file
41
packages/svelte-query/tests/useMutationState/Base.svelte
Normal file
@@ -0,0 +1,41 @@
|
||||
<script lang="ts">
|
||||
import type { QueryClient } from '@tanstack/query-core'
|
||||
import {
|
||||
createMutation,
|
||||
setQueryClientContext,
|
||||
useMutationState,
|
||||
} from '../../src/index.js'
|
||||
import type {
|
||||
Accessor,
|
||||
CreateMutationOptions,
|
||||
MutationStateOptions,
|
||||
} from '../../src/index.js'
|
||||
|
||||
type Props = {
|
||||
queryClient: QueryClient
|
||||
successMutationOpts: Accessor<CreateMutationOptions<string>>
|
||||
errorMutationOpts: Accessor<CreateMutationOptions<string>>
|
||||
mutationStateOpts?: MutationStateOptions
|
||||
}
|
||||
|
||||
let {
|
||||
queryClient,
|
||||
successMutationOpts,
|
||||
errorMutationOpts,
|
||||
mutationStateOpts,
|
||||
}: Props = $props()
|
||||
|
||||
setQueryClientContext(queryClient)
|
||||
|
||||
const successMutation = createMutation(successMutationOpts)
|
||||
const errorMutation = createMutation(errorMutationOpts)
|
||||
|
||||
const mutationState = useMutationState(mutationStateOpts)
|
||||
</script>
|
||||
|
||||
<button onclick={() => successMutation.mutate()}>Success</button>
|
||||
<button onclick={() => errorMutation.mutate()}>Error</button>
|
||||
|
||||
<div>
|
||||
Data: {JSON.stringify(mutationState.map((state) => state.status))}
|
||||
</div>
|
||||
33
packages/svelte-query/tests/useMutationState/Select.svelte
Normal file
33
packages/svelte-query/tests/useMutationState/Select.svelte
Normal file
@@ -0,0 +1,33 @@
|
||||
<script lang="ts">
|
||||
import type { QueryClient } from '@tanstack/query-core'
|
||||
import {
|
||||
createMutation,
|
||||
setQueryClientContext,
|
||||
useMutationState,
|
||||
} from '../../src/index.js'
|
||||
import type {
|
||||
Accessor,
|
||||
CreateMutationOptions,
|
||||
MutationStateOptions,
|
||||
} from '../../src/index.js'
|
||||
|
||||
type Props = {
|
||||
queryClient: QueryClient
|
||||
mutationOpts: Accessor<CreateMutationOptions<string>>
|
||||
mutationStateOpts: MutationStateOptions<string>
|
||||
}
|
||||
|
||||
let { queryClient, mutationOpts, mutationStateOpts }: Props = $props()
|
||||
|
||||
setQueryClientContext(queryClient)
|
||||
|
||||
const mutation = createMutation(mutationOpts)
|
||||
|
||||
const variables = useMutationState(mutationStateOpts)
|
||||
</script>
|
||||
|
||||
<button onclick={() => mutation.mutate()}>mutate</button>
|
||||
|
||||
<div>
|
||||
Variables: {JSON.stringify(variables)}
|
||||
</div>
|
||||
@@ -0,0 +1,195 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { fireEvent, render } from '@testing-library/svelte'
|
||||
import { QueryClient } from '@tanstack/query-core'
|
||||
import { queryKey, sleep } from '@tanstack/query-test-utils'
|
||||
import Base from './Base.svelte'
|
||||
import Select from './Select.svelte'
|
||||
import type { Mutation } from '@tanstack/query-core'
|
||||
|
||||
describe('useMutationState', () => {
|
||||
let queryClient: QueryClient
|
||||
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
queryClient = new QueryClient()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
queryClient.clear()
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
it('should run few mutation functions and check from useMutationState', async () => {
|
||||
const successKey = queryKey()
|
||||
const errorKey = queryKey()
|
||||
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
|
||||
const errorMutationFn = vi
|
||||
.fn()
|
||||
.mockImplementation(() =>
|
||||
sleep(20).then(() => Promise.reject(new Error('error'))),
|
||||
)
|
||||
|
||||
const rendered = render(Base, {
|
||||
props: {
|
||||
queryClient,
|
||||
successMutationOpts: () => ({
|
||||
mutationKey: successKey,
|
||||
mutationFn: successMutationFn,
|
||||
}),
|
||||
errorMutationOpts: () => ({
|
||||
mutationKey: errorKey,
|
||||
mutationFn: errorMutationFn,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
expect(successMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
|
||||
await vi.advanceTimersByTimeAsync(20)
|
||||
expect(errorMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: ["success","error"]')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should select specific type of mutation ( i.e: error only )', async () => {
|
||||
const successKey = queryKey()
|
||||
const errorKey = queryKey()
|
||||
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
|
||||
const errorMutationFn = vi
|
||||
.fn()
|
||||
.mockImplementation(() =>
|
||||
sleep(20).then(() => Promise.reject(new Error('error'))),
|
||||
)
|
||||
|
||||
const rendered = render(Base, {
|
||||
props: {
|
||||
queryClient,
|
||||
successMutationOpts: () => ({
|
||||
mutationKey: successKey,
|
||||
mutationFn: successMutationFn,
|
||||
}),
|
||||
errorMutationOpts: () => ({
|
||||
mutationKey: errorKey,
|
||||
mutationFn: errorMutationFn,
|
||||
}),
|
||||
mutationStateOpts: {
|
||||
filters: { status: 'error' },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
expect(successMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: []')).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
|
||||
await vi.advanceTimersByTimeAsync(20)
|
||||
expect(errorMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: ["error"]')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should return selected value when using select option', async () => {
|
||||
const mutationKey = queryKey()
|
||||
|
||||
const rendered = render(Select, {
|
||||
props: {
|
||||
queryClient,
|
||||
mutationOpts: () => ({
|
||||
mutationKey,
|
||||
mutationFn: () => sleep(10).then(() => 'data'),
|
||||
}),
|
||||
mutationStateOpts: {
|
||||
filters: { mutationKey },
|
||||
select: (mutation: Mutation) => mutation.state.status,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expect(rendered.getByText('Variables: []')).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /mutate/i }))
|
||||
await vi.advanceTimersByTimeAsync(0)
|
||||
expect(rendered.getByText('Variables: ["pending"]')).toBeInTheDocument()
|
||||
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
expect(rendered.getByText('Variables: ["success"]')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should select specific mutation using mutation key', async () => {
|
||||
const successKey = queryKey()
|
||||
const errorKey = queryKey()
|
||||
const successMutationFn = vi.fn(() => sleep(10).then(() => 'data'))
|
||||
const errorMutationFn = vi
|
||||
.fn()
|
||||
.mockImplementation(() =>
|
||||
sleep(20).then(() => Promise.reject(new Error('error'))),
|
||||
)
|
||||
|
||||
const rendered = render(Base, {
|
||||
props: {
|
||||
queryClient,
|
||||
successMutationOpts: () => ({
|
||||
mutationKey: successKey,
|
||||
mutationFn: successMutationFn,
|
||||
}),
|
||||
errorMutationOpts: () => ({
|
||||
mutationKey: errorKey,
|
||||
mutationFn: errorMutationFn,
|
||||
}),
|
||||
mutationStateOpts: {
|
||||
filters: { mutationKey: successKey },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
expect(successMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
|
||||
await vi.advanceTimersByTimeAsync(20)
|
||||
expect(errorMutationFn).toHaveBeenCalledTimes(1)
|
||||
expect(rendered.getByText('Data: ["success"]')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should remove mutations that no longer match the filter', async () => {
|
||||
const firstKey = queryKey()
|
||||
const secondKey = queryKey()
|
||||
const mutationFn = vi.fn(() => sleep(10).then(() => 'data'))
|
||||
|
||||
const rendered = render(Base, {
|
||||
props: {
|
||||
queryClient,
|
||||
successMutationOpts: () => ({
|
||||
mutationKey: firstKey,
|
||||
mutationFn,
|
||||
}),
|
||||
errorMutationOpts: () => ({
|
||||
mutationKey: secondKey,
|
||||
mutationFn,
|
||||
}),
|
||||
mutationStateOpts: {
|
||||
filters: { status: 'pending' },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Success/i }))
|
||||
fireEvent.click(rendered.getByRole('button', { name: /Error/i }))
|
||||
|
||||
await vi.advanceTimersByTimeAsync(0)
|
||||
|
||||
expect(
|
||||
rendered.getByText('Data: ["pending","pending"]'),
|
||||
).toBeInTheDocument()
|
||||
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
|
||||
expect(rendered.getByText('Data: []')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,24 @@
|
||||
import { describe, expectTypeOf, it } from 'vitest'
|
||||
import { useMutationState } from '../../src/index.js'
|
||||
import type { MutationState, MutationStatus } from '@tanstack/query-core'
|
||||
|
||||
describe('useMutationState', () => {
|
||||
it('should default to MutationState', () => {
|
||||
const result = useMutationState({
|
||||
filters: { status: 'pending' },
|
||||
})
|
||||
|
||||
expectTypeOf(result).toEqualTypeOf<
|
||||
Array<MutationState<unknown, Error, unknown, unknown>>
|
||||
>()
|
||||
})
|
||||
|
||||
it('should infer with select', () => {
|
||||
const result = useMutationState({
|
||||
filters: { status: 'pending' },
|
||||
select: (mutation) => mutation.state.status,
|
||||
})
|
||||
|
||||
expectTypeOf(result).toEqualTypeOf<Array<MutationStatus>>()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user