|
|
@@ -1,148 +1,185 @@
|
|
|
import { parse } from '../../src/parse'
|
|
|
import { transform } from '../../src/transform'
|
|
|
import { transformFor } from '../../src/transforms/vFor'
|
|
|
-import { ForNode, NodeTypes, SimpleExpressionNode } from '../../src/ast'
|
|
|
+import {
|
|
|
+ ForNode,
|
|
|
+ NodeTypes,
|
|
|
+ SimpleExpressionNode,
|
|
|
+ ElementNode,
|
|
|
+ InterpolationNode
|
|
|
+} from '../../src/ast'
|
|
|
import { ErrorCodes } from '../../src/errors'
|
|
|
import { CompilerOptions } from '../../src'
|
|
|
+import { transformExpression } from '../../src/transforms/transformExpression'
|
|
|
|
|
|
function parseWithForTransform(
|
|
|
template: string,
|
|
|
options: CompilerOptions = {}
|
|
|
-): ForNode {
|
|
|
+) {
|
|
|
const node = parse(template, options)
|
|
|
- transform(node, { nodeTransforms: [transformFor], ...options })
|
|
|
- if (!options.onError) {
|
|
|
- expect(node.children.length).toBe(1)
|
|
|
- expect(node.children[0].type).toBe(NodeTypes.FOR)
|
|
|
- }
|
|
|
- return node.children[0] as ForNode
|
|
|
+ transform(node, {
|
|
|
+ nodeTransforms: [
|
|
|
+ transformFor,
|
|
|
+ ...(options.prefixIdentifiers ? [transformExpression] : [])
|
|
|
+ ],
|
|
|
+ ...options
|
|
|
+ })
|
|
|
+ return node.children[0]
|
|
|
}
|
|
|
|
|
|
describe('compiler: transform v-for', () => {
|
|
|
test('number expression', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for="index in 5" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for="index in 5" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('index')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('index')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('5')
|
|
|
})
|
|
|
|
|
|
test('value', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for="(item) in items" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for="(item) in items" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('object de-structured value', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="({ id, value }) in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('{ id, value }')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ '{ id, value }'
|
|
|
+ )
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('array de-structured value', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="([ id, value ]) in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('[ id, value ]')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ '[ id, value ]'
|
|
|
+ )
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('value and key', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="(item, key) in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).not.toBeUndefined()
|
|
|
- expect(forNode.keyAlias!.content).toBe('key')
|
|
|
+ expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('value, key and index', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="(value, key, index) in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).not.toBeUndefined()
|
|
|
- expect(forNode.keyAlias!.content).toBe('key')
|
|
|
+ expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.valueAlias!.content).toBe('value')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('skipped key', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="(value,,index) in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.valueAlias!.content).toBe('value')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('skipped value and key', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for="(,,index) in items" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for="(,,index) in items" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
expect(forNode.valueAlias).toBeUndefined()
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('unbracketed value', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for="item in items" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for="item in items" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('unbracketed value and key', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for="item, key in items" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for="item, key in items" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).not.toBeUndefined()
|
|
|
- expect(forNode.keyAlias!.content).toBe('key')
|
|
|
+ expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
|
|
|
expect(forNode.objectIndexAlias).toBeUndefined()
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('unbracketed value, key and index', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="value, key, index in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).not.toBeUndefined()
|
|
|
- expect(forNode.keyAlias!.content).toBe('key')
|
|
|
+ expect((forNode.keyAlias as SimpleExpressionNode).content).toBe('key')
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.valueAlias!.content).toBe('value')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('unbracketed skipped key', () => {
|
|
|
const forNode = parseWithForTransform(
|
|
|
'<span v-for="value, , index in items" />'
|
|
|
- )
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.valueAlias!.content).toBe('value')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('value')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
|
|
|
test('unbracketed skipped value and key', () => {
|
|
|
- const forNode = parseWithForTransform('<span v-for=", , index in items" />')
|
|
|
+ const forNode = parseWithForTransform(
|
|
|
+ '<span v-for=", , index in items" />'
|
|
|
+ ) as ForNode
|
|
|
expect(forNode.keyAlias).toBeUndefined()
|
|
|
expect(forNode.objectIndexAlias).not.toBeUndefined()
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
+ expect((forNode.objectIndexAlias as SimpleExpressionNode).content).toBe(
|
|
|
+ 'index'
|
|
|
+ )
|
|
|
expect(forNode.valueAlias).toBeUndefined()
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
})
|
|
|
@@ -210,17 +247,16 @@ describe('compiler: transform v-for', () => {
|
|
|
describe('source location', () => {
|
|
|
test('value & source', () => {
|
|
|
const source = '<span v-for="item in items" />'
|
|
|
- const forNode = parseWithForTransform(source)
|
|
|
+ const forNode = parseWithForTransform(source) as ForNode
|
|
|
|
|
|
const itemOffset = source.indexOf('item')
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
- expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset)
|
|
|
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1)
|
|
|
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.end.column).toBe(
|
|
|
- itemOffset + 1 + `item`.length
|
|
|
- )
|
|
|
+ const value = forNode.valueAlias as SimpleExpressionNode
|
|
|
+ expect((forNode.valueAlias as SimpleExpressionNode).content).toBe('item')
|
|
|
+ expect(value.loc.start.offset).toBe(itemOffset)
|
|
|
+ expect(value.loc.start.line).toBe(1)
|
|
|
+ expect(value.loc.start.column).toBe(itemOffset + 1)
|
|
|
+ expect(value.loc.end.line).toBe(1)
|
|
|
+ expect(value.loc.end.column).toBe(itemOffset + 1 + `item`.length)
|
|
|
|
|
|
const itemsOffset = source.indexOf('items')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
@@ -235,17 +271,16 @@ describe('compiler: transform v-for', () => {
|
|
|
|
|
|
test('bracketed value', () => {
|
|
|
const source = '<span v-for="( item ) in items" />'
|
|
|
- const forNode = parseWithForTransform(source)
|
|
|
+ const forNode = parseWithForTransform(source) as ForNode
|
|
|
|
|
|
const itemOffset = source.indexOf('item')
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
- expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset)
|
|
|
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1)
|
|
|
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.end.column).toBe(
|
|
|
- itemOffset + 1 + `item`.length
|
|
|
- )
|
|
|
+ const value = forNode.valueAlias as SimpleExpressionNode
|
|
|
+ expect(value.content).toBe('item')
|
|
|
+ expect(value.loc.start.offset).toBe(itemOffset)
|
|
|
+ expect(value.loc.start.line).toBe(1)
|
|
|
+ expect(value.loc.start.column).toBe(itemOffset + 1)
|
|
|
+ expect(value.loc.end.line).toBe(1)
|
|
|
+ expect(value.loc.end.column).toBe(itemOffset + 1 + `item`.length)
|
|
|
|
|
|
const itemsOffset = source.indexOf('items')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
@@ -260,17 +295,16 @@ describe('compiler: transform v-for', () => {
|
|
|
|
|
|
test('de-structured value', () => {
|
|
|
const source = '<span v-for="( { id, key }) in items" />'
|
|
|
- const forNode = parseWithForTransform(source)
|
|
|
+ const forNode = parseWithForTransform(source) as ForNode
|
|
|
|
|
|
+ const value = forNode.valueAlias as SimpleExpressionNode
|
|
|
const valueIndex = source.indexOf('{ id, key }')
|
|
|
- expect(forNode.valueAlias!.content).toBe('{ id, key }')
|
|
|
- expect(forNode.valueAlias!.loc.start.offset).toBe(valueIndex)
|
|
|
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.start.column).toBe(valueIndex + 1)
|
|
|
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.end.column).toBe(
|
|
|
- valueIndex + 1 + '{ id, key }'.length
|
|
|
- )
|
|
|
+ expect(value.content).toBe('{ id, key }')
|
|
|
+ expect(value.loc.start.offset).toBe(valueIndex)
|
|
|
+ expect(value.loc.start.line).toBe(1)
|
|
|
+ expect(value.loc.start.column).toBe(valueIndex + 1)
|
|
|
+ expect(value.loc.end.line).toBe(1)
|
|
|
+ expect(value.loc.end.column).toBe(valueIndex + 1 + '{ id, key }'.length)
|
|
|
|
|
|
const itemsOffset = source.indexOf('items')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
@@ -285,37 +319,34 @@ describe('compiler: transform v-for', () => {
|
|
|
|
|
|
test('bracketed value, key, index', () => {
|
|
|
const source = '<span v-for="( item, key, index ) in items" />'
|
|
|
- const forNode = parseWithForTransform(source)
|
|
|
+ const forNode = parseWithForTransform(source) as ForNode
|
|
|
|
|
|
const itemOffset = source.indexOf('item')
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
- expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset)
|
|
|
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1)
|
|
|
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.end.column).toBe(
|
|
|
- itemOffset + 1 + `item`.length
|
|
|
- )
|
|
|
+ const value = forNode.valueAlias as SimpleExpressionNode
|
|
|
+ expect(value.content).toBe('item')
|
|
|
+ expect(value.loc.start.offset).toBe(itemOffset)
|
|
|
+ expect(value.loc.start.line).toBe(1)
|
|
|
+ expect(value.loc.start.column).toBe(itemOffset + 1)
|
|
|
+ expect(value.loc.end.line).toBe(1)
|
|
|
+ expect(value.loc.end.column).toBe(itemOffset + 1 + `item`.length)
|
|
|
|
|
|
const keyOffset = source.indexOf('key')
|
|
|
- expect(forNode.keyAlias!.content).toBe('key')
|
|
|
- expect(forNode.keyAlias!.loc.start.offset).toBe(keyOffset)
|
|
|
- expect(forNode.keyAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.keyAlias!.loc.start.column).toBe(keyOffset + 1)
|
|
|
- expect(forNode.keyAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.keyAlias!.loc.end.column).toBe(
|
|
|
- keyOffset + 1 + `key`.length
|
|
|
- )
|
|
|
+ const key = forNode.keyAlias as SimpleExpressionNode
|
|
|
+ expect(key.content).toBe('key')
|
|
|
+ expect(key.loc.start.offset).toBe(keyOffset)
|
|
|
+ expect(key.loc.start.line).toBe(1)
|
|
|
+ expect(key.loc.start.column).toBe(keyOffset + 1)
|
|
|
+ expect(key.loc.end.line).toBe(1)
|
|
|
+ expect(key.loc.end.column).toBe(keyOffset + 1 + `key`.length)
|
|
|
|
|
|
const indexOffset = source.indexOf('index')
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.offset).toBe(indexOffset)
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.column).toBe(indexOffset + 1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.end.column).toBe(
|
|
|
- indexOffset + 1 + `index`.length
|
|
|
- )
|
|
|
+ const index = forNode.objectIndexAlias as SimpleExpressionNode
|
|
|
+ expect(index.content).toBe('index')
|
|
|
+ expect(index.loc.start.offset).toBe(indexOffset)
|
|
|
+ expect(index.loc.start.line).toBe(1)
|
|
|
+ expect(index.loc.start.column).toBe(indexOffset + 1)
|
|
|
+ expect(index.loc.end.line).toBe(1)
|
|
|
+ expect(index.loc.end.column).toBe(indexOffset + 1 + `index`.length)
|
|
|
|
|
|
const itemsOffset = source.indexOf('items')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
@@ -330,27 +361,25 @@ describe('compiler: transform v-for', () => {
|
|
|
|
|
|
test('skipped key', () => {
|
|
|
const source = '<span v-for="( item,, index ) in items" />'
|
|
|
- const forNode = parseWithForTransform(source)
|
|
|
+ const forNode = parseWithForTransform(source) as ForNode
|
|
|
|
|
|
const itemOffset = source.indexOf('item')
|
|
|
- expect(forNode.valueAlias!.content).toBe('item')
|
|
|
- expect(forNode.valueAlias!.loc.start.offset).toBe(itemOffset)
|
|
|
- expect(forNode.valueAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.start.column).toBe(itemOffset + 1)
|
|
|
- expect(forNode.valueAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.valueAlias!.loc.end.column).toBe(
|
|
|
- itemOffset + 1 + `item`.length
|
|
|
- )
|
|
|
+ const value = forNode.valueAlias as SimpleExpressionNode
|
|
|
+ expect(value.content).toBe('item')
|
|
|
+ expect(value.loc.start.offset).toBe(itemOffset)
|
|
|
+ expect(value.loc.start.line).toBe(1)
|
|
|
+ expect(value.loc.start.column).toBe(itemOffset + 1)
|
|
|
+ expect(value.loc.end.line).toBe(1)
|
|
|
+ expect(value.loc.end.column).toBe(itemOffset + 1 + `item`.length)
|
|
|
|
|
|
const indexOffset = source.indexOf('index')
|
|
|
- expect(forNode.objectIndexAlias!.content).toBe('index')
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.offset).toBe(indexOffset)
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.line).toBe(1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.start.column).toBe(indexOffset + 1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.end.line).toBe(1)
|
|
|
- expect(forNode.objectIndexAlias!.loc.end.column).toBe(
|
|
|
- indexOffset + 1 + `index`.length
|
|
|
- )
|
|
|
+ const index = forNode.objectIndexAlias as SimpleExpressionNode
|
|
|
+ expect(index.content).toBe('index')
|
|
|
+ expect(index.loc.start.offset).toBe(indexOffset)
|
|
|
+ expect(index.loc.start.line).toBe(1)
|
|
|
+ expect(index.loc.start.column).toBe(indexOffset + 1)
|
|
|
+ expect(index.loc.end.line).toBe(1)
|
|
|
+ expect(index.loc.end.column).toBe(indexOffset + 1 + `index`.length)
|
|
|
|
|
|
const itemsOffset = source.indexOf('items')
|
|
|
expect((forNode.source as SimpleExpressionNode).content).toBe('items')
|
|
|
@@ -363,4 +392,146 @@ describe('compiler: transform v-for', () => {
|
|
|
)
|
|
|
})
|
|
|
})
|
|
|
+
|
|
|
+ describe('prefixIdentifiers: true', () => {
|
|
|
+ test('should prefix v-for source', () => {
|
|
|
+ const node = parseWithForTransform(`<div v-for="i in list"/>`, {
|
|
|
+ prefixIdentifiers: true
|
|
|
+ }) as ForNode
|
|
|
+ expect(node.source).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `_ctx.list`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('should prefix v-for source w/ complex expression', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div v-for="i in list.concat([foo])"/>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ForNode
|
|
|
+ expect(node.source).toMatchObject({
|
|
|
+ type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
+ children: [
|
|
|
+ { content: `_ctx.list` },
|
|
|
+ `.`,
|
|
|
+ { content: `concat` },
|
|
|
+ `([`,
|
|
|
+ { content: `_ctx.foo` },
|
|
|
+ `])`
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('should not prefix v-for alias', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div v-for="i in list">{{ i }}{{ j }}</div>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ForNode
|
|
|
+ const div = node.children[0] as ElementNode
|
|
|
+ expect((div.children[0] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `i`
|
|
|
+ })
|
|
|
+ expect((div.children[1] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `_ctx.j`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('should not prefix v-for aliases (multiple)', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div v-for="(i, j, k) in list">{{ i + j + k }}{{ l }}</div>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ForNode
|
|
|
+ const div = node.children[0] as ElementNode
|
|
|
+ expect((div.children[0] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
+ children: [
|
|
|
+ { content: `i` },
|
|
|
+ ` + `,
|
|
|
+ { content: `j` },
|
|
|
+ ` + `,
|
|
|
+ { content: `k` }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ expect((div.children[1] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `_ctx.l`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('should prefix id outside of v-for', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div><div v-for="i in list" />{{ i }}</div>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ElementNode
|
|
|
+ expect((node.children[1] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `_ctx.i`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('nested v-for', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div v-for="i in list">
|
|
|
+ <div v-for="i in list">{{ i + j }}</div>{{ i }}
|
|
|
+ </div>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ForNode
|
|
|
+ const outerDiv = node.children[0] as ElementNode
|
|
|
+ const innerFor = outerDiv.children[0] as ForNode
|
|
|
+ const innerExp = (innerFor.children[0] as ElementNode)
|
|
|
+ .children[0] as InterpolationNode
|
|
|
+ expect(innerExp.content).toMatchObject({
|
|
|
+ type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
+ children: [{ content: 'i' }, ` + `, { content: `_ctx.j` }]
|
|
|
+ })
|
|
|
+
|
|
|
+ // when an inner v-for shadows a variable of an outer v-for and exit,
|
|
|
+ // it should not cause the outer v-for's alias to be removed from known ids
|
|
|
+ const outerExp = outerDiv.children[1] as InterpolationNode
|
|
|
+ expect(outerExp.content).toMatchObject({
|
|
|
+ type: NodeTypes.SIMPLE_EXPRESSION,
|
|
|
+ content: `i`
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ test('v-for aliases w/ complex expressions', () => {
|
|
|
+ const node = parseWithForTransform(
|
|
|
+ `<div v-for="({ foo = bar, baz: [qux = quux] }) in list">
|
|
|
+ {{ foo + bar + baz + qux + quux }}
|
|
|
+ </div>`,
|
|
|
+ { prefixIdentifiers: true }
|
|
|
+ ) as ForNode
|
|
|
+ expect(node.valueAlias!).toMatchObject({
|
|
|
+ type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
+ children: [
|
|
|
+ `{ `,
|
|
|
+ { content: `foo` },
|
|
|
+ ` = `,
|
|
|
+ { content: `_ctx.bar` },
|
|
|
+ `, baz: [`,
|
|
|
+ { content: `qux` },
|
|
|
+ ` = `,
|
|
|
+ { content: `_ctx.quux` },
|
|
|
+ `] }`
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ const div = node.children[0] as ElementNode
|
|
|
+ expect((div.children[0] as InterpolationNode).content).toMatchObject({
|
|
|
+ type: NodeTypes.COMPOUND_EXPRESSION,
|
|
|
+ children: [
|
|
|
+ { content: `foo` },
|
|
|
+ ` + `,
|
|
|
+ { content: `_ctx.bar` },
|
|
|
+ ` + `,
|
|
|
+ { content: `_ctx.baz` },
|
|
|
+ ` + `,
|
|
|
+ { content: `qux` },
|
|
|
+ ` + `,
|
|
|
+ { content: `_ctx.quux` }
|
|
|
+ ]
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
})
|