diff --git a/packages/compiler-core/__tests__/directives/vFor.spec.ts b/packages/compiler-core/__tests__/directives/vFor.spec.ts
index 9a937d45..b23537e3 100644
--- a/packages/compiler-core/__tests__/directives/vFor.spec.ts
+++ b/packages/compiler-core/__tests__/directives/vFor.spec.ts
@@ -5,292 +5,9 @@ import { ForNode, NodeTypes } from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
describe('v-for', () => {
- test('number expression', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('index')
- expect(forNode.source.content).toBe('5')
- })
-
- test('value', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('object de-structured value', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('{ id, value }')
- expect(forNode.source.content).toBe('items')
- })
-
- test('array de-structured value', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('[ id, value ]')
- expect(forNode.source.content).toBe('items')
- })
-
- test('value and key', () => {
- const node = parse('')
-
- transform(node, { transforms: [transformFor] })
-
- expect(node.children.length).toBe(1)
-
- 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')
- })
-
- test('value, key and index', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('skipped key', () => {
- const node = parse('')
-
- transform(node, { transforms: [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!.content).toBe('value')
- expect(forNode.source.content).toBe('items')
- })
-
- test('skipped value and key', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('unbracketed value', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('')
-
- transform(node, { transforms: [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('')
-
- transform(node, { transforms: [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('')
-
- transform(node, { transforms: [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!.content).toBe('value')
- expect(forNode.source.content).toBe('items')
- })
-
- test('unbracketed skipped value and key', () => {
- const node = parse('')
-
- transform(node, { transforms: [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('')
- const onError = jest.fn()
- transform(node, { transforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_NO_EXPRESSION
- })
- )
- })
-
- test('empty expression', () => {
- const node = parse('')
- const onError = jest.fn()
- transform(node, { transforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
- )
- })
-
- test('invalid expression', () => {
- const node = parse('')
- const onError = jest.fn()
- transform(node, { transforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
- )
- })
-
- test('missing source', () => {
- const node = parse('')
- const onError = jest.fn()
- transform(node, { transforms: [transformFor], onError })
-
- expect(onError).toHaveBeenCalledTimes(1)
- expect(onError).toHaveBeenCalledWith(
- expect.objectContaining({
- code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
- })
- )
- })
-
- test('missing value', () => {
- const node = parse('')
- const onError = jest.fn()
- transform(node, { transforms: [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 = ''
- const node = parse(source)
+ describe('transform', () => {
+ test('number expression', () => {
+ const node = parse('')
transform(node, { transforms: [transformFor] })
@@ -299,29 +16,14 @@ describe('v-for', () => {
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)
+ expect(forNode.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('index')
+ expect(forNode.source.content).toBe('5')
})
- test('bracketed value', () => {
- const source = ''
- const node = parse(source)
+ test('value', () => {
+ const node = parse('')
transform(node, { transforms: [transformFor] })
@@ -330,29 +32,14 @@ describe('v-for', () => {
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('de-structured value', () => {
- const source = ''
- const node = parse(source)
+ test('object de-structured value', () => {
+ const node = parse('')
transform(node, { transforms: [transformFor] })
@@ -361,31 +48,14 @@ describe('v-for', () => {
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.keyAlias).toBeUndefined()
+ expect(forNode.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('{ id, value }')
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 = ''
- const node = parse(source)
+ test('array de-structured value', () => {
+ const node = parse('')
transform(node, { transforms: [transformFor] })
@@ -394,48 +64,30 @@ describe('v-for', () => {
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.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
- )
+ test('value and key', () => {
+ const node = parse('')
+ transform(node, { transforms: [transformFor] })
+
+ expect(node.children.length).toBe(1)
+
+ const forNode = node.children[0] as ForNode
+
+ expect(forNode.keyAlias).not.toBeUndefined()
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.objectIndexAlias).toBeUndefined()
+ expect(forNode.valueAlias!.content).toBe('item')
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 = ''
- const node = parse(source)
+
+ test('value, key and index', () => {
+ const node = parse('')
transform(node, { transforms: [transformFor] })
@@ -444,37 +96,408 @@ describe('v-for', () => {
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).not.toBeUndefined()
+ expect(forNode.keyAlias!.content).toBe('key')
+ expect(forNode.objectIndexAlias).not.toBeUndefined()
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.valueAlias!.content).toBe('value')
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 node = parse('')
+
+ transform(node, { transforms: [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!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('skipped value and key', () => {
+ const node = parse('')
+
+ transform(node, { transforms: [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('unbracketed value', () => {
+ const node = parse('')
+
+ transform(node, { transforms: [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('')
+
+ transform(node, { transforms: [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('')
+
+ transform(node, { transforms: [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('')
+
+ transform(node, { transforms: [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!.content).toBe('value')
+ expect(forNode.source.content).toBe('items')
+ })
+
+ test('unbracketed skipped value and key', () => {
+ const node = parse('')
+
+ transform(node, { transforms: [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('')
+ const onError = jest.fn()
+ transform(node, { transforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_NO_EXPRESSION
+ })
+ )
+ })
+
+ test('empty expression', () => {
+ const node = parse('')
+ const onError = jest.fn()
+ transform(node, { transforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('invalid expression', () => {
+ const node = parse('')
+ const onError = jest.fn()
+ transform(node, { transforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('missing source', () => {
+ const node = parse('')
+ const onError = jest.fn()
+ transform(node, { transforms: [transformFor], onError })
+
+ expect(onError).toHaveBeenCalledTimes(1)
+ expect(onError).toHaveBeenCalledWith(
+ expect.objectContaining({
+ code: ErrorCodes.X_FOR_MALFORMED_EXPRESSION
+ })
+ )
+ })
+
+ test('missing value', () => {
+ const node = parse('')
+ const onError = jest.fn()
+ transform(node, { transforms: [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 = ''
+ const node = parse(source)
+
+ transform(node, { transforms: [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 = ''
+ const node = parse(source)
+
+ transform(node, { transforms: [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 = ''
+ const node = parse(source)
+
+ transform(node, { transforms: [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 = ''
+ const node = parse(source)
+
+ transform(node, { transforms: [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 = ''
+ const node = parse(source)
+
+ transform(node, { transforms: [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)
+ })
})
})
})