Skip to content

Commit 91fb1eb

Browse files
authored
chore(angular-query): add query options tests (TanStack#6677)
1 parent 7eb49eb commit 91fb1eb

File tree

5 files changed

+134
-18
lines changed

5 files changed

+134
-18
lines changed

packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('injectIsFetching', () => {
1717
})
1818
})
1919

20-
it('Returns number of fetching queries', fakeAsync(() => {
20+
test('Returns number of fetching queries', fakeAsync(() => {
2121
const isFetching = TestBed.runInInjectionContext(() => {
2222
injectQuery(() => ({
2323
queryKey: ['isFetching1'],

packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('injectIsMutating', () => {
1717
})
1818
})
1919

20-
it('should properly return isMutating state', fakeAsync(() => {
20+
test('should properly return isMutating state', fakeAsync(() => {
2121
TestBed.runInInjectionContext(() => {
2222
const isMutating = injectIsMutating()
2323
const mutation = injectMutation(() => ({

packages/angular-query-experimental/src/__tests__/inject-query.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('injectQuery', () => {
1818
})
1919
})
2020

21-
it('should return pending status initially', fakeAsync(() => {
21+
test('should return pending status initially', fakeAsync(() => {
2222
const query = TestBed.runInInjectionContext(() => {
2323
return injectQuery(() => ({
2424
queryKey: ['key1'],
@@ -35,7 +35,7 @@ describe('injectQuery', () => {
3535
flush()
3636
}))
3737

38-
it('should resolve to success and update signal: injectQuery()', fakeAsync(() => {
38+
test('should resolve to success and update signal: injectQuery()', fakeAsync(() => {
3939
const query = TestBed.runInInjectionContext(() => {
4040
return injectQuery(() => ({
4141
queryKey: ['key2'],
@@ -53,7 +53,7 @@ describe('injectQuery', () => {
5353
expect(query.isSuccess()).toBe(true)
5454
}))
5555

56-
it('should reject and update signal', fakeAsync(() => {
56+
test('should reject and update signal', fakeAsync(() => {
5757
const query = TestBed.runInInjectionContext(() => {
5858
return injectQuery(() => ({
5959
retry: false,
@@ -74,7 +74,7 @@ describe('injectQuery', () => {
7474
expect(query.failureReason()).toMatchObject({ message: 'Some error' })
7575
}))
7676

77-
it('should update query on options contained signal change', fakeAsync(() => {
77+
test('should update query on options contained signal change', fakeAsync(() => {
7878
const key = signal(['key6', 'key7'])
7979
const spy = vi.fn(simpleFetcher)
8080

@@ -97,7 +97,7 @@ describe('injectQuery', () => {
9797
flush()
9898
}))
9999

100-
it('should only run query once enabled signal is set to true', fakeAsync(() => {
100+
test('should only run query once enabled signal is set to true', fakeAsync(() => {
101101
const spy = vi.fn(simpleFetcher)
102102
const enabled = signal(false)
103103

@@ -119,7 +119,7 @@ describe('injectQuery', () => {
119119
expect(query.status()).toBe('success')
120120
}))
121121

122-
it('should properly execute dependant queries', fakeAsync(() => {
122+
test('should properly execute dependant queries', fakeAsync(() => {
123123
const query1 = TestBed.runInInjectionContext(() => {
124124
return injectQuery(() => ({
125125
queryKey: ['dependant1'],
@@ -159,7 +159,7 @@ describe('injectQuery', () => {
159159
)
160160
}))
161161

162-
it('should use the current value for the queryKey when refetch is called', fakeAsync(() => {
162+
test('should use the current value for the queryKey when refetch is called', fakeAsync(() => {
163163
const fetchFn = vi.fn(simpleFetcher)
164164
const keySignal = signal('key11')
165165

@@ -200,7 +200,7 @@ describe('injectQuery', () => {
200200
flush()
201201
}))
202202

203-
it('should set state to error when queryFn returns reject promise', fakeAsync(() => {
203+
test('should set state to error when queryFn returns reject promise', fakeAsync(() => {
204204
const query = TestBed.runInInjectionContext(() => {
205205
return injectQuery(() => ({
206206
retry: false,
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import { assertType, describe, expectTypeOf } from 'vitest'
2+
import { QueryClient } from '@tanstack/query-core'
3+
import { dataTagSymbol } from '@tanstack/query-core'
4+
import { queryOptions } from '../query-options'
5+
import { injectQuery } from '../inject-query'
6+
import type { Signal } from '@angular/core'
7+
8+
describe('queryOptions', () => {
9+
test('should not allow excess properties', () => {
10+
return queryOptions({
11+
queryKey: ['key'],
12+
queryFn: () => Promise.resolve(5),
13+
// @ts-expect-error this is a good error, because stallTime does not exist!
14+
stallTime: 1000,
15+
})
16+
})
17+
18+
test('should infer types for callbacks', () => {
19+
return queryOptions({
20+
queryKey: ['key'],
21+
queryFn: () => Promise.resolve(5),
22+
staleTime: 1000,
23+
select: (data) => {
24+
expectTypeOf(data).toEqualTypeOf<number>()
25+
},
26+
})
27+
})
28+
})
29+
30+
test('should work when passed to injectQuery', () => {
31+
const options = queryOptions({
32+
queryKey: ['key'],
33+
queryFn: () => Promise.resolve(5),
34+
})
35+
36+
const { data } = injectQuery(() => options)
37+
expectTypeOf(data).toEqualTypeOf<Signal<number | undefined>>()
38+
})
39+
40+
test('should work when passed to fetchQuery', () => {
41+
const options = queryOptions({
42+
queryKey: ['key'],
43+
queryFn: () => Promise.resolve(5),
44+
})
45+
46+
const data = new QueryClient().fetchQuery(options)
47+
assertType<Promise<number>>(data)
48+
})
49+
50+
test('should tag the queryKey with the result type of the QueryFn', () => {
51+
const { queryKey } = queryOptions({
52+
queryKey: ['key'],
53+
queryFn: () => Promise.resolve(5),
54+
})
55+
assertType<number>(queryKey[dataTagSymbol])
56+
})
57+
58+
test('should tag the queryKey even if no promise is returned', () => {
59+
const { queryKey } = queryOptions({
60+
queryKey: ['key'],
61+
queryFn: () => 5,
62+
})
63+
assertType<number>(queryKey[dataTagSymbol])
64+
})
65+
66+
test('should tag the queryKey with unknown if there is no queryFn', () => {
67+
const { queryKey } = queryOptions({
68+
queryKey: ['key'],
69+
})
70+
71+
assertType<unknown>(queryKey[dataTagSymbol])
72+
})
73+
74+
test('should return the proper type when passed to getQueryData', () => {
75+
const { queryKey } = queryOptions({
76+
queryKey: ['key'],
77+
queryFn: () => Promise.resolve(5),
78+
})
79+
80+
const queryClient = new QueryClient()
81+
const data = queryClient.getQueryData(queryKey)
82+
83+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
84+
})
85+
86+
test('should properly type updaterFn when passed to setQueryData', () => {
87+
const { queryKey } = queryOptions({
88+
queryKey: ['key'],
89+
queryFn: () => Promise.resolve(5),
90+
})
91+
92+
const queryClient = new QueryClient()
93+
const data = queryClient.setQueryData(queryKey, (prev) => {
94+
expectTypeOf(prev).toEqualTypeOf<number | undefined>()
95+
return prev
96+
})
97+
98+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
99+
})
100+
101+
test('should properly type value when passed to setQueryData', () => {
102+
const { queryKey } = queryOptions({
103+
queryKey: ['key'],
104+
queryFn: () => Promise.resolve(5),
105+
})
106+
107+
const queryClient = new QueryClient()
108+
109+
// @ts-expect-error value should be a number
110+
queryClient.setQueryData(queryKey, '5')
111+
// @ts-expect-error value should be a number
112+
queryClient.setQueryData(queryKey, () => '5')
113+
114+
const data = queryClient.setQueryData(queryKey, 5)
115+
116+
expectTypeOf(data).toEqualTypeOf<number | undefined>()
117+
})
Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
import { signal } from '@angular/core'
2-
import { isReactive } from '@angular/core/primitives/signals'
1+
import { isSignal, signal } from '@angular/core'
32
import { describe } from 'vitest'
43
import { signalProxy } from '../signal-proxy'
54

65
describe('signalProxy', () => {
76
const inputSignal = signal({ fn: () => 'bar', baz: 'qux' })
87
const proxy = signalProxy(inputSignal)
98

10-
it('should have computed fields', () => {
9+
test('should have computed fields', () => {
1110
expect(proxy.baz()).toEqual('qux')
12-
expect(isReactive(proxy.baz)).toBe(true)
11+
expect(isSignal(proxy.baz)).toBe(true)
1312
})
1413

15-
it('should pass through functions as-is', () => {
14+
test('should pass through functions as-is', () => {
1615
expect(proxy.fn()).toEqual('bar')
17-
expect(isReactive(proxy.fn)).toBe(false)
16+
expect(isSignal(proxy.fn)).toBe(false)
1817
})
1918

20-
it('supports "in" operator', () => {
19+
test('supports "in" operator', () => {
2120
expect('baz' in proxy).toBe(true)
2221
expect('foo' in proxy).toBe(false)
2322
})
2423

25-
it('supports "Object.keys"', () => {
24+
test('supports "Object.keys"', () => {
2625
expect(Object.keys(proxy)).toEqual(['fn', 'baz'])
2726
})
2827
})

0 commit comments

Comments
 (0)