Skip to content

Commit 9969eee

Browse files
authored
test: test for provide/inject (#745)
Co-authored-by: webfansplz <>
1 parent b25f65c commit 9969eee

File tree

1 file changed

+258
-0
lines changed

1 file changed

+258
-0
lines changed
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
import {
2+
h,
3+
provide,
4+
inject,
5+
InjectionKey,
6+
ref,
7+
nextTick,
8+
Ref,
9+
reactive,
10+
defineComponent,
11+
createApp,
12+
} from '../../../src'
13+
import { mockWarn } from '../../helpers'
14+
15+
describe('api: provide/inject', () => {
16+
mockWarn(true)
17+
it('string keys', async () => {
18+
const Provider = {
19+
setup() {
20+
provide('foo', 1)
21+
return () => h(Middle)
22+
},
23+
}
24+
25+
const Middle = {
26+
setup() {
27+
return () => h(Consumer)
28+
},
29+
}
30+
31+
const Consumer = {
32+
setup() {
33+
const foo = inject<number>('foo')
34+
return () => h('div', foo as unknown as string)
35+
},
36+
}
37+
38+
const root = document.createElement('div')
39+
const vm = createApp(Provider).mount(root)
40+
expect(vm.$el.outerHTML).toBe(`<div>1</div>`)
41+
})
42+
43+
it('symbol keys', () => {
44+
// also verifies InjectionKey type sync
45+
const key: InjectionKey<number> = Symbol()
46+
47+
const Provider = {
48+
setup() {
49+
provide(key, 1)
50+
return () => h(Middle)
51+
},
52+
}
53+
54+
const Middle = {
55+
setup() {
56+
return () => h(Consumer)
57+
},
58+
}
59+
60+
const Consumer = {
61+
setup() {
62+
const foo = inject(key) || 1
63+
return () => h('div', (foo + 1) as unknown as string)
64+
},
65+
}
66+
67+
const root = document.createElement('div')
68+
const vm = createApp(Provider).mount(root)
69+
expect(vm.$el.outerHTML).toBe(`<div>2</div>`)
70+
})
71+
72+
it('default values', () => {
73+
const Provider = {
74+
setup() {
75+
provide('foo', 'foo')
76+
return () => h(Middle)
77+
},
78+
}
79+
80+
const Middle = {
81+
setup() {
82+
return () => h(Consumer)
83+
},
84+
}
85+
86+
const Consumer = {
87+
setup() {
88+
// default value should be ignored if value is provided
89+
const foo = inject('foo', 'fooDefault')
90+
// default value should be used if value is not provided
91+
const bar = inject('bar', 'bar')
92+
return () => h('div', (foo + bar) as unknown as string)
93+
},
94+
}
95+
96+
const root = document.createElement('div')
97+
const vm = createApp(Provider).mount(root)
98+
expect(vm.$el.outerHTML).toBe(`<div>foobar</div>`)
99+
})
100+
101+
it('bound to instance', () => {
102+
const Provider = {
103+
setup() {
104+
return () => h(Consumer)
105+
},
106+
}
107+
108+
const Consumer = defineComponent({
109+
name: 'Consumer',
110+
inject: {
111+
foo: {
112+
from: 'foo',
113+
default() {
114+
return this!.$options.name
115+
},
116+
},
117+
},
118+
render() {
119+
return h('div', this.foo as unknown as string)
120+
},
121+
})
122+
123+
const root = document.createElement('div')
124+
const vm = createApp(Provider).mount(root)
125+
expect(vm.$el.outerHTML).toBe(`<div>Consumer</div>`)
126+
})
127+
128+
it('nested providers', () => {
129+
const ProviderOne = {
130+
setup() {
131+
provide('foo', 'foo')
132+
provide('bar', 'bar')
133+
return () => h(ProviderTwo)
134+
},
135+
}
136+
137+
const ProviderTwo = {
138+
setup() {
139+
// override parent value
140+
provide('foo', 'fooOverride')
141+
provide('baz', 'baz')
142+
return () => h(Consumer)
143+
},
144+
}
145+
146+
const Consumer = {
147+
setup() {
148+
const foo = inject('foo')
149+
const bar = inject('bar')
150+
const baz = inject('baz')
151+
return () => h('div', [foo, bar, baz].join(',') as unknown as string)
152+
},
153+
}
154+
155+
const root = document.createElement('div')
156+
const vm = createApp(ProviderOne).mount(root)
157+
expect(vm.$el.outerHTML).toBe(`<div>fooOverride,bar,baz</div>`)
158+
})
159+
160+
it('reactivity with refs', async () => {
161+
const count = ref(1)
162+
163+
const Provider = {
164+
setup() {
165+
provide('count', count)
166+
return () => h(Middle)
167+
},
168+
}
169+
170+
const Middle = {
171+
setup() {
172+
return () => h(Consumer)
173+
},
174+
}
175+
176+
const Consumer = {
177+
setup() {
178+
const count = inject<Ref<number>>('count')!
179+
return () => h('div', count.value as unknown as string)
180+
},
181+
}
182+
183+
const root = document.createElement('div')
184+
const vm = createApp(Provider).mount(root)
185+
expect(vm.$el.outerHTML).toBe(`<div>1</div>`)
186+
187+
count.value++
188+
await nextTick()
189+
expect(vm.$el.outerHTML).toBe(`<div>2</div>`)
190+
})
191+
192+
it('reactivity with objects', async () => {
193+
const rootState = reactive({ count: 1 })
194+
195+
const Provider = {
196+
setup() {
197+
provide('state', rootState)
198+
return () => h(Middle)
199+
},
200+
}
201+
202+
const Middle = {
203+
setup() {
204+
return () => h(Consumer)
205+
},
206+
}
207+
208+
const Consumer = {
209+
setup() {
210+
const state = inject<typeof rootState>('state')!
211+
return () => h('div', state.count as unknown as string)
212+
},
213+
}
214+
215+
const root = document.createElement('div')
216+
const vm = createApp(Provider).mount(root)
217+
expect(vm.$el.outerHTML).toBe(`<div>1</div>`)
218+
219+
rootState.count++
220+
await nextTick()
221+
expect(vm.$el.outerHTML).toBe(`<div>2</div>`)
222+
})
223+
224+
it('should warn unfound', () => {
225+
const Provider = {
226+
setup() {
227+
return () => h(Consumer)
228+
},
229+
}
230+
231+
const Consumer = {
232+
setup() {
233+
const foo = inject('foo')
234+
expect(foo).toBeUndefined()
235+
return () => h('div', foo as unknown as string)
236+
},
237+
}
238+
239+
const root = document.createElement('div')
240+
const vm = createApp(Provider).mount(root)
241+
expect(vm.$el.outerHTML).toBe(`<div></div>`)
242+
expect(`[Vue warn]: Injection "foo" not found`).toHaveBeenWarned()
243+
})
244+
245+
it('should not self-inject', () => {
246+
const Comp = {
247+
setup() {
248+
provide('foo', 'foo')
249+
const injection = inject('foo', null)
250+
return () => h('div', injection as unknown as string)
251+
},
252+
}
253+
254+
const root = document.createElement('div')
255+
const vm = createApp(Comp).mount(root)
256+
expect(vm.$el.outerHTML).toBe(`<div>foo</div>`)
257+
})
258+
})

0 commit comments

Comments
 (0)