import { h, render, nodeOps, serializeInner, renderSlot } from '@vue/runtime-test' import { setScopeId, withCtx } from '../src/componentRenderContext' describe('scopeId runtime support', () => { test('should attach scopeId', () => { const App = { __scopeId: 'parent', render: () => h('div', [h('div')]) } const root = nodeOps.createElement('div') render(h(App), root) expect(serializeInner(root)).toBe(`
`) }) test('should attach scopeId to components in parent component', () => { const Child = { __scopeId: 'child', render: () => h('div') } const App = { __scopeId: 'parent', render: () => h('div', [h(Child)]) } const root = nodeOps.createElement('div') render(h(App), root) expect(serializeInner(root)).toBe( `
` ) }) // :slotted basic test('should work on slots', () => { const Child = { __scopeId: 'child', render(this: any) { return h('div', renderSlot(this.$slots, 'default', {}, undefined, true)) } } const Child2 = { __scopeId: 'child2', render: () => h('span') } const App = { __scopeId: 'parent', render: () => { return h( Child, withCtx(() => { return [h('div'), h(Child2)] }) ) } } const root = nodeOps.createElement('div') render(h(App), root) // slot content should have: // - scopeId from parent // - slotted scopeId (with `-s` postfix) from child (the tree owner) expect(serializeInner(root)).toBe( `
` + `
` + // component inside slot should have: // - scopeId from template context // - slotted scopeId from slot owner // - its own scopeId `` + `
` ) }) // #2892 test(':slotted on forwarded slots', async () => { const Wrapper = { __scopeId: 'wrapper', render(this: any) { //
return h('div', { class: 'wrapper' }, [ renderSlot(this.$slots, 'default') ]) } } const Slotted = { __scopeId: 'slotted', render(this: any) { // return h(Wrapper, null, { default: withCtx(() => [ renderSlot(this.$slots, 'default', {}, undefined, true) ]) }) } } // simulate hoisted node setScopeId('root') const hoisted = h('div', 'hoisted') setScopeId(null) const Root = { __scopeId: 'root', render(this: any) { //
hoisted
{{ dynamic }}
return h(Slotted, null, { default: withCtx(() => { return [hoisted, h('div', 'dynamic')] }) }) } } const root = nodeOps.createElement('div') render(h(Root), root) expect(serializeInner(root)).toBe( `
` + `
hoisted
` + `
dynamic
` + `
` ) const Root2 = { __scopeId: 'root', render(this: any) { // // //
hoisted
{{ dynamic }}
//
//
return h(Slotted, null, { default: withCtx(() => [ h(Wrapper, null, { default: withCtx(() => [hoisted, h('div', 'dynamic')]) }) ]) }) } } const root2 = nodeOps.createElement('div') render(h(Root2), root2) expect(serializeInner(root2)).toBe( `
` + `
` + `
hoisted
` + `
dynamic
` + `
` + `
` ) }) // #1988 test('should inherit scopeId through nested HOCs with inheritAttrs: false', () => { const App = { __scopeId: 'parent', render: () => { return h(Child) } } function Child() { return h(Child2, { class: 'foo' }) } function Child2() { return h('div') } Child2.inheritAttrs = false const root = nodeOps.createElement('div') render(h(App), root) expect(serializeInner(root)).toBe(`
`) }) })