Skip to content

Commit 0d22bbc

Browse files
committed
wip: add tests
1 parent 40b1e1e commit 0d22bbc

File tree

7 files changed

+133
-4
lines changed

7 files changed

+133
-4
lines changed

packages/compiler-vapor/__tests__/transforms/__snapshots__/transformElement.spec.ts.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`compiler: element transform > MathML 1`] = `
4+
"import { template as _template } from 'vue';
5+
const t0 = _template("<math><mrow><mi>x</mi></mrow></math>", true, 2)
6+
7+
export function render(_ctx) {
8+
const n0 = t0()
9+
return n0
10+
}"
11+
`;
12+
313
exports[`compiler: element transform > component > cache v-on expression with unique handler name 1`] = `
414
"import { resolveComponent as _resolveComponent, createComponentWithFallback as _createComponentWithFallback } from 'vue';
515
@@ -407,6 +417,16 @@ export function render(_ctx) {
407417
}"
408418
`;
409419
420+
exports[`compiler: element transform > svg 1`] = `
421+
"import { template as _template } from 'vue';
422+
const t0 = _template("<svg><circle r=\\"40\\"></circle></svg>", true, 1)
423+
424+
export function render(_ctx) {
425+
const n0 = t0()
426+
return n0
427+
}"
428+
`;
429+
410430
exports[`compiler: element transform > v-bind="obj" 1`] = `
411431
"import { setDynamicProps as _setDynamicProps, renderEffect as _renderEffect, template as _template } from 'vue';
412432
const t0 = _template("<div></div>", true)

packages/compiler-vapor/__tests__/transforms/__snapshots__/vBind.spec.ts.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,17 @@ export function render(_ctx) {
465465
}"
466466
`;
467467
468+
exports[`compiler v-bind > :class w/ svg elements 1`] = `
469+
"import { setAttr as _setAttr, renderEffect as _renderEffect, template as _template } from 'vue';
470+
const t0 = _template("<svg></svg>", true, 1)
471+
472+
export function render(_ctx) {
473+
const n0 = t0()
474+
_renderEffect(() => _setAttr(n0, "class", _ctx.cls))
475+
return n0
476+
}"
477+
`;
478+
468479
exports[`compiler v-bind > :innerHTML 1`] = `
469480
"import { setHtml as _setHtml, renderEffect as _renderEffect, template as _template } from 'vue';
470481
const t0 = _template("<div></div>", true)

packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,4 +956,26 @@ describe('compiler: element transform', () => {
956956
expect(code).toMatchSnapshot()
957957
expect(code).contain('return null')
958958
})
959+
960+
test('svg', () => {
961+
const t = `<svg><circle r="40"></circle></svg>`
962+
const { code, ir } = compileWithElementTransform(t)
963+
expect(code).toMatchSnapshot()
964+
expect(code).contains(
965+
'_template("<svg><circle r=\\"40\\"></circle></svg>", true, 1)',
966+
)
967+
expect(ir.template).toMatchObject([t])
968+
expect(ir.templateNS.get(t)).toBe(1)
969+
})
970+
971+
test('MathML', () => {
972+
const t = `<math><mrow><mi>x</mi></mrow></math>`
973+
const { code, ir } = compileWithElementTransform(t)
974+
expect(code).toMatchSnapshot()
975+
expect(code).contains(
976+
'_template("<math><mrow><mi>x</mi></mrow></math>", true, 2)',
977+
)
978+
expect(ir.template).toMatchObject([t])
979+
expect(ir.templateNS.get(t)).toBe(2)
980+
})
959981
})

packages/compiler-vapor/__tests__/transforms/vBind.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,14 @@ describe('compiler v-bind', () => {
656656
expect(code).contains('_setProp(n0, "value", _ctx.foo)')
657657
})
658658

659+
test(':class w/ svg elements', () => {
660+
const { code } = compileWithVBind(`
661+
<svg :class="cls"/>
662+
`)
663+
expect(code).matchSnapshot()
664+
expect(code).contains('_setAttr(n0, "class", _ctx.cls))')
665+
})
666+
659667
test('number value', () => {
660668
const { code } = compileWithVBind(`<Comp :depth="0" />`)
661669
expect(code).matchSnapshot()

packages/compiler-vapor/src/generators/prop.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,16 +169,17 @@ function getRuntimeHelper(
169169
modifier: '.' | '^' | undefined,
170170
): HelperConfig {
171171
const tagName = tag.toUpperCase()
172+
const isSVG = isSVGTag(tag)
172173
if (modifier) {
173174
if (modifier === '.') {
174-
return getSpecialHelper(key, tagName) || helpers.setDOMProp
175+
return getSpecialHelper(key, tagName, isSVG) || helpers.setDOMProp
175176
} else {
176177
return helpers.setAttr
177178
}
178179
}
179180

180181
// 1. special handling for value / style / class / textContent / innerHTML
181-
const helper = getSpecialHelper(key, tagName)
182+
const helper = getSpecialHelper(key, tagName, isSVG)
182183
if (helper) {
183184
return helper
184185
}
@@ -190,7 +191,7 @@ function getRuntimeHelper(
190191
}
191192

192193
// 3. SVG: always attribute
193-
if (isSVGTag(tag)) {
194+
if (isSVG) {
194195
// TODO pass svg flag
195196
return helpers.setAttr
196197
}
@@ -209,12 +210,13 @@ function getRuntimeHelper(
209210
function getSpecialHelper(
210211
keyName: string,
211212
tagName: string,
213+
isSVG: boolean,
212214
): HelperConfig | undefined {
213215
// special case for 'value' property
214216
if (keyName === 'value' && canSetValueDirectly(tagName)) {
215217
return helpers.setValue
216218
} else if (keyName === 'class') {
217-
return helpers.setClass
219+
return isSVG ? helpers.setAttr : helpers.setClass
218220
} else if (keyName === 'style') {
219221
return helpers.setStyle
220222
} else if (keyName === 'innerHTML') {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
describe.todo('MathML support', () => {})
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { makeRender } from '../_utils'
2+
import { template } from '../../src/dom/template'
3+
import { child } from '../../src/dom/node'
4+
import { setAttr, setClass } from '../../src/dom/prop'
5+
import { renderEffect } from '../../src'
6+
import { nextTick, ref } from '@vue/runtime-dom'
7+
8+
const define = makeRender()
9+
10+
describe('SVG support', () => {
11+
afterEach(() => {
12+
document.body.innerHTML = ''
13+
})
14+
15+
test('should mount elements with correct html namespace', () => {
16+
define({
17+
setup() {
18+
const t0 = template(
19+
'<div id="e0"><svg id="e1"><foreignObject id="e2"><div id="e3"></div><svg id="e4"></svg><math id="e5"></math></foreignObject></svg></div>',
20+
true,
21+
)
22+
return t0()
23+
},
24+
}).render()
25+
26+
const e0 = document.getElementById('e0')!
27+
expect(e0.namespaceURI).toMatch('xhtml')
28+
expect(e0.querySelector('#e1')!.namespaceURI).toMatch('svg')
29+
expect(e0.querySelector('#e2')!.namespaceURI).toMatch('svg')
30+
expect(e0.querySelector('#e3')!.namespaceURI).toMatch('xhtml')
31+
expect(e0.querySelector('#e4')!.namespaceURI).toMatch('svg')
32+
expect(e0.querySelector('#e5')!.namespaceURI).toMatch('Math')
33+
})
34+
35+
test('should patch elements with correct namespaces', async () => {
36+
const cls = ref('foo')
37+
define({
38+
setup() {
39+
const t0 = template(
40+
'<div><svg id="f1"><foreignObject><div id="f2">hi</div></foreignObject></svg></div>',
41+
true,
42+
)
43+
const n2 = t0() as HTMLElement
44+
const n1 = child(n2) as HTMLElement
45+
const p0 = child(n1) as HTMLElement
46+
const n0 = child(p0) as HTMLElement
47+
renderEffect(() => {
48+
const _cls = cls.value
49+
setAttr(n1, 'class', _cls)
50+
setClass(n0, _cls)
51+
})
52+
return n2
53+
},
54+
}).render()
55+
const f1 = document.querySelector('#f1')!
56+
const f2 = document.querySelector('#f2')!
57+
expect(f1.getAttribute('class')).toBe('foo')
58+
expect(f2.className).toBe('foo')
59+
60+
cls.value = 'bar'
61+
await nextTick()
62+
expect(f1.getAttribute('class')).toBe('bar')
63+
expect(f2.className).toBe('bar')
64+
})
65+
})

0 commit comments

Comments
 (0)