|
| 1 | +import { defineComponent, h } from 'vue' |
| 2 | +import { render as testRender } from '../test-utils/vue-testing-library' |
| 3 | + |
| 4 | +import { render } from './render' |
| 5 | +import { html } from '../test-utils/html' |
| 6 | + |
| 7 | +let Dummy = defineComponent({ |
| 8 | + props: { |
| 9 | + as: { type: [Object, String], default: 'div' }, |
| 10 | + }, |
| 11 | + setup(props, { attrs, slots }) { |
| 12 | + return () => render({ props, slots, attrs, slot: {}, name: 'Dummy' }) |
| 13 | + }, |
| 14 | +}) |
| 15 | + |
| 16 | +function renderTemplate(input: string | Partial<Parameters<typeof defineComponent>[0]>) { |
| 17 | + let defaultComponents = { Dummy } |
| 18 | + |
| 19 | + if (typeof input === 'string') { |
| 20 | + return testRender(defineComponent({ template: input, components: defaultComponents })) |
| 21 | + } |
| 22 | + |
| 23 | + return testRender( |
| 24 | + defineComponent( |
| 25 | + Object.assign({}, input, { |
| 26 | + components: { ...defaultComponents, ...input.components }, |
| 27 | + }) as Parameters<typeof defineComponent>[0] |
| 28 | + ) |
| 29 | + ) |
| 30 | +} |
| 31 | + |
| 32 | +describe('Validation', () => { |
| 33 | + it('should error when using an as="template" with additional props', () => { |
| 34 | + expect.hasAssertions() |
| 35 | + |
| 36 | + renderTemplate({ |
| 37 | + template: html` |
| 38 | + <Dummy as="template" class="abc">Contents</Dummy> |
| 39 | + `, |
| 40 | + errorCaptured(err) { |
| 41 | + expect(err as Error).toEqual( |
| 42 | + new Error( |
| 43 | + [ |
| 44 | + 'Passing props on "template"!', |
| 45 | + '', |
| 46 | + 'The current component <Dummy /> is rendering a "template".', |
| 47 | + 'However we need to passthrough the following props:', |
| 48 | + ' - class', |
| 49 | + '', |
| 50 | + 'You can apply a few solutions:', |
| 51 | + ' - Add an `as="..."` prop, to ensure that we render an actual element instead of a "template".', |
| 52 | + ' - Render a single element as the child so that we can forward the props onto that element.', |
| 53 | + ].join('\n') |
| 54 | + ) |
| 55 | + ) |
| 56 | + return false |
| 57 | + }, |
| 58 | + }) |
| 59 | + }) |
| 60 | + |
| 61 | + it('should forward the props to the first child', () => { |
| 62 | + renderTemplate({ |
| 63 | + template: html` |
| 64 | + <Dummy as="template" class="abc"> |
| 65 | + <div id="result">Contents</div> |
| 66 | + </Dummy> |
| 67 | + `, |
| 68 | + }) |
| 69 | + |
| 70 | + expect(document.getElementById('result')).toHaveClass('abc') |
| 71 | + }) |
| 72 | + |
| 73 | + it('should forward the props via Functional Components', () => { |
| 74 | + renderTemplate({ |
| 75 | + components: { |
| 76 | + PassThrough(props, context) { |
| 77 | + props.as = props.as ?? 'template' |
| 78 | + return render({ |
| 79 | + props, |
| 80 | + attrs: context.attrs, |
| 81 | + slots: context.slots, |
| 82 | + slot: {}, |
| 83 | + name: 'PassThrough', |
| 84 | + }) |
| 85 | + }, |
| 86 | + }, |
| 87 | + template: html` |
| 88 | + <Dummy as="template" class="abc" data-test="123"> |
| 89 | + <PassThrough> |
| 90 | + <div id="result">Contents</div> |
| 91 | + </PassThrough> |
| 92 | + </Dummy> |
| 93 | + `, |
| 94 | + }) |
| 95 | + |
| 96 | + expect(document.getElementById('result')).toHaveClass('abc') |
| 97 | + }) |
| 98 | +}) |
0 commit comments