Skip to content

Commit 246badc

Browse files
committed
test(runtime-vapor): component slots [wip]
1 parent ffee672 commit 246badc

File tree

1 file changed

+220
-14
lines changed

1 file changed

+220
-14
lines changed
Lines changed: 220 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,249 @@
11
// NOTE: This test is implemented based on the case of `runtime-core/__test__/componentSlots.spec.ts`.
22

3+
import {
4+
defineComponent,
5+
getCurrentInstance,
6+
nextTick,
7+
ref,
8+
render as renderComponent,
9+
template,
10+
} from '../src'
11+
import { createSlots } from '../src/slot'
312
import { makeRender } from './_utils'
413

514
const define = makeRender<any>()
615

716
describe('component: slots', () => {
8-
test.todo('initSlots: instance.slots should be set correctly', () => {})
17+
function renderWithSlots(slots: any): any {
18+
let instance: any
19+
const Comp = defineComponent({
20+
vapor: true,
21+
render() {
22+
const t0 = template('<div></div>')
23+
const n0 = t0()
24+
instance = getCurrentInstance()
25+
return n0
26+
},
27+
})
28+
29+
const { render } = define({
30+
render() {
31+
const t0 = template('<div></div>')
32+
const n0 = t0()
33+
renderComponent(Comp, {}, slots, n0 as ParentNode)
34+
},
35+
})
36+
37+
render()
38+
return instance
39+
}
40+
41+
test('initSlots: instance.slots should be set correctly', () => {
42+
const { slots } = renderWithSlots({ _: 1 })
43+
expect(slots).toMatchObject({ _: 1 })
44+
})
945

1046
test.todo(
1147
'initSlots: should normalize object slots (when value is null, string, array)',
12-
() => {},
48+
() => {
49+
// TODO: normalize
50+
},
1351
)
1452

1553
test.todo(
1654
'initSlots: should normalize object slots (when value is function)',
17-
() => {},
55+
() => {
56+
// TODO: normalize
57+
},
1858
)
1959

20-
test.todo(
21-
'initSlots: instance.slots should be set correctly (when vnode.shapeFlag is not SLOTS_CHILDREN)',
22-
() => {},
23-
)
60+
test('initSlots: instance.slots should be set correctly', () => {
61+
let proxy: any
62+
const { render } = define({
63+
render() {
64+
const t0 = template('<div></div>')
65+
const n0 = t0()
66+
proxy = getCurrentInstance()
67+
return n0
68+
},
69+
})
70+
71+
render(
72+
{},
73+
createSlots({
74+
header: () => {
75+
const t0 = template('header')
76+
// TODO: single node
77+
return [t0()]
78+
},
79+
}),
80+
)
81+
expect(proxy.slots.header()).toMatchObject([
82+
document.createTextNode('header'),
83+
])
84+
})
2485

86+
test('initSlots: instance.slots should be set correctly (when vnode.shapeFlag is not SLOTS_CHILDREN)', () => {
87+
const { slots } = renderWithSlots(
88+
createSlots({
89+
// TODO: normalize from array
90+
default: () => {
91+
const t0 = template('<span></span>')
92+
return [t0()]
93+
},
94+
}),
95+
)
96+
97+
// TODO: warn
98+
// expect(
99+
// '[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance.',
100+
// ).toHaveBeenWarned()
101+
102+
expect(slots.default()).toMatchObject([document.createElement('span')])
103+
})
104+
105+
// TODO: dynamic slot
25106
test.todo(
26-
'updateSlots: instance.slots should be updated correctly (when slotType is number)',
27-
async () => {},
107+
'updateSlots: instance.slots should be updated correctly',
108+
async () => {
109+
const flag1 = ref(true)
110+
111+
let instance: any
112+
const Child = () => {
113+
instance = getCurrentInstance()
114+
return template('child')()
115+
}
116+
117+
const { render } = define({
118+
render() {
119+
const t0 = template('<div></div>')
120+
const n0 = t0()
121+
renderComponent(
122+
Child,
123+
{},
124+
createSlots({
125+
default: () => {
126+
// TODO: dynamic slot
127+
return flag1.value
128+
? [template('<span></span>')()]
129+
: [template('<div></div>')()]
130+
},
131+
}),
132+
n0 as ParentNode,
133+
)
134+
return []
135+
},
136+
})
137+
138+
render()
139+
140+
expect(instance.slots.default()).toMatchObject([])
141+
expect(instance.slots.default()).not.toMatchObject([])
142+
143+
flag1.value = false
144+
await nextTick()
145+
146+
expect(instance.slots.default()).not.toMatchObject([])
147+
expect(instance.slots.default()).toMatchObject([])
148+
},
28149
)
29150

151+
// TODO: dynamic slots
30152
test.todo(
31-
'updateSlots: instance.slots should be updated correctly (when slotType is null)',
32-
async () => {},
153+
'updateSlots: instance.slots should be updated correctly',
154+
async () => {
155+
const flag1 = ref(true)
156+
157+
let instance: any
158+
const Child = () => {
159+
instance = getCurrentInstance()
160+
return template('child')()
161+
}
162+
163+
const oldSlots = {
164+
header: () => template('header')(),
165+
footer: undefined,
166+
}
167+
const newSlots = {
168+
header: undefined,
169+
footer: () => template('footer')(),
170+
}
171+
172+
const { render } = define({
173+
render() {
174+
const t0 = template('<div></div>')
175+
const n0 = t0()
176+
// renderComponent(
177+
// Child,
178+
// {},
179+
// createSlots(flag1.value ? oldSlots : newSlots),
180+
// n0 as ParentNode,
181+
// )
182+
return []
183+
},
184+
})
185+
186+
render()
187+
188+
expect(instance.slots).toMatchObject({ _: null })
189+
190+
flag1.value = false
191+
await nextTick()
192+
193+
expect(instance.slots).toMatchObject({ _: null })
194+
},
33195
)
34196

35197
test.todo(
36198
'updateSlots: instance.slots should be update correctly (when vnode.shapeFlag is not SLOTS_CHILDREN)',
37-
async () => {},
199+
async () => {
200+
// TODO: dynamic slots
201+
},
38202
)
39203

40-
test.todo('should respect $stable flag', async () => {})
204+
test.todo('should respect $stable flag', async () => {
205+
// TODO: $stable flag
206+
})
41207

42-
test.todo('should not warn when mounting another app in setup', () => {})
208+
test.todo('should not warn when mounting another app in setup', () => {
209+
// TODO: warning and createApp fn
210+
// const Comp = {
211+
// render() {
212+
// const i = getCurrentInstance()
213+
// return i?.slots.default?.()
214+
// },
215+
// }
216+
// const mountComp = () => {
217+
// createApp({
218+
// render() {
219+
// const t0 = template('<div></div>')
220+
// const n0 = t0()
221+
// renderComponent(
222+
// Comp,
223+
// {},
224+
// createSlots({
225+
// default: () => {
226+
// const t0 = template('msg')
227+
// return [t0()]
228+
// },
229+
// }),
230+
// n0,
231+
// )
232+
// return n0
233+
// },
234+
// })
235+
// }
236+
// const App = {
237+
// setup() {
238+
// mountComp()
239+
// },
240+
// render() {
241+
// return null
242+
// },
243+
// }
244+
// createApp(App).mount(document.createElement('div'))
245+
// expect(
246+
// 'Slot "default" invoked outside of the render function',
247+
// ).not.toHaveBeenWarned()
248+
})
43249
})

0 commit comments

Comments
 (0)