Skip to content

Commit 2571388

Browse files
committed
wip: save
1 parent 9be697b commit 2571388

File tree

2 files changed

+312
-61
lines changed

2 files changed

+312
-61
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
import {
2+
type LooseRawProps,
3+
type VaporComponent,
4+
createComponent as originalCreateComponent,
5+
} from '../../src/component'
6+
import { VaporTeleport, template } from '@vue/runtime-vapor'
7+
8+
import { makeRender } from '../_utils'
9+
import { nextTick, onBeforeUnmount, onUnmounted, ref, shallowRef } from 'vue'
10+
11+
const define = makeRender()
12+
13+
describe('renderer: VaporTeleport', () => {
14+
describe('eager mode', () => {
15+
runSharedTests(false)
16+
})
17+
18+
describe('defer mode', () => {
19+
runSharedTests(true)
20+
})
21+
})
22+
23+
function runSharedTests(deferMode: boolean): void {
24+
const createComponent = deferMode
25+
? (
26+
component: VaporComponent,
27+
rawProps?: LooseRawProps | null,
28+
...args: any[]
29+
) => {
30+
if (component === VaporTeleport) {
31+
rawProps!.defer = () => true
32+
}
33+
return originalCreateComponent(component, rawProps, ...args)
34+
}
35+
: originalCreateComponent
36+
37+
test('should work', () => {
38+
const target = document.createElement('div')
39+
const root = document.createElement('div')
40+
41+
const { mount } = define({
42+
setup() {
43+
const n0 = createComponent(
44+
VaporTeleport,
45+
{
46+
to: () => target,
47+
},
48+
{
49+
default: () => template('<div>teleported</div>')(),
50+
},
51+
)
52+
const n1 = template('<div>root</div>')()
53+
return [n0, n1]
54+
},
55+
}).create()
56+
mount(root)
57+
58+
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
59+
expect(target.innerHTML).toBe('<div>teleported</div>')
60+
})
61+
62+
test.todo('should work with SVG', async () => {})
63+
64+
test('should update target', async () => {
65+
const targetA = document.createElement('div')
66+
const targetB = document.createElement('div')
67+
const target = ref(targetA)
68+
const root = document.createElement('div')
69+
70+
const { mount } = define({
71+
setup() {
72+
const n0 = createComponent(
73+
VaporTeleport,
74+
{
75+
to: () => target.value,
76+
},
77+
{
78+
default: () => template('<div>teleported</div>')(),
79+
},
80+
)
81+
const n1 = template('<div>root</div>')()
82+
return [n0, n1]
83+
},
84+
}).create()
85+
mount(root)
86+
87+
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
88+
expect(targetA.innerHTML).toBe('<div>teleported</div>')
89+
expect(targetB.innerHTML).toBe('')
90+
91+
target.value = targetB
92+
await nextTick()
93+
94+
expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
95+
expect(targetA.innerHTML).toBe('')
96+
expect(targetB.innerHTML).toBe('<div>teleported</div>')
97+
})
98+
99+
test('should update children', async () => {
100+
const target = document.createElement('div')
101+
const root = document.createElement('div')
102+
const children = shallowRef([template('<div>teleported</div>')()])
103+
104+
const { mount } = define({
105+
setup() {
106+
const n0 = createComponent(
107+
VaporTeleport,
108+
{
109+
to: () => target,
110+
},
111+
{
112+
default: () => children.value,
113+
},
114+
)
115+
const n1 = template('<div>root</div>')()
116+
return [n0, n1]
117+
},
118+
}).create()
119+
mount(root)
120+
121+
expect(target.innerHTML).toBe('<div>teleported</div>')
122+
123+
children.value = [template('')()]
124+
await nextTick()
125+
expect(target.innerHTML).toBe('')
126+
127+
children.value = [template('teleported')()]
128+
await nextTick()
129+
expect(target.innerHTML).toBe('teleported')
130+
})
131+
132+
test('should remove children when unmounted', async () => {
133+
const target = document.createElement('div')
134+
const root = document.createElement('div')
135+
136+
function testUnmount(props: any) {
137+
const { app } = define({
138+
setup() {
139+
const n0 = createComponent(VaporTeleport, props, {
140+
default: () => template('<div>teleported</div>')(),
141+
})
142+
const n1 = template('<div>root</div>')()
143+
return [n0, n1]
144+
},
145+
}).create()
146+
app.mount(root)
147+
148+
expect(target.innerHTML).toBe(
149+
props.disabled() ? '' : '<div>teleported</div>',
150+
)
151+
152+
app.unmount()
153+
expect(target.innerHTML).toBe('')
154+
expect(target.children.length).toBe(0)
155+
}
156+
157+
testUnmount({ to: () => target, disabled: () => false })
158+
testUnmount({ to: () => target, disabled: () => true })
159+
testUnmount({ to: () => null, disabled: () => true })
160+
})
161+
162+
test('component with multi roots should be removed when unmounted', async () => {
163+
const target = document.createElement('div')
164+
const root = document.createElement('div')
165+
166+
const { component: Comp } = define({
167+
setup() {
168+
return [template('<p>')(), template('<p>')()]
169+
},
170+
})
171+
172+
const { app } = define({
173+
setup() {
174+
const n0 = createComponent(
175+
VaporTeleport,
176+
{
177+
to: () => target,
178+
},
179+
{
180+
default: () => createComponent(Comp),
181+
},
182+
)
183+
const n1 = template('<div>root</div>')()
184+
return [n0, n1]
185+
},
186+
}).create()
187+
188+
app.mount(root)
189+
expect(target.innerHTML).toBe('<p></p><p></p>')
190+
191+
app.unmount()
192+
expect(target.innerHTML).toBe('')
193+
})
194+
195+
test.todo(
196+
'descendent component should be unmounted when teleport is disabled and unmounted',
197+
async () => {
198+
const root = document.createElement('div')
199+
const beforeUnmount = vi.fn()
200+
const unmounted = vi.fn()
201+
const { component: Comp } = define({
202+
setup() {
203+
onBeforeUnmount(beforeUnmount)
204+
onUnmounted(unmounted)
205+
return [template('<p>')(), template('<p>')()]
206+
},
207+
})
208+
209+
const { app } = define({
210+
setup() {
211+
const n0 = createComponent(
212+
VaporTeleport,
213+
{
214+
to: () => null,
215+
disabled: () => true,
216+
},
217+
{
218+
default: () => createComponent(Comp),
219+
},
220+
)
221+
return [n0]
222+
},
223+
}).create()
224+
app.mount(root)
225+
226+
expect(beforeUnmount).toHaveBeenCalledTimes(0)
227+
expect(unmounted).toHaveBeenCalledTimes(0)
228+
229+
app.unmount()
230+
expect(beforeUnmount).toHaveBeenCalledTimes(1)
231+
expect(unmounted).toHaveBeenCalledTimes(1)
232+
},
233+
)
234+
235+
test.todo('multiple teleport with same target', async () => {})
236+
test.todo('should work when using template ref as target', async () => {})
237+
test.todo('disabled', async () => {})
238+
test.todo('moving teleport while enabled', async () => {})
239+
test.todo('moving teleport while disabled', async () => {})
240+
test.todo('should work with block tree', async () => {})
241+
test.todo(
242+
`the dir hooks of the Teleport's children should be called correctly`,
243+
async () => {},
244+
)
245+
test.todo(
246+
`ensure that target changes when disabled are updated correctly when enabled`,
247+
async () => {},
248+
)
249+
test.todo('toggle sibling node inside target node', async () => {})
250+
test.todo('unmount previous sibling node inside target node', async () => {})
251+
test.todo('accessing template refs inside teleport', async () => {})
252+
}

0 commit comments

Comments
 (0)