wip: test for transformExpression

This commit is contained in:
Evan You 2019-09-23 21:22:52 -04:00
parent acfa7bd46e
commit 4a82e7cdbc
3 changed files with 110 additions and 20 deletions

View File

@ -1,8 +1,93 @@
import { compile } from '../../src' import {
parse,
transform,
ExpressionNode,
ElementNode,
DirectiveNode
} from '../../src'
import { transformFor } from '../..//src/transforms/vFor'
import { transformExpression } from '../../src/transforms/transformExpression'
test(`should work`, () => { function parseWithExpressionTransform(template: string) {
const { code } = compile(`<div>{{ foo }} bar</div>`, { const ast = parse(template)
prefixIdentifiers: true transform(ast, {
prefixIdentifiers: true,
nodeTransforms: [transformFor, transformExpression]
}) })
expect(code).toContain(`foo`) return ast.children[0]
}
describe('compiler: expression transform', () => {
test('interpolation (root)', () => {
const node = parseWithExpressionTransform(`{{ foo }}`) as ExpressionNode
expect(node.content).toBe(`_ctx.foo`)
})
test('interpolation (children)', () => {
const node = parseWithExpressionTransform(
`<div>{{ foo }}</div>`
) as ElementNode
expect((node.children[0] as ExpressionNode).content).toBe(`_ctx.foo`)
})
test('directive value', () => {
const node = parseWithExpressionTransform(
`<div v-foo:arg="baz"/>`
) as ElementNode
expect((node.props[0] as DirectiveNode).arg!.content).toBe(`arg`)
expect((node.props[0] as DirectiveNode).exp!.content).toBe(`_ctx.baz`)
})
test('dynamic directive arg', () => {
const node = parseWithExpressionTransform(
`<div v-foo:[arg]="baz"/>`
) as ElementNode
expect((node.props[0] as DirectiveNode).arg!.content).toBe(`_ctx.arg`)
expect((node.props[0] as DirectiveNode).exp!.content).toBe(`_ctx.baz`)
})
test('should prefix complex expressions', () => {
const node = parseWithExpressionTransform(
`{{ foo(baz + 1, { key: kuz }) }}`
) as ExpressionNode
// should parse into compound expression
expect(node.children).toMatchObject([
{ content: `_ctx.foo` },
`(`,
{ content: `_ctx.baz` },
` + 1, { key: `,
{ content: `_ctx.kuz` },
` })`
])
})
// TODO FIXME
test('should not prefix v-for aliases', () => {
// const node = parseWithExpressionTransform(`{{ { foo } }}`) as ExpressionNode
// expect(node.children).toMatchObject([
// `{ foo: `,
// { content: `_ctx.foo` },
// ` }`
// ])
})
test('should prefix id outside of v-for', () => {})
test('nested v-for', () => {})
test('should not prefix whitelisted globals', () => {})
test('should not prefix id of a function declaration', () => {})
test('should not prefix params of a function expression', () => {
// also test object + array destructure
})
test('should not prefix an object property key', () => {})
test('should prefix a computed object property key', () => {})
test('should prefix object property shorthand value', () => {})
test('should not prefix id in a member expression', () => {})
}) })

View File

@ -294,17 +294,18 @@ function genExpressionAsPropertyKey(
node: ExpressionNode, node: ExpressionNode,
context: CodegenContext context: CodegenContext
) { ) {
if (node.children) { const { push } = context
return genCompoundExpression(node, context) const { content, children, isStatic } = node
} if (children) {
if (node.isStatic) { push(`[`)
genCompoundExpression(node, context)
push(`]`)
} else if (isStatic) {
// only quote keys if necessary // only quote keys if necessary
const text = /^\d|[^\w]/.test(node.content) const text = /^\d|[^\w]/.test(content) ? JSON.stringify(content) : content
? JSON.stringify(node.content) push(text, node)
: node.content
context.push(text, node)
} else { } else {
context.push(`[${node.content}]`, node) push(`[${content}]`, node)
} }
} }

View File

@ -74,11 +74,13 @@ export function processExpression(
walk(ast, { walk(ast, {
enter(node, parent) { enter(node, parent) {
if (node.type === 'Identifier') { if (node.type === 'Identifier') {
if (ids.indexOf(node) === -1) { if (
ids.push(node) ids.indexOf(node) === -1 &&
if (!knownIds[node.name] && shouldPrefix(node, parent)) { !knownIds[node.name] &&
shouldPrefix(node, parent)
) {
node.name = `_ctx.${node.name}` node.name = `_ctx.${node.name}`
} ids.push(node)
} }
} else if (isFunction(node)) { } else if (isFunction(node)) {
node.params.forEach(p => node.params.forEach(p =>
@ -123,12 +125,14 @@ export function processExpression(
}) })
) )
if (i === ids.length - 1 && id.end < full.length - 1) { if (i === ids.length - 1 && id.end < full.length - 1) {
children.push(full.slice(id.end)) children.push(full.slice(id.end - 1))
} }
}) })
if (children.length) {
node.children = children node.children = children
} }
}
const globals = new Set( const globals = new Set(
( (