import { createApp, h } from '@vue/runtime-dom'
import {
createComponent,
createDynamicComponent,
createSlot,
defineVaporComponent,
setInsertionState,
template,
vaporInteropPlugin,
withVaporCtx,
} from '../src'
import { makeRender } from './_utils'
const define = makeRender()
describe('scopeId', () => {
test('should attach scopeId to child component', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
return template('
', true)()
},
})
const { html } = define({
__scopeId: 'parent',
setup() {
return createComponent(Child)
},
}).render()
expect(html()).toBe(``)
})
test('should attach scopeId to child component with insertion state', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
return template('', true)()
},
})
const { html } = define({
__scopeId: 'parent',
setup() {
const t0 = template('', true)
const n1 = t0() as any
setInsertionState(n1)
createComponent(Child)
return n1
},
}).render()
expect(html()).toBe(``)
})
test('should attach scopeId to nested child component', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
return template('', true)()
},
})
const Parent = defineVaporComponent({
__scopeId: 'parent',
setup() {
return createComponent(Child)
},
})
const { html } = define({
__scopeId: 'app',
setup() {
return createComponent(Parent)
},
}).render()
expect(html()).toBe(``)
})
test('should not attach scopeId to nested multiple root components', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
return template('', true)()
},
})
const Parent = defineVaporComponent({
__scopeId: 'parent',
setup() {
const n0 = template('')()
const n1 = createComponent(Child)
return [n0, n1]
},
})
const { html } = define({
__scopeId: 'app',
setup() {
return createComponent(Parent)
},
}).render()
expect(html()).toBe(``)
})
test('should attach scopeId to nested child component with insertion state', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
return template('', true)()
},
})
const Parent = defineVaporComponent({
__scopeId: 'parent',
setup() {
return createComponent(Child)
},
})
const { html } = define({
__scopeId: 'app',
setup() {
const t0 = template('', true)
const n1 = t0() as any
setInsertionState(n1)
createComponent(Parent)
return n1
},
}).render()
expect(html()).toBe(
``,
)
})
test('should attach scopeId to dynamic component', () => {
const { html } = define({
__scopeId: 'parent',
setup() {
return createDynamicComponent(() => 'button')
},
}).render()
expect(html()).toBe(``)
})
test('should attach scopeId to dynamic component with insertion state', () => {
const { html } = define({
__scopeId: 'parent',
setup() {
const t0 = template('', true)
const n1 = t0() as any
setInsertionState(n1)
createDynamicComponent(() => 'button')
return n1
},
}).render()
expect(html()).toBe(
``,
)
})
test('should attach scopeId to nested dynamic component', () => {
const Comp = defineVaporComponent({
__scopeId: 'child',
setup() {
return createDynamicComponent(() => 'button', null, null, true)
},
})
const { html } = define({
__scopeId: 'parent',
setup() {
return createComponent(Comp, null, null, true)
},
}).render()
expect(html()).toBe(
``,
)
})
test('should attach scopeId to nested dynamic component with insertion state', () => {
const Comp = defineVaporComponent({
__scopeId: 'child',
setup() {
return createDynamicComponent(() => 'button', null, null, true)
},
})
const { html } = define({
__scopeId: 'parent',
setup() {
const t0 = template('', true)
const n1 = t0() as any
setInsertionState(n1)
createComponent(Comp, null, null, true)
return n1
},
}).render()
expect(html()).toBe(
``,
)
})
test.todo('should attach scopeId to suspense content', async () => {})
// :slotted basic
test('should work on slots', () => {
const Child = defineVaporComponent({
__scopeId: 'child',
setup() {
const n1 = template('', true)() as any
setInsertionState(n1)
createSlot('default', null)
return n1
},
})
const Child2 = defineVaporComponent({
__scopeId: 'child2',
setup() {
return template('', true)()
},
})
const { html } = define({
__scopeId: 'parent',
setup() {
const n2 = createComponent(
Child,
null,
{
default: withVaporCtx(() => {
const n0 = template('')()
const n1 = createComponent(Child2)
return [n0, n1]
}),
},
true,
)
return n2
},
}).render()
// slot content should have:
// - scopeId from parent
// - slotted scopeId (with `-s` postfix) from child (the tree owner)
expect(html()).toBe(
`` +
`
` +
// component inside slot should have:
// - scopeId from template context
// - slotted scopeId from slot owner
// - its own scopeId
`
` +
`` +
`
`,
)
})
test(':slotted on forwarded slots', async () => {
const Wrapper = defineVaporComponent({
__scopeId: 'wrapper',
setup() {
//
const n1 = template('', true)() as any
setInsertionState(n1)
createSlot('default', null, undefined, true /* noSlotted */)
return n1
},
})
const Slotted = defineVaporComponent({
__scopeId: 'slotted',
setup() {
//
const n1 = createComponent(
Wrapper,
null,
{
default: withVaporCtx(() => {
const n0 = createSlot('default', null)
return n0
}),
},
true,
)
return n1
},
})
const { html } = define({
__scopeId: 'root',
setup() {
//
const n2 = createComponent(
Slotted,
null,
{
default: () => {
return template('')()
},
},
true,
)
return n2
},
}).render()
expect(html()).toBe(
``,
)
})
})
describe('vdom interop', () => {
test('vdom parent > vapor child', () => {
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return template('', true)()
},
})
const VdomParent = {
__scopeId: 'vdom-parent',
setup() {
return () => h(VaporChild as any)
},
}
const App = {
setup() {
return () => h(VdomParent)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vdom parent > vapor child > vdom child', () => {
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h('button')
},
}
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return createComponent(VdomChild as any, null, null, true)
},
})
const VdomParent = {
__scopeId: 'vdom-parent',
setup() {
return () => h(VaporChild as any)
},
}
const App = {
setup() {
return () => h(VdomParent)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vdom parent > vapor child > vapor child > vdom child', () => {
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h('button')
},
}
const NestedVaporChild = defineVaporComponent({
__scopeId: 'nested-vapor-child',
setup() {
return createComponent(VdomChild as any, null, null, true)
},
})
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return createComponent(NestedVaporChild as any, null, null, true)
},
})
const VdomParent = {
__scopeId: 'vdom-parent',
setup() {
return () => h(VaporChild as any)
},
}
const App = {
setup() {
return () => h(VdomParent)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vdom parent > vapor dynamic child', () => {
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return createDynamicComponent(() => 'button', null, null, true)
},
})
const VdomParent = {
__scopeId: 'vdom-parent',
setup() {
return () => h(VaporChild as any)
},
}
const App = {
setup() {
return () => h(VdomParent)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vapor parent > vdom child', () => {
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h('button')
},
}
const VaporParent = defineVaporComponent({
__scopeId: 'vapor-parent',
setup() {
return createComponent(VdomChild as any, null, null, true)
},
})
const App = {
setup() {
return () => h(VaporParent as any)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vapor parent > vdom child > vapor child', () => {
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return template('', true)()
},
})
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h(VaporChild as any)
},
}
const VaporParent = defineVaporComponent({
__scopeId: 'vapor-parent',
setup() {
return createComponent(VdomChild as any, null, null, true)
},
})
const App = {
setup() {
return () => h(VaporParent as any)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vapor parent > vdom child > vdom child > vapor child', () => {
const VaporChild = defineVaporComponent({
__scopeId: 'vapor-child',
setup() {
return template('', true)()
},
})
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h(VaporChild as any)
},
}
const VdomParent = {
__scopeId: 'vdom-parent',
setup() {
return () => h(VdomChild as any)
},
}
const VaporParent = defineVaporComponent({
__scopeId: 'vapor-parent',
setup() {
return createComponent(VdomParent as any, null, null, true)
},
})
const App = {
setup() {
return () => h(VaporParent as any)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
test('vapor parent > vapor slot > vdom child', () => {
const VaporSlot = defineVaporComponent({
__scopeId: 'vapor-slot',
setup() {
const n1 = template('', true)() as any
setInsertionState(n1)
createSlot('default', null)
return n1
},
})
const VdomChild = {
__scopeId: 'vdom-child',
setup() {
return () => h('span')
},
}
const VaporParent = defineVaporComponent({
__scopeId: 'vapor-parent',
setup() {
const n2 = createComponent(
VaporSlot,
null,
{
default: withVaporCtx(() => {
const n0 = template('')()
const n1 = createComponent(VdomChild)
return [n0, n1]
}),
},
true,
)
return n2
},
})
const App = {
setup() {
return () => h(VaporParent as any)
},
}
const root = document.createElement('div')
createApp(App).use(vaporInteropPlugin).mount(root)
expect(root.innerHTML).toBe(
``,
)
})
})