Skip to content

Commit 6694878

Browse files
committed
test(custom-elements): inject from app context within nested elements
1 parent 399dfaf commit 6694878

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

packages/runtime-dom/__tests__/customElement.spec.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,101 @@ describe('defineCustomElement', () => {
708708
`<div>changedA! changedB!</div>`,
709709
)
710710
})
711+
712+
// #13212
713+
test('inherited from app context within nested elements', async () => {
714+
const outerValues: (string | undefined)[] = []
715+
const innerValues: (string | undefined)[] = []
716+
const innerChildValues: (string | undefined)[] = []
717+
718+
const Outer = defineCustomElement(
719+
{
720+
setup() {
721+
outerValues.push(
722+
inject<string>('shared'),
723+
inject<string>('outer'),
724+
inject<string>('inner'),
725+
)
726+
},
727+
render() {
728+
return h('div', [renderSlot(this.$slots, 'default')])
729+
},
730+
},
731+
{
732+
configureApp(app) {
733+
app.provide('shared', 'shared')
734+
app.provide('outer', 'outer')
735+
},
736+
},
737+
)
738+
739+
const Inner = defineCustomElement(
740+
{
741+
setup() {
742+
// ensure values are not self-injected
743+
provide('inner', 'inner-child')
744+
745+
innerValues.push(
746+
inject<string>('shared'),
747+
inject<string>('outer'),
748+
inject<string>('inner'),
749+
)
750+
},
751+
render() {
752+
return h('div', [renderSlot(this.$slots, 'default')])
753+
},
754+
},
755+
{
756+
configureApp(app) {
757+
app.provide('outer', 'override-outer')
758+
app.provide('inner', 'inner')
759+
},
760+
},
761+
)
762+
763+
const InnerChild = defineCustomElement({
764+
setup() {
765+
innerChildValues.push(
766+
inject<string>('shared'),
767+
inject<string>('outer'),
768+
inject<string>('inner'),
769+
)
770+
},
771+
render() {
772+
return h('div')
773+
},
774+
})
775+
776+
customElements.define('provide-from-app-outer', Outer)
777+
customElements.define('provide-from-app-inner', Inner)
778+
customElements.define('provide-from-app-inner-child', InnerChild)
779+
780+
container.innerHTML =
781+
'<provide-from-app-outer>' +
782+
'<provide-from-app-inner>' +
783+
'<provide-from-app-inner-child></provide-from-app-inner-child>' +
784+
'</provide-from-app-inner>' +
785+
'</provide-from-app-outer>'
786+
787+
const outer = container.childNodes[0] as VueElement
788+
expect(outer.shadowRoot!.innerHTML).toBe('<div><slot></slot></div>')
789+
790+
expect('[Vue warn]: injection "inner" not found.').toHaveBeenWarnedTimes(
791+
1,
792+
)
793+
expect(
794+
'[Vue warn]: App already provides property with key "outer" inherited from its parent element. ' +
795+
'It will be overwritten with the new value.',
796+
).toHaveBeenWarnedTimes(1)
797+
798+
expect(outerValues).toEqual(['shared', 'outer', undefined])
799+
expect(innerValues).toEqual(['shared', 'override-outer', 'inner'])
800+
expect(innerChildValues).toEqual([
801+
'shared',
802+
'override-outer',
803+
'inner-child',
804+
])
805+
})
711806
})
712807

713808
describe('styles', () => {

0 commit comments

Comments
 (0)