diff --git a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
index 924038450..8886ce337 100644
--- a/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
+++ b/packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
@@ -1,5 +1,501 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+exports[`compiler: parse > Edge Cases > invalid html 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 1,
+ "line": 3,
+ "offset": 13,
+ },
+ "source": "
+",
+ "start": {
+ "column": 1,
+ "line": 2,
+ "offset": 6,
+ },
+ },
+ "ns": 0,
+ "props": [],
+ "tag": "span",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 3,
+ "offset": 19,
+ },
+ "source": "
+
+
",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 8,
+ "line": 4,
+ "offset": 27,
+ },
+ "source": "
+
+
+",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "
+
+
+",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
+exports[`compiler: parse > Edge Cases > self closing multiple tag 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 1,
+ "offset": 36,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 16,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 11,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 18,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 35,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": {
+ "column": 4,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "
+",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "
+",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
+exports[`compiler: parse > Edge Cases > valid html 1`] = `
+{
+ "cached": 0,
+ "children": [
+ {
+ "children": [
+ {
+ "children": [],
+ "codegenNode": undefined,
+ "isSelfClosing": true,
+ "loc": {
+ "end": {
+ "column": 39,
+ "line": 2,
+ "offset": 73,
+ },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 2,
+ "offset": 37,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "style",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 18,
+ "line": 2,
+ "offset": 52,
+ },
+ "source": "style",
+ "start": {
+ "column": 13,
+ "line": 2,
+ "offset": 47,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ color: 'red' }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 36,
+ "line": 2,
+ "offset": 70,
+ },
+ "source": "{ color: 'red' }",
+ "start": {
+ "column": 20,
+ "line": 2,
+ "offset": 54,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 37,
+ "line": 2,
+ "offset": 71,
+ },
+ "source": "v-bind:style=\\"{ color: 'red' }\\"",
+ "start": {
+ "column": 6,
+ "line": 2,
+ "offset": 40,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": "v-bind:style",
+ "type": 7,
+ },
+ ],
+ "tag": "p",
+ "tagType": 0,
+ "type": 1,
+ },
+ {
+ "content": " a comment with inside it ",
+ "loc": {
+ "end": {
+ "column": 43,
+ "line": 3,
+ "offset": 116,
+ },
+ "source": "",
+ "start": {
+ "column": 3,
+ "line": 3,
+ "offset": 76,
+ },
+ },
+ "type": 3,
+ },
+ ],
+ "codegenNode": undefined,
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "ns": 0,
+ "props": [
+ {
+ "arg": {
+ "constType": 3,
+ "content": "class",
+ "isStatic": true,
+ "loc": {
+ "end": {
+ "column": 12,
+ "line": 1,
+ "offset": 11,
+ },
+ "source": "class",
+ "start": {
+ "column": 7,
+ "line": 1,
+ "offset": 6,
+ },
+ },
+ "type": 4,
+ },
+ "exp": {
+ "constType": 0,
+ "content": "{ some: condition }",
+ "isStatic": false,
+ "loc": {
+ "end": {
+ "column": 33,
+ "line": 1,
+ "offset": 32,
+ },
+ "source": "{ some: condition }",
+ "start": {
+ "column": 14,
+ "line": 1,
+ "offset": 13,
+ },
+ },
+ "type": 4,
+ },
+ "loc": {
+ "end": {
+ "column": 34,
+ "line": 1,
+ "offset": 33,
+ },
+ "source": ":class=\\"{ some: condition }\\"",
+ "start": {
+ "column": 6,
+ "line": 1,
+ "offset": 5,
+ },
+ },
+ "modifiers": [],
+ "name": "bind",
+ "rawName": ":class",
+ "type": 7,
+ },
+ ],
+ "tag": "div",
+ "tagType": 0,
+ "type": 1,
+ },
+ ],
+ "codegenNode": undefined,
+ "components": [],
+ "directives": [],
+ "helpers": Set {},
+ "hoists": [],
+ "imports": [],
+ "loc": {
+ "end": {
+ "column": 7,
+ "line": 4,
+ "offset": 123,
+ },
+ "source": "",
+ "start": {
+ "column": 1,
+ "line": 1,
+ "offset": 0,
+ },
+ },
+ "source": "",
+ "temps": 0,
+ "type": 0,
+}
+`;
+
exports[`compiler: parse > Errors > CDATA_IN_HTML_CONTENT > 1`] = `
{
"cached": 0,
@@ -4326,499 +4822,3 @@ exports[`compiler: parse > Errors > X_MISSING_INTERPOLATION_END > {{}} 1`] = `
"type": 0,
}
`;
-
-exports[`compiler: parse > invalid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 1,
- "line": 3,
- "offset": 13,
- },
- "source": "
-",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 6,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "span",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 7,
- "line": 3,
- "offset": 19,
- },
- "source": "
-
-
",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 8,
- "line": 4,
- "offset": 27,
- },
- "source": "
-
-
-",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "
-
-
-",
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse > self closing multiple tag 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 1,
- "offset": 36,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class=\\"{ some: condition }\\"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": ":class",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 16,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 11,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 34,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 18,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 35,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style=\\"{ color: 'red' }\\"",
- "start": {
- "column": 4,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": "v-bind:style",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 73,
- },
- "source": "
-",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "
-",
- "temps": 0,
- "type": 0,
-}
-`;
-
-exports[`compiler: parse > valid html 1`] = `
-{
- "cached": 0,
- "children": [
- {
- "children": [
- {
- "children": [],
- "codegenNode": undefined,
- "isSelfClosing": true,
- "loc": {
- "end": {
- "column": 39,
- "line": 2,
- "offset": 73,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 2,
- "offset": 37,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "style",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 18,
- "line": 2,
- "offset": 52,
- },
- "source": "style",
- "start": {
- "column": 13,
- "line": 2,
- "offset": 47,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ color: 'red' }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 36,
- "line": 2,
- "offset": 70,
- },
- "source": "{ color: 'red' }",
- "start": {
- "column": 20,
- "line": 2,
- "offset": 54,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 37,
- "line": 2,
- "offset": 71,
- },
- "source": "v-bind:style=\\"{ color: 'red' }\\"",
- "start": {
- "column": 6,
- "line": 2,
- "offset": 40,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": "v-bind:style",
- "type": 7,
- },
- ],
- "tag": "p",
- "tagType": 0,
- "type": 1,
- },
- {
- "content": " a comment with inside it ",
- "loc": {
- "end": {
- "column": 43,
- "line": 3,
- "offset": 116,
- },
- "source": "",
- "start": {
- "column": 3,
- "line": 3,
- "offset": 76,
- },
- },
- "type": 3,
- },
- ],
- "codegenNode": undefined,
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "ns": 0,
- "props": [
- {
- "arg": {
- "constType": 3,
- "content": "class",
- "isStatic": true,
- "loc": {
- "end": {
- "column": 12,
- "line": 1,
- "offset": 11,
- },
- "source": "class",
- "start": {
- "column": 7,
- "line": 1,
- "offset": 6,
- },
- },
- "type": 4,
- },
- "exp": {
- "constType": 0,
- "content": "{ some: condition }",
- "isStatic": false,
- "loc": {
- "end": {
- "column": 33,
- "line": 1,
- "offset": 32,
- },
- "source": "{ some: condition }",
- "start": {
- "column": 14,
- "line": 1,
- "offset": 13,
- },
- },
- "type": 4,
- },
- "loc": {
- "end": {
- "column": 34,
- "line": 1,
- "offset": 33,
- },
- "source": ":class=\\"{ some: condition }\\"",
- "start": {
- "column": 6,
- "line": 1,
- "offset": 5,
- },
- },
- "modifiers": [],
- "name": "bind",
- "rawName": ":class",
- "type": 7,
- },
- ],
- "tag": "div",
- "tagType": 0,
- "type": 1,
- },
- ],
- "codegenNode": undefined,
- "components": [],
- "directives": [],
- "helpers": Set {},
- "hoists": [],
- "imports": [],
- "loc": {
- "end": {
- "column": 7,
- "line": 4,
- "offset": 123,
- },
- "source": "",
- "start": {
- "column": 1,
- "line": 1,
- "offset": 0,
- },
- },
- "source": "",
- "temps": 0,
- "type": 0,
-}
-`;
diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts
index 4e6c80b38..05a2afcdc 100644
--- a/packages/compiler-core/__tests__/parse.spec.ts
+++ b/packages/compiler-core/__tests__/parse.spec.ts
@@ -1796,166 +1796,167 @@ describe('compiler: parse', () => {
})
})
- test('self closing single tag', () => {
- const ast = baseParse('')
+ describe('Edge Cases', () => {
+ test('self closing single tag', () => {
+ const ast = baseParse('')
- expect(ast.children).toHaveLength(1)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- })
-
- test('self closing multiple tag', () => {
- const ast = baseParse(
- `\n` +
- ``
- )
-
- expect(ast).toMatchSnapshot()
-
- expect(ast.children).toHaveLength(2)
- expect(ast.children[0]).toMatchObject({ tag: 'div' })
- expect(ast.children[1]).toMatchObject({ tag: 'p' })
- })
-
- test('valid html', () => {
- const ast = baseParse(
- `\n` +
- `
\n` +
- ` \n` +
- `
`
- )
-
- expect(ast).toMatchSnapshot()
-
- expect(ast.children).toHaveLength(1)
- const el = ast.children[0] as any
- expect(el).toMatchObject({
- tag: 'div'
- })
- expect(el.children).toHaveLength(2)
- expect(el.children[0]).toMatchObject({
- tag: 'p'
- })
- expect(el.children[1]).toMatchObject({
- type: NodeTypes.COMMENT
- })
- })
-
- test('invalid html', () => {
- expect(() => {
- baseParse(`\n\n
\n`)
- }).toThrow('Element is missing end tag.')
-
- const spy = vi.fn()
- const ast = baseParse(`\n\n
\n`, {
- onError: spy
+ expect(ast.children).toHaveLength(1)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
})
- expect(spy.mock.calls).toMatchObject([
- [
- {
- code: ErrorCodes.X_MISSING_END_TAG,
- loc: {
- start: {
- offset: 6,
- line: 2,
- column: 1
- }
- }
- }
- ],
- [
- {
- code: ErrorCodes.X_INVALID_END_TAG,
- loc: {
- start: {
- offset: 20,
- line: 4,
- column: 1
- }
- }
- }
- ]
- ])
+ test('self closing multiple tag', () => {
+ const ast = baseParse(
+ `\n` +
+ ``
+ )
- expect(ast).toMatchSnapshot()
- })
+ expect(ast).toMatchSnapshot()
- test('parse with correct location info', () => {
- const fooSrc = `foo
- is `
- const barSrc = `{{ bar }}`
- const butSrc = ` but `
- const bazSrc = `{{ baz }}`
- const [foo, bar, but, baz] = baseParse(
- fooSrc + barSrc + butSrc + bazSrc
- ).children
+ expect(ast.children).toHaveLength(2)
+ expect(ast.children[0]).toMatchObject({ tag: 'div' })
+ expect(ast.children[1]).toMatchObject({ tag: 'p' })
+ })
- let offset = 0
- expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
- offset += fooSrc.length
- expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
+ test('valid html', () => {
+ const ast = baseParse(
+ `\n` +
+ `
\n` +
+ ` \n` +
+ `
`
+ )
- expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
- const barInner = (bar as InterpolationNode).content
- offset += 3
- expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
- offset += 3
- expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
- offset += 3
- expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
+ expect(ast).toMatchSnapshot()
- expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
- offset += butSrc.length
- expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
+ expect(ast.children).toHaveLength(1)
+ const el = ast.children[0] as any
+ expect(el).toMatchObject({
+ tag: 'div'
+ })
+ expect(el.children).toHaveLength(2)
+ expect(el.children[0]).toMatchObject({
+ tag: 'p'
+ })
+ expect(el.children[1]).toMatchObject({
+ type: NodeTypes.COMMENT
+ })
+ })
- expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
- const bazInner = (baz as InterpolationNode).content
- offset += 3
- expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
- offset += 3
- expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
- offset += 3
- expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
- })
+ test('invalid html', () => {
+ expect(() => {
+ baseParse(`\n\n
\n`)
+ }).toThrow('Element is missing end tag.')
- // With standard HTML parsing, the following input would ignore the slash
- // and treat "<" and "template" as attributes on the open tag of "Hello",
- // causing `` to fail to close, and ``,
- {
+ const spy = vi.fn()
+ const ast = baseParse(`\n\n
\n`, {
onError: spy
- }
- )
- //
- expect(ast.children.length).toBe(2)
- expect(ast.children[1]).toMatchObject({
- type: NodeTypes.ELEMENT,
- tag: 'script'
- })
- })
+ })
- test('arg should be undefined on shorthand dirs with no arg', () => {
- const ast = baseParse(``)
- const el = ast.children[0] as ElementNode
- expect(el.props[0]).toMatchObject({
- type: NodeTypes.DIRECTIVE,
- name: 'slot',
- exp: undefined,
- arg: undefined
- })
- })
+ expect(spy.mock.calls).toMatchObject([
+ [
+ {
+ code: ErrorCodes.X_MISSING_END_TAG,
+ loc: {
+ start: {
+ offset: 6,
+ line: 2,
+ column: 1
+ }
+ }
+ }
+ ],
+ [
+ {
+ code: ErrorCodes.X_INVALID_END_TAG,
+ loc: {
+ start: {
+ offset: 20,
+ line: 4,
+ column: 1
+ }
+ }
+ }
+ ]
+ ])
- // edge case found in vue-macros where the input is TS or JSX
- test('should reset inRCDATA state', () => {
- baseParse(``, { parseMode: 'sfc', onError() {} })
- expect(() => baseParse(`{ foo }`)).not.toThrow()
+ expect(ast).toMatchSnapshot()
+ })
+
+ test('parse with correct location info', () => {
+ const fooSrc = `foo\n is `
+ const barSrc = `{{ bar }}`
+ const butSrc = ` but `
+ const bazSrc = `{{ baz }}`
+ const [foo, bar, but, baz] = baseParse(
+ fooSrc + barSrc + butSrc + bazSrc
+ ).children
+
+ let offset = 0
+ expect(foo.loc.start).toEqual({ line: 1, column: 1, offset })
+ offset += fooSrc.length
+ expect(foo.loc.end).toEqual({ line: 2, column: 5, offset })
+
+ expect(bar.loc.start).toEqual({ line: 2, column: 5, offset })
+ const barInner = (bar as InterpolationNode).content
+ offset += 3
+ expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset })
+ offset += 3
+ expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset })
+ offset += 3
+ expect(bar.loc.end).toEqual({ line: 2, column: 14, offset })
+
+ expect(but.loc.start).toEqual({ line: 2, column: 14, offset })
+ offset += butSrc.length
+ expect(but.loc.end).toEqual({ line: 2, column: 19, offset })
+
+ expect(baz.loc.start).toEqual({ line: 2, column: 19, offset })
+ const bazInner = (baz as InterpolationNode).content
+ offset += 3
+ expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset })
+ offset += 3
+ expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset })
+ offset += 3
+ expect(baz.loc.end).toEqual({ line: 2, column: 28, offset })
+ })
+
+ // With standard HTML parsing, the following input would ignore the slash
+ // and treat "<" and "template" as attributes on the open tag of "Hello",
+ // causing `` to fail to close, and ``,
+ {
+ onError: spy
+ }
+ )
+ //
+ expect(ast.children.length).toBe(2)
+ expect(ast.children[1]).toMatchObject({
+ type: NodeTypes.ELEMENT,
+ tag: 'script'
+ })
+ })
+
+ test('arg should be undefined on shorthand dirs with no arg', () => {
+ const ast = baseParse(``)
+ const el = ast.children[0] as ElementNode
+ expect(el.props[0]).toMatchObject({
+ type: NodeTypes.DIRECTIVE,
+ name: 'slot',
+ exp: undefined,
+ arg: undefined
+ })
+ })
+
+ // edge case found in vue-macros where the input is TS or JSX
+ test('should reset inRCDATA state', () => {
+ baseParse(``, { parseMode: 'sfc', onError() {} })
+ expect(() => baseParse(`{ foo }`)).not.toThrow()
+ })
})
describe('decodeEntities option', () => {