import { ForNode, NodeTypes } from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
-describe('v-for', () => {
- describe('transform', () => {
- test('number expression', () => {
- const node = parse('<span v-for="index in 5" />')
+describe('compiler: transform v-for', () => {
+ test('number expression', () => {
+ const node = parse('<span v-for="index in 5" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).toBeUndefined()
- expect(forNode.valueAlias!.content).toBe('index')
- expect(forNode.source.content).toBe('5')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('index')
+ expect(forNode.source.content).toBe('5')
+ })
- test('value', () => {
- const node = parse('<span v-for="(item) in items" />')
+ test('value', () => {
+ const node = parse('<span v-for="(item) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).toBeUndefined()
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.source.content).toBe('items')
+ })
- test('object de-structured value', () => {
- const node = parse('<span v-for="({ id, value }) in items" />')
+ test('object de-structured value', () => {
+ const node = parse('<span v-for="({ id, value }) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).toBeUndefined()
- expect(forNode.valueAlias!.content).toBe('{ id, value }')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('{ id, value }')
+ expect(forNode.source.content).toBe('items')
+ })
- test('array de-structured value', () => {
- const node = parse('<span v-for="([ id, value ]) in items" />')
+ test('array de-structured value', () => {
+ const node = parse('<span v-for="([ id, value ]) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).toBeUndefined()
- expect(forNode.valueAlias!.content).toBe('[ id, value ]')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('[ id, value ]')
+ expect(forNode.source.content).toBe('items')
+ })
- test('value and key', () => {
- const node = parse('<span v-for="(item, key) in items" />')
+ test('value and key', () => {
+ const node = parse('<span v-for="(item, key) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.keyAlias).not.toBeUndefined()
- expect(forNode.keyAlias!.content).toBe('key')
- expect(forNode.objectIndexAlias).toBeUndefined()
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.keyAlias).not.toBeUndefined()
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.source.content).toBe('items')
+ })
- test('value, key and index', () => {
- const node = parse('<span v-for="(value, key, index) in items" />')
+ test('value, key and index', () => {
+ const node = parse('<span v-for="(value, key, index) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).not.toBeUndefined()
- expect(forNode.keyAlias!.content).toBe('key')
- expect(forNode.objectIndexAlias).not.toBeUndefined()
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias!.content).toBe('value')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).not.toBeUndefined()
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
- test('skipped key', () => {
- const node = parse('<span v-for="(value,,index) in items" />')
+ test('skipped key', () => {
+ const node = parse('<span v-for="(value,,index) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).not.toBeUndefined()
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias!.content).toBe('value')
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
- test('skipped value and key', () => {
- const node = parse('<span v-for="(,,index) in items" />')
+ test('skipped value and key', () => {
+ const node = parse('<span v-for="(,,index) in items" />')
- transform(node, { nodeTransforms: [transformFor] })
+ transform(node, { nodeTransforms: [transformFor] })
- expect(node.children.length).toBe(1)
+ expect(node.children.length).toBe(1)
- const forNode = node.children[0] as ForNode
+ const forNode = node.children[0] as ForNode
- expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).not.toBeUndefined()
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias).toBeUndefined()
- expect(forNode.source.content).toBe('items')
- })
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias).toBeUndefined()
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed value', () => {
+ const node = parse('<span v-for="item in items" />')
+
+ transform(node, { nodeTransforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
+
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed value and key', () => {
+ const node = parse('<span v-for="item, key in items" />')
+
+ transform(node, { nodeTransforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
+
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).not.toBeUndefined()
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed value, key and index', () => {
+ const node = parse('<span v-for="value, key, index in items" />')
+
+ transform(node, { nodeTransforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
+
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).not.toBeUndefined()
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed skipped key', () => {
+ const node = parse('<span v-for="value, , index in items" />')
+
+ transform(node, { nodeTransforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
- test('unbracketed value', () => {
- const node = parse('<span v-for="item in items" />')
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed skipped value and key', () => {
+ const node = parse('<span v-for=", , index in items" />')
+
+ transform(node, { nodeTransforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
+
+ expect(forNode.type).toBe(NodeTypes.FOR)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.valueAlias).toBeUndefined()
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('missing expression', () => {
+ const node = parse('<span v-for />')
+ const onError = jest.fn()
+ transform(node, { nodeTransforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_NO_EXPRESSION
+ })
+ )
+ })
+
+ test('empty expression', () => {
+ const node = parse('<span v-for="" />')
+ const onError = jest.fn()
+ transform(node, { nodeTransforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('invalid expression', () => {
+ const node = parse('<span v-for="items" />')
+ const onError = jest.fn()
+ transform(node, { nodeTransforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('missing source', () => {
+ const node = parse('<span v-for="item in" />')
+ const onError = jest.fn()
+ transform(node, { nodeTransforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('missing value', () => {
+ const node = parse('<span v-for="in items" />')
+ const onError = jest.fn()
+ transform(node, { nodeTransforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ describe('source location', () => {
+ test('value & source', () => {
+ const source = '<span v-for="item in items" />'
+ const node = parse(source)
transform(node, { nodeTransforms: [transformFor] })
const forNode = node.children[0] as ForNode
expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).toBeUndefined()
+
expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.valueAlias!.loc.start.offset).toBe(
+ source.indexOf('item') - 1
+ )
+ expect(forNode.valueAlias!.loc.start.line).toBe(1)
+ expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item'))
+ expect(forNode.valueAlias!.loc.end.line).toBe(1)
+ expect(forNode.valueAlias!.loc.end.column).toBe(
+ source.indexOf('item') + 4
+ )
+
expect(forNode.source.content).toBe('items')
+ expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1)
+ expect(forNode.source.loc.start.line).toBe(1)
+ expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
+ expect(forNode.source.loc.end.line).toBe(1)
+ expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
})
- test('unbracketed value and key', () => {
- const node = parse('<span v-for="item, key in items" />')
+ test('bracketed value', () => {
+ const source = '<span v-for="( item ) in items" />'
+ const node = parse(source)
transform(node, { nodeTransforms: [transformFor] })
const forNode = node.children[0] as ForNode
expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).not.toBeUndefined()
- expect(forNode.keyAlias!.content).toBe('key')
- expect(forNode.objectIndexAlias).toBeUndefined()
+
expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.valueAlias!.loc.start.offset).toBe(
+ source.indexOf('item') - 1
+ )
+ expect(forNode.valueAlias!.loc.start.line).toBe(1)
+ expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item'))
+ expect(forNode.valueAlias!.loc.end.line).toBe(1)
+ expect(forNode.valueAlias!.loc.end.column).toBe(
+ source.indexOf('item') + 4
+ )
+
expect(forNode.source.content).toBe('items')
+ expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1)
+ expect(forNode.source.loc.start.line).toBe(1)
+ expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
+ expect(forNode.source.loc.end.line).toBe(1)
+ expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
})
- test('unbracketed value, key and index', () => {
- const node = parse('<span v-for="value, key, index in items" />')
+ test('de-structured value', () => {
+ const source = '<span v-for="( { id, key })in items" />'
+ const node = parse(source)
transform(node, { nodeTransforms: [transformFor] })
const forNode = node.children[0] as ForNode
expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).not.toBeUndefined()
- expect(forNode.keyAlias!.content).toBe('key')
- expect(forNode.objectIndexAlias).not.toBeUndefined()
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias!.content).toBe('value')
+
+ expect(forNode.valueAlias!.content).toBe('{ id, key }')
+ expect(forNode.valueAlias!.loc.start.offset).toBe(
+ source.indexOf('{ id, key }') - 1
+ )
+ expect(forNode.valueAlias!.loc.start.line).toBe(1)
+ expect(forNode.valueAlias!.loc.start.column).toBe(
+ source.indexOf('{ id, key }')
+ )
+ expect(forNode.valueAlias!.loc.end.line).toBe(1)
+ expect(forNode.valueAlias!.loc.end.column).toBe(
+ source.indexOf('{ id, key }') + '{ id, key }'.length
+ )
+
expect(forNode.source.content).toBe('items')
+ expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1)
+ expect(forNode.source.loc.start.line).toBe(1)
+ expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
+ expect(forNode.source.loc.end.line).toBe(1)
+ expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
})
- test('unbracketed skipped key', () => {
- const node = parse('<span v-for="value, , index in items" />')
+ test('bracketed value, key, index', () => {
+ const source = '<span v-for="( item, key, index ) in items" />'
+ const node = parse(source)
transform(node, { nodeTransforms: [transformFor] })
const forNode = node.children[0] as ForNode
expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).not.toBeUndefined()
+
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.valueAlias!.loc.start.offset).toBe(
+ source.indexOf('item') - 1
+ )
+ expect(forNode.valueAlias!.loc.start.line).toBe(1)
+ expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item'))
+ expect(forNode.valueAlias!.loc.end.line).toBe(1)
+ expect(forNode.valueAlias!.loc.end.column).toBe(
+ source.indexOf('item') + 4
+ )
+
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.keyAlias!.loc.start.offset).toBe(source.indexOf('key') - 1)
+ expect(forNode.keyAlias!.loc.start.line).toBe(1)
+ expect(forNode.keyAlias!.loc.start.column).toBe(source.indexOf('key'))
+ expect(forNode.keyAlias!.loc.end.line).toBe(1)
+ expect(forNode.keyAlias!.loc.end.column).toBe(source.indexOf('key') + 3)
+
expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias!.content).toBe('value')
+ expect(forNode.objectIndexAlias!.loc.start.offset).toBe(
+ source.indexOf('index') - 1
+ )
+ expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
+ expect(forNode.objectIndexAlias!.loc.start.column).toBe(
+ source.indexOf('index')
+ )
+ expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
+ expect(forNode.objectIndexAlias!.loc.end.column).toBe(
+ source.indexOf('index') + 5
+ )
+
expect(forNode.source.content).toBe('items')
+ expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1)
+ expect(forNode.source.loc.start.line).toBe(1)
+ expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
+ expect(forNode.source.loc.end.line).toBe(1)
+ expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
})
- test('unbracketed skipped value and key', () => {
- const node = parse('<span v-for=", , index in items" />')
+ test('skipped key', () => {
+ const source = '<span v-for="( item,, index ) in items" />'
+ const node = parse(source)
transform(node, { nodeTransforms: [transformFor] })
const forNode = node.children[0] as ForNode
expect(forNode.type).toBe(NodeTypes.FOR)
- expect(forNode.keyAlias).toBeUndefined()
- expect(forNode.objectIndexAlias).not.toBeUndefined()
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.valueAlias).toBeUndefined()
- expect(forNode.source.content).toBe('items')
- })
-
- test('missing expression', () => {
- const node = parse('<span v-for />')
- const onError = jest.fn()
- transform(node, { nodeTransforms: [transformFor], onError })
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_NO_EXPRESSION
- })
+ expect(forNode.valueAlias!.content).toBe('item')
+ expect(forNode.valueAlias!.loc.start.offset).toBe(
+ source.indexOf('item') - 1
)
- })
-
- test('empty expression', () => {
- const node = parse('<span v-for="" />')
- const onError = jest.fn()
- transform(node, { nodeTransforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
+ expect(forNode.valueAlias!.loc.start.line).toBe(1)
+ expect(forNode.valueAlias!.loc.start.column).toBe(source.indexOf('item'))
+ expect(forNode.valueAlias!.loc.end.line).toBe(1)
+ expect(forNode.valueAlias!.loc.end.column).toBe(
+ source.indexOf('item') + 4
)
- })
-
- test('invalid expression', () => {
- const node = parse('<span v-for="items" />')
- const onError = jest.fn()
- transform(node, { nodeTransforms: [transformFor], onError })
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
+ expect(forNode.objectIndexAlias!.content).toBe('index')
+ expect(forNode.objectIndexAlias!.loc.start.offset).toBe(
+ source.indexOf('index') - 1
)
- })
-
- test('missing source', () => {
- const node = parse('<span v-for="item in" />')
- const onError = jest.fn()
- transform(node, { nodeTransforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
+ expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
+ expect(forNode.objectIndexAlias!.loc.start.column).toBe(
+ source.indexOf('index')
)
- })
-
- test('missing value', () => {
- const node = parse('<span v-for="in items" />')
- const onError = jest.fn()
- transform(node, { nodeTransforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
+ expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
+ expect(forNode.objectIndexAlias!.loc.end.column).toBe(
+ source.indexOf('index') + 5
)
- })
- describe('source location', () => {
- test('value & source', () => {
- const source = '<span v-for="item in items" />'
- const node = parse(source)
-
- transform(node, { nodeTransforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- const forNode = node.children[0] as ForNode
-
- expect(forNode.type).toBe(NodeTypes.FOR)
-
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.valueAlias!.loc.start.offset).toBe(
- source.indexOf('item') - 1
- )
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
- expect(forNode.valueAlias!.loc.start.column).toBe(
- source.indexOf('item')
- )
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
- expect(forNode.valueAlias!.loc.end.column).toBe(
- source.indexOf('item') + 4
- )
-
- expect(forNode.source.content).toBe('items')
- expect(forNode.source.loc.start.offset).toBe(
- source.indexOf('items') - 1
- )
- expect(forNode.source.loc.start.line).toBe(1)
- expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
- expect(forNode.source.loc.end.line).toBe(1)
- expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
- })
-
- test('bracketed value', () => {
- const source = '<span v-for="( item ) in items" />'
- const node = parse(source)
-
- transform(node, { nodeTransforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- const forNode = node.children[0] as ForNode
-
- expect(forNode.type).toBe(NodeTypes.FOR)
-
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.valueAlias!.loc.start.offset).toBe(
- source.indexOf('item') - 1
- )
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
- expect(forNode.valueAlias!.loc.start.column).toBe(
- source.indexOf('item')
- )
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
- expect(forNode.valueAlias!.loc.end.column).toBe(
- source.indexOf('item') + 4
- )
-
- expect(forNode.source.content).toBe('items')
- expect(forNode.source.loc.start.offset).toBe(
- source.indexOf('items') - 1
- )
- expect(forNode.source.loc.start.line).toBe(1)
- expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
- expect(forNode.source.loc.end.line).toBe(1)
- expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
- })
-
- test('de-structured value', () => {
- const source = '<span v-for="( { id, key })in items" />'
- const node = parse(source)
-
- transform(node, { nodeTransforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- const forNode = node.children[0] as ForNode
-
- expect(forNode.type).toBe(NodeTypes.FOR)
-
- expect(forNode.valueAlias!.content).toBe('{ id, key }')
- expect(forNode.valueAlias!.loc.start.offset).toBe(
- source.indexOf('{ id, key }') - 1
- )
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
- expect(forNode.valueAlias!.loc.start.column).toBe(
- source.indexOf('{ id, key }')
- )
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
- expect(forNode.valueAlias!.loc.end.column).toBe(
- source.indexOf('{ id, key }') + '{ id, key }'.length
- )
-
- expect(forNode.source.content).toBe('items')
- expect(forNode.source.loc.start.offset).toBe(
- source.indexOf('items') - 1
- )
- expect(forNode.source.loc.start.line).toBe(1)
- expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
- expect(forNode.source.loc.end.line).toBe(1)
- expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
- })
-
- test('bracketed value, key, index', () => {
- const source = '<span v-for="( item, key, index ) in items" />'
- const node = parse(source)
-
- transform(node, { nodeTransforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- const forNode = node.children[0] as ForNode
-
- expect(forNode.type).toBe(NodeTypes.FOR)
-
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.valueAlias!.loc.start.offset).toBe(
- source.indexOf('item') - 1
- )
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
- expect(forNode.valueAlias!.loc.start.column).toBe(
- source.indexOf('item')
- )
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
- expect(forNode.valueAlias!.loc.end.column).toBe(
- source.indexOf('item') + 4
- )
-
- expect(forNode.keyAlias!.content).toBe('key')
- expect(forNode.keyAlias!.loc.start.offset).toBe(
- source.indexOf('key') - 1
- )
- expect(forNode.keyAlias!.loc.start.line).toBe(1)
- expect(forNode.keyAlias!.loc.start.column).toBe(source.indexOf('key'))
- expect(forNode.keyAlias!.loc.end.line).toBe(1)
- expect(forNode.keyAlias!.loc.end.column).toBe(source.indexOf('key') + 3)
-
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.objectIndexAlias!.loc.start.offset).toBe(
- source.indexOf('index') - 1
- )
- expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
- expect(forNode.objectIndexAlias!.loc.start.column).toBe(
- source.indexOf('index')
- )
- expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
- expect(forNode.objectIndexAlias!.loc.end.column).toBe(
- source.indexOf('index') + 5
- )
-
- expect(forNode.source.content).toBe('items')
- expect(forNode.source.loc.start.offset).toBe(
- source.indexOf('items') - 1
- )
- expect(forNode.source.loc.start.line).toBe(1)
- expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
- expect(forNode.source.loc.end.line).toBe(1)
- expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
- })
-
- test('skipped key', () => {
- const source = '<span v-for="( item,, index ) in items" />'
- const node = parse(source)
-
- transform(node, { nodeTransforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- const forNode = node.children[0] as ForNode
-
- expect(forNode.type).toBe(NodeTypes.FOR)
-
- expect(forNode.valueAlias!.content).toBe('item')
- expect(forNode.valueAlias!.loc.start.offset).toBe(
- source.indexOf('item') - 1
- )
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
- expect(forNode.valueAlias!.loc.start.column).toBe(
- source.indexOf('item')
- )
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
- expect(forNode.valueAlias!.loc.end.column).toBe(
- source.indexOf('item') + 4
- )
-
- expect(forNode.objectIndexAlias!.content).toBe('index')
- expect(forNode.objectIndexAlias!.loc.start.offset).toBe(
- source.indexOf('index') - 1
- )
- expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
- expect(forNode.objectIndexAlias!.loc.start.column).toBe(
- source.indexOf('index')
- )
- expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
- expect(forNode.objectIndexAlias!.loc.end.column).toBe(
- source.indexOf('index') + 5
- )
-
- expect(forNode.source.content).toBe('items')
- expect(forNode.source.loc.start.offset).toBe(
- source.indexOf('items') - 1
- )
- expect(forNode.source.loc.start.line).toBe(1)
- expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
- expect(forNode.source.loc.end.line).toBe(1)
- expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
- })
+ expect(forNode.source.content).toBe('items')
+ expect(forNode.source.loc.start.offset).toBe(source.indexOf('items') - 1)
+ expect(forNode.source.loc.start.line).toBe(1)
+ expect(forNode.source.loc.start.column).toBe(source.indexOf('items'))
+ expect(forNode.source.loc.end.line).toBe(1)
+ expect(forNode.source.loc.end.column).toBe(source.indexOf('items') + 5)
})
})
})
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
-describe('compiler: v-if', () => {
- describe('transform', () => {
- test('basic v-if', () => {
- const ast = parse(`<div v-if="ok"/>`)
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(1)
- expect(node.branches[0].condition!.content).toBe(`ok`)
- expect(node.branches[0].children.length).toBe(1)
- expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
- expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
+describe('compiler: transform v-if', () => {
+ test('basic v-if', () => {
+ const ast = parse(`<div v-if="ok"/>`)
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(1)
+ expect(node.branches[0].condition!.content).toBe(`ok`)
+ expect(node.branches[0].children.length).toBe(1)
+ expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
+ })
- test('template v-if', () => {
- const ast = parse(`<template v-if="ok"><div/>hello<p/></template>`)
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(1)
- expect(node.branches[0].condition!.content).toBe(`ok`)
- expect(node.branches[0].children.length).toBe(3)
- expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
- expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
- expect(node.branches[0].children[1].type).toBe(NodeTypes.TEXT)
- expect((node.branches[0].children[1] as TextNode).content).toBe(`hello`)
- expect(node.branches[0].children[2].type).toBe(NodeTypes.ELEMENT)
- expect((node.branches[0].children[2] as ElementNode).tag).toBe(`p`)
+ test('template v-if', () => {
+ const ast = parse(`<template v-if="ok"><div/>hello<p/></template>`)
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(1)
+ expect(node.branches[0].condition!.content).toBe(`ok`)
+ expect(node.branches[0].children.length).toBe(3)
+ expect(node.branches[0].children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((node.branches[0].children[0] as ElementNode).tag).toBe(`div`)
+ expect(node.branches[0].children[1].type).toBe(NodeTypes.TEXT)
+ expect((node.branches[0].children[1] as TextNode).content).toBe(`hello`)
+ expect(node.branches[0].children[2].type).toBe(NodeTypes.ELEMENT)
+ expect((node.branches[0].children[2] as ElementNode).tag).toBe(`p`)
+ })
- test('v-if + v-else', () => {
- const ast = parse(`<div v-if="ok"/><p v-else/>`)
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- // should fold branches
- expect(ast.children.length).toBe(1)
-
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(2)
-
- const b1 = node.branches[0]
- expect(b1.condition!.content).toBe(`ok`)
- expect(b1.children.length).toBe(1)
- expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b1.children[0] as ElementNode).tag).toBe(`div`)
-
- const b2 = node.branches[1]
- expect(b2.condition).toBeUndefined()
- expect(b2.children.length).toBe(1)
- expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b2.children[0] as ElementNode).tag).toBe(`p`)
+ test('v-if + v-else', () => {
+ const ast = parse(`<div v-if="ok"/><p v-else/>`)
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ // should fold branches
+ expect(ast.children.length).toBe(1)
+
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(2)
+
+ const b1 = node.branches[0]
+ expect(b1.condition!.content).toBe(`ok`)
+ expect(b1.children.length).toBe(1)
+ expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b1.children[0] as ElementNode).tag).toBe(`div`)
+
+ const b2 = node.branches[1]
+ expect(b2.condition).toBeUndefined()
+ expect(b2.children.length).toBe(1)
+ expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b2.children[0] as ElementNode).tag).toBe(`p`)
+ })
- test('v-if + v-else-if', () => {
- const ast = parse(`<div v-if="ok"/><p v-else-if="orNot"/>`)
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- // should fold branches
- expect(ast.children.length).toBe(1)
-
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(2)
-
- const b1 = node.branches[0]
- expect(b1.condition!.content).toBe(`ok`)
- expect(b1.children.length).toBe(1)
- expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b1.children[0] as ElementNode).tag).toBe(`div`)
-
- const b2 = node.branches[1]
- expect(b2.condition!.content).toBe(`orNot`)
- expect(b2.children.length).toBe(1)
- expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b2.children[0] as ElementNode).tag).toBe(`p`)
+ test('v-if + v-else-if', () => {
+ const ast = parse(`<div v-if="ok"/><p v-else-if="orNot"/>`)
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ // should fold branches
+ expect(ast.children.length).toBe(1)
+
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(2)
+
+ const b1 = node.branches[0]
+ expect(b1.condition!.content).toBe(`ok`)
+ expect(b1.children.length).toBe(1)
+ expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b1.children[0] as ElementNode).tag).toBe(`div`)
+
+ const b2 = node.branches[1]
+ expect(b2.condition!.content).toBe(`orNot`)
+ expect(b2.children.length).toBe(1)
+ expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b2.children[0] as ElementNode).tag).toBe(`p`)
+ })
- test('v-if + v-else-if + v-else', () => {
- const ast = parse(
- `<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
- )
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- // should fold branches
- expect(ast.children.length).toBe(1)
-
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(3)
-
- const b1 = node.branches[0]
- expect(b1.condition!.content).toBe(`ok`)
- expect(b1.children.length).toBe(1)
- expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b1.children[0] as ElementNode).tag).toBe(`div`)
-
- const b2 = node.branches[1]
- expect(b2.condition!.content).toBe(`orNot`)
- expect(b2.children.length).toBe(1)
- expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b2.children[0] as ElementNode).tag).toBe(`p`)
-
- const b3 = node.branches[2]
- expect(b3.condition).toBeUndefined()
- expect(b3.children.length).toBe(1)
- expect(b3.children[0].type).toBe(NodeTypes.TEXT)
- expect((b3.children[0] as TextNode).content).toBe(`fine`)
+ test('v-if + v-else-if + v-else', () => {
+ const ast = parse(
+ `<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`
+ )
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ // should fold branches
+ expect(ast.children.length).toBe(1)
+
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(3)
+
+ const b1 = node.branches[0]
+ expect(b1.condition!.content).toBe(`ok`)
+ expect(b1.children.length).toBe(1)
+ expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b1.children[0] as ElementNode).tag).toBe(`div`)
+
+ const b2 = node.branches[1]
+ expect(b2.condition!.content).toBe(`orNot`)
+ expect(b2.children.length).toBe(1)
+ expect(b2.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b2.children[0] as ElementNode).tag).toBe(`p`)
+
+ const b3 = node.branches[2]
+ expect(b3.condition).toBeUndefined()
+ expect(b3.children.length).toBe(1)
+ expect(b3.children[0].type).toBe(NodeTypes.TEXT)
+ expect((b3.children[0] as TextNode).content).toBe(`fine`)
+ })
- test('comment between branches', () => {
- const ast = parse(`
- <div v-if="ok"/>
- <!--foo-->
- <p v-else-if="orNot"/>
- <!--bar-->
- <template v-else>fine</template>
- `)
- transform(ast, {
- nodeTransforms: [transformIf]
- })
- // should fold branches
- expect(ast.children.length).toBe(1)
-
- const node = ast.children[0] as IfNode
- expect(node.type).toBe(NodeTypes.IF)
- expect(node.branches.length).toBe(3)
-
- const b1 = node.branches[0]
- expect(b1.condition!.content).toBe(`ok`)
- expect(b1.children.length).toBe(1)
- expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
- expect((b1.children[0] as ElementNode).tag).toBe(`div`)
-
- const b2 = node.branches[1]
- expect(b2.condition!.content).toBe(`orNot`)
- expect(b2.children.length).toBe(2)
- expect(b2.children[0].type).toBe(NodeTypes.COMMENT)
- expect((b2.children[0] as CommentNode).content).toBe(`foo`)
- expect(b2.children[1].type).toBe(NodeTypes.ELEMENT)
- expect((b2.children[1] as ElementNode).tag).toBe(`p`)
-
- const b3 = node.branches[2]
- expect(b3.condition).toBeUndefined()
- expect(b3.children.length).toBe(2)
- expect(b3.children[0].type).toBe(NodeTypes.COMMENT)
- expect((b3.children[0] as CommentNode).content).toBe(`bar`)
- expect(b3.children[1].type).toBe(NodeTypes.TEXT)
- expect((b3.children[1] as TextNode).content).toBe(`fine`)
+ test('comment between branches', () => {
+ const ast = parse(`
+ <div v-if="ok"/>
+ <!--foo-->
+ <p v-else-if="orNot"/>
+ <!--bar-->
+ <template v-else>fine</template>
+ `)
+ transform(ast, {
+ nodeTransforms: [transformIf]
})
+ // should fold branches
+ expect(ast.children.length).toBe(1)
+
+ const node = ast.children[0] as IfNode
+ expect(node.type).toBe(NodeTypes.IF)
+ expect(node.branches.length).toBe(3)
+
+ const b1 = node.branches[0]
+ expect(b1.condition!.content).toBe(`ok`)
+ expect(b1.children.length).toBe(1)
+ expect(b1.children[0].type).toBe(NodeTypes.ELEMENT)
+ expect((b1.children[0] as ElementNode).tag).toBe(`div`)
+
+ const b2 = node.branches[1]
+ expect(b2.condition!.content).toBe(`orNot`)
+ expect(b2.children.length).toBe(2)
+ expect(b2.children[0].type).toBe(NodeTypes.COMMENT)
+ expect((b2.children[0] as CommentNode).content).toBe(`foo`)
+ expect(b2.children[1].type).toBe(NodeTypes.ELEMENT)
+ expect((b2.children[1] as ElementNode).tag).toBe(`p`)
+
+ const b3 = node.branches[2]
+ expect(b3.condition).toBeUndefined()
+ expect(b3.children.length).toBe(2)
+ expect(b3.children[0].type).toBe(NodeTypes.COMMENT)
+ expect((b3.children[0] as CommentNode).content).toBe(`bar`)
+ expect(b3.children[1].type).toBe(NodeTypes.TEXT)
+ expect((b3.children[1] as TextNode).content).toBe(`fine`)
+ })
- test('error on v-else missing adjacent v-if', () => {
- const ast = parse(`<div v-else/>`)
- const spy = jest.fn()
- transform(ast, {
- nodeTransforms: [transformIf],
- onError: spy
- })
- expect(spy.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
- loc: ast.children[0].loc.start
- }
- ])
-
- const ast2 = parse(`<div/><div v-else/>`)
- const spy2 = jest.fn()
- transform(ast2, {
- nodeTransforms: [transformIf],
- onError: spy2
- })
- expect(spy2.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
- loc: ast2.children[1].loc.start
- }
- ])
-
- const ast3 = parse(`<div/>foo<div v-else/>`)
- const spy3 = jest.fn()
- transform(ast3, {
- nodeTransforms: [transformIf],
- onError: spy3
- })
- expect(spy3.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
- loc: ast3.children[2].loc.start
- }
- ])
+ test('error on v-else missing adjacent v-if', () => {
+ const ast = parse(`<div v-else/>`)
+ const spy = jest.fn()
+ transform(ast, {
+ nodeTransforms: [transformIf],
+ onError: spy
})
-
- test('error on v-else-if missing adjacent v-if', () => {
- const ast = parse(`<div v-else-if="foo"/>`)
- const spy = jest.fn()
- transform(ast, {
- nodeTransforms: [transformIf],
- onError: spy
- })
- expect(spy.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
- loc: ast.children[0].loc.start
- }
- ])
-
- const ast2 = parse(`<div/><div v-else-if="foo"/>`)
- const spy2 = jest.fn()
- transform(ast2, {
- nodeTransforms: [transformIf],
- onError: spy2
- })
- expect(spy2.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
- loc: ast2.children[1].loc.start
- }
- ])
-
- const ast3 = parse(`<div/>foo<div v-else-if="foo"/>`)
- const spy3 = jest.fn()
- transform(ast3, {
- nodeTransforms: [transformIf],
- onError: spy3
- })
- expect(spy3.mock.calls[0]).toMatchObject([
- {
- code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
- loc: ast3.children[2].loc.start
- }
- ])
+ expect(spy.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
+ loc: ast.children[0].loc
+ }
+ ])
+
+ const ast2 = parse(`<div/><div v-else/>`)
+ const spy2 = jest.fn()
+ transform(ast2, {
+ nodeTransforms: [transformIf],
+ onError: spy2
+ })
+ expect(spy2.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
+ loc: ast2.children[1].loc
+ }
+ ])
+
+ const ast3 = parse(`<div/>foo<div v-else/>`)
+ const spy3 = jest.fn()
+ transform(ast3, {
+ nodeTransforms: [transformIf],
+ onError: spy3
})
+ expect(spy3.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_NO_ADJACENT_IF,
+ loc: ast3.children[2].loc
+ }
+ ])
})
- describe('codegen', () => {
- // TODO
+ test('error on v-else-if missing adjacent v-if', () => {
+ const ast = parse(`<div v-else-if="foo"/>`)
+ const spy = jest.fn()
+ transform(ast, {
+ nodeTransforms: [transformIf],
+ onError: spy
+ })
+ expect(spy.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
+ loc: ast.children[0].loc
+ }
+ ])
+
+ const ast2 = parse(`<div/><div v-else-if="foo"/>`)
+ const spy2 = jest.fn()
+ transform(ast2, {
+ nodeTransforms: [transformIf],
+ onError: spy2
+ })
+ expect(spy2.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
+ loc: ast2.children[1].loc
+ }
+ ])
+
+ const ast3 = parse(`<div/>foo<div v-else-if="foo"/>`)
+ const spy3 = jest.fn()
+ transform(ast3, {
+ nodeTransforms: [transformIf],
+ onError: spy3
+ })
+ expect(spy3.mock.calls[0]).toMatchObject([
+ {
+ code: ErrorCodes.X_ELSE_IF_NO_ADJACENT_IF,
+ loc: ast3.children[2].loc
+ }
+ ])
})
})