test(compiler): codegen tests for Sequence & Conditional expressions

This commit is contained in:
Evan You 2019-10-01 15:43:59 -04:00
parent ed111cd37b
commit aa134e7a4f
4 changed files with 176 additions and 109 deletions

View File

@ -1,5 +1,27 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler: codegen ConditionalExpression 1`] = `
"
return function render() {
with (this) {
return (foo, ok
? foo()
: orNot
? bar()
: baz())
}
}"
`;
exports[`compiler: codegen SequenceExpression 1`] = `
"
return function render() {
with (this) {
return (foo, bar(baz))
}
}"
`;
exports[`compiler: codegen SlotFunctionExpression 1`] = ` exports[`compiler: codegen SlotFunctionExpression 1`] = `
" "
return function render() { return function render() {

View File

@ -1,19 +1,19 @@
import { import {
locStub,
generate, generate,
NodeTypes, NodeTypes,
RootNode, RootNode,
SourceLocation,
createSimpleExpression, createSimpleExpression,
Namespaces, Namespaces,
ElementTypes, ElementTypes,
CallExpression,
createObjectExpression, createObjectExpression,
createObjectProperty, createObjectProperty,
createArrayExpression, createArrayExpression,
ElementNode,
createCompoundExpression, createCompoundExpression,
createInterpolation, createInterpolation,
createSequenceExpression createSequenceExpression,
createCallExpression,
createConditionalExpression
} from '../src' } from '../src'
import { import {
CREATE_VNODE, CREATE_VNODE,
@ -21,20 +21,7 @@ import {
TO_STRING, TO_STRING,
RENDER_LIST RENDER_LIST
} from '../src/runtimeConstants' } from '../src/runtimeConstants'
import { createElementWithCodegen } from './testUtils'
const mockLoc: SourceLocation = {
source: ``,
start: {
offset: 0,
line: 1,
column: 1
},
end: {
offset: 3,
line: 1,
column: 4
}
}
function createRoot(options: Partial<RootNode> = {}): RootNode { function createRoot(options: Partial<RootNode> = {}): RootNode {
return { return {
@ -43,7 +30,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
imports: [], imports: [],
statements: [], statements: [],
hoists: [], hoists: [],
loc: mockLoc, loc: locStub,
...options ...options
} }
} }
@ -96,15 +83,15 @@ describe('compiler: codegen', () => {
test('hoists', () => { test('hoists', () => {
const root = createRoot({ const root = createRoot({
hoists: [ hoists: [
createSimpleExpression(`hello`, false, mockLoc), createSimpleExpression(`hello`, false, locStub),
createObjectExpression( createObjectExpression(
[ [
createObjectProperty( createObjectProperty(
createSimpleExpression(`id`, true, mockLoc), createSimpleExpression(`id`, true, locStub),
createSimpleExpression(`foo`, true, mockLoc) createSimpleExpression(`foo`, true, locStub)
) )
], ],
mockLoc locStub
) )
] ]
}) })
@ -128,7 +115,7 @@ describe('compiler: codegen', () => {
type: NodeTypes.TEXT, type: NodeTypes.TEXT,
content: 'hello', content: 'hello',
isEmpty: false, isEmpty: false,
loc: mockLoc loc: locStub
} }
] ]
}) })
@ -140,7 +127,7 @@ describe('compiler: codegen', () => {
test('interpolation', () => { test('interpolation', () => {
const { code } = generate( const { code } = generate(
createRoot({ createRoot({
children: [createInterpolation(`hello`, mockLoc)] children: [createInterpolation(`hello`, locStub)]
}) })
) )
expect(code).toMatch(`return _${TO_STRING}(hello)`) expect(code).toMatch(`return _${TO_STRING}(hello)`)
@ -154,7 +141,7 @@ describe('compiler: codegen', () => {
{ {
type: NodeTypes.COMMENT, type: NodeTypes.COMMENT,
content: 'foo', content: 'foo',
loc: mockLoc loc: locStub
} }
] ]
}) })
@ -171,13 +158,13 @@ describe('compiler: codegen', () => {
type: NodeTypes.TEXT, type: NodeTypes.TEXT,
content: 'foo', content: 'foo',
isEmpty: false, isEmpty: false,
loc: mockLoc loc: locStub
}, },
createInterpolation(`hello`, mockLoc), createInterpolation(`hello`, locStub),
{ {
type: NodeTypes.COMMENT, type: NodeTypes.COMMENT,
content: 'foo', content: 'foo',
loc: mockLoc loc: locStub
} }
] ]
}) })
@ -199,13 +186,13 @@ describe('compiler: codegen', () => {
type: NodeTypes.TEXT, type: NodeTypes.TEXT,
content: 'foo', content: 'foo',
isEmpty: false, isEmpty: false,
loc: mockLoc loc: locStub
}, },
createInterpolation(`hello`, mockLoc), createInterpolation(`hello`, locStub),
{ {
type: NodeTypes.COMMENT, type: NodeTypes.COMMENT,
content: 'foo', content: 'foo',
loc: mockLoc loc: locStub
} }
] ]
}), }),
@ -228,12 +215,12 @@ describe('compiler: codegen', () => {
children: [ children: [
createCompoundExpression([ createCompoundExpression([
`_ctx.`, `_ctx.`,
createSimpleExpression(`foo`, false, mockLoc), createSimpleExpression(`foo`, false, locStub),
` + `, ` + `,
{ {
type: NodeTypes.INTERPOLATION, type: NodeTypes.INTERPOLATION,
loc: mockLoc, loc: locStub,
content: createSimpleExpression(`bar`, false, mockLoc) content: createSimpleExpression(`bar`, false, locStub)
} }
]) ])
] ]
@ -249,7 +236,7 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.IF, type: NodeTypes.IF,
loc: mockLoc, loc: locStub,
branches: [], branches: [],
codegenNode: createSequenceExpression([ codegenNode: createSequenceExpression([
createSimpleExpression('foo', false), createSimpleExpression('foo', false),
@ -269,12 +256,12 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.FOR, type: NodeTypes.FOR,
loc: mockLoc, loc: locStub,
source: createSimpleExpression(`list`, false, mockLoc), source: createSimpleExpression(`list`, false, locStub),
valueAlias: createSimpleExpression(`v`, false, mockLoc), valueAlias: createSimpleExpression(`v`, false, locStub),
keyAlias: createSimpleExpression(`k`, false, mockLoc), keyAlias: createSimpleExpression(`k`, false, locStub),
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc), objectIndexAlias: createSimpleExpression(`i`, false, locStub),
children: [createInterpolation(`v`, mockLoc)] children: [createInterpolation(`v`, locStub)]
} }
] ]
}) })
@ -293,12 +280,12 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.FOR, type: NodeTypes.FOR,
loc: mockLoc, loc: locStub,
source: createSimpleExpression(`list`, false, mockLoc), source: createSimpleExpression(`list`, false, locStub),
valueAlias: createSimpleExpression(`v`, false, mockLoc), valueAlias: createSimpleExpression(`v`, false, locStub),
keyAlias: createSimpleExpression(`k`, false, mockLoc), keyAlias: createSimpleExpression(`k`, false, locStub),
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc), objectIndexAlias: createSimpleExpression(`i`, false, locStub),
children: [createInterpolation(`v`, mockLoc)] children: [createInterpolation(`v`, locStub)]
} }
] ]
}), }),
@ -320,12 +307,12 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.FOR, type: NodeTypes.FOR,
loc: mockLoc, loc: locStub,
source: createSimpleExpression(`list`, false, mockLoc), source: createSimpleExpression(`list`, false, locStub),
valueAlias: undefined, valueAlias: undefined,
keyAlias: createSimpleExpression(`k`, false, mockLoc), keyAlias: createSimpleExpression(`k`, false, locStub),
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc), objectIndexAlias: createSimpleExpression(`i`, false, locStub),
children: [createInterpolation(`v`, mockLoc)] children: [createInterpolation(`v`, locStub)]
} }
] ]
}) })
@ -344,12 +331,12 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.FOR, type: NodeTypes.FOR,
loc: mockLoc, loc: locStub,
source: createSimpleExpression(`list`, false, mockLoc), source: createSimpleExpression(`list`, false, locStub),
valueAlias: createSimpleExpression(`v`, false, mockLoc), valueAlias: createSimpleExpression(`v`, false, locStub),
keyAlias: undefined, keyAlias: undefined,
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc), objectIndexAlias: createSimpleExpression(`i`, false, locStub),
children: [createInterpolation(`v`, mockLoc)] children: [createInterpolation(`v`, locStub)]
} }
] ]
}) })
@ -368,12 +355,12 @@ describe('compiler: codegen', () => {
children: [ children: [
{ {
type: NodeTypes.FOR, type: NodeTypes.FOR,
loc: mockLoc, loc: locStub,
source: createSimpleExpression(`list`, false, mockLoc), source: createSimpleExpression(`list`, false, locStub),
valueAlias: undefined, valueAlias: undefined,
keyAlias: undefined, keyAlias: undefined,
objectIndexAlias: createSimpleExpression(`i`, false, mockLoc), objectIndexAlias: createSimpleExpression(`i`, false, locStub),
children: [createInterpolation(`v`, mockLoc)] children: [createInterpolation(`v`, locStub)]
} }
] ]
}) })
@ -396,47 +383,47 @@ describe('compiler: codegen', () => {
ns: Namespaces.HTML, ns: Namespaces.HTML,
isSelfClosing: false, isSelfClosing: false,
tag: `Comp`, tag: `Comp`,
loc: mockLoc, loc: locStub,
props: [], props: [],
children: [], children: [],
codegenNode: { codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
loc: mockLoc, loc: locStub,
callee: `_${CREATE_VNODE}`, callee: `_${CREATE_VNODE}`,
arguments: [ arguments: [
`Comp`, `Comp`,
`0`, `0`,
{ {
type: NodeTypes.JS_OBJECT_EXPRESSION, type: NodeTypes.JS_OBJECT_EXPRESSION,
loc: mockLoc, loc: locStub,
properties: [ properties: [
{ {
type: NodeTypes.JS_PROPERTY, type: NodeTypes.JS_PROPERTY,
loc: mockLoc, loc: locStub,
key: { key: {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: true, isStatic: true,
content: `default`, content: `default`,
loc: mockLoc loc: locStub
}, },
value: { value: {
type: NodeTypes.JS_SLOT_FUNCTION, type: NodeTypes.JS_SLOT_FUNCTION,
loc: mockLoc, loc: locStub,
params: { params: {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: false, isStatic: false,
content: `{ foo }`, content: `{ foo }`,
loc: mockLoc loc: locStub
}, },
returns: [ returns: [
{ {
type: NodeTypes.INTERPOLATION, type: NodeTypes.INTERPOLATION,
loc: mockLoc, loc: locStub,
content: { content: {
type: NodeTypes.SIMPLE_EXPRESSION, type: NodeTypes.SIMPLE_EXPRESSION,
isStatic: false, isStatic: false,
content: `foo`, content: `foo`,
loc: mockLoc loc: locStub
} }
} }
] ]
@ -461,27 +448,6 @@ describe('compiler: codegen', () => {
}) })
test('callExpression + objectExpression + arrayExpression', () => { test('callExpression + objectExpression + arrayExpression', () => {
function createElementWithCodegen(
args: CallExpression['arguments']
): ElementNode {
return {
type: NodeTypes.ELEMENT,
loc: mockLoc,
ns: Namespaces.HTML,
tag: 'div',
tagType: ElementTypes.ELEMENT,
isSelfClosing: false,
props: [],
children: [],
codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION,
loc: mockLoc,
callee: CREATE_VNODE,
arguments: args
}
}
}
const { code } = generate( const { code } = generate(
createRoot({ createRoot({
children: [ children: [
@ -492,27 +458,27 @@ describe('compiler: codegen', () => {
createObjectExpression( createObjectExpression(
[ [
createObjectProperty( createObjectProperty(
createSimpleExpression(`id`, true, mockLoc), createSimpleExpression(`id`, true, locStub),
createSimpleExpression(`foo`, true, mockLoc) createSimpleExpression(`foo`, true, locStub)
), ),
createObjectProperty( createObjectProperty(
createSimpleExpression(`prop`, false, mockLoc), createSimpleExpression(`prop`, false, locStub),
createSimpleExpression(`bar`, false, mockLoc) createSimpleExpression(`bar`, false, locStub)
), ),
// compound expression as computed key // compound expression as computed key
createObjectProperty( createObjectProperty(
{ {
type: NodeTypes.COMPOUND_EXPRESSION, type: NodeTypes.COMPOUND_EXPRESSION,
loc: mockLoc, loc: locStub,
children: [ children: [
`foo + `, `foo + `,
createSimpleExpression(`bar`, false, mockLoc) createSimpleExpression(`bar`, false, locStub)
] ]
}, },
createSimpleExpression(`bar`, false, mockLoc) createSimpleExpression(`bar`, false, locStub)
) )
], ],
mockLoc locStub
), ),
// ChildNode[] // ChildNode[]
[ [
@ -522,11 +488,11 @@ describe('compiler: codegen', () => {
[ [
createObjectProperty( createObjectProperty(
// should quote the key! // should quote the key!
createSimpleExpression(`some-key`, true, mockLoc), createSimpleExpression(`some-key`, true, locStub),
createSimpleExpression(`foo`, true, mockLoc) createSimpleExpression(`foo`, true, locStub)
) )
], ],
mockLoc locStub
) )
]) ])
], ],
@ -536,12 +502,12 @@ describe('compiler: codegen', () => {
'foo', 'foo',
{ {
type: NodeTypes.JS_CALL_EXPRESSION, type: NodeTypes.JS_CALL_EXPRESSION,
loc: mockLoc, loc: locStub,
callee: CREATE_VNODE, callee: CREATE_VNODE,
arguments: [`"p"`] arguments: [`"p"`]
} }
], ],
mockLoc locStub
) )
]) ])
] ]
@ -561,7 +527,57 @@ describe('compiler: codegen', () => {
expect(code).toMatchSnapshot() expect(code).toMatchSnapshot()
}) })
test.todo('SequenceExpression') test('SequenceExpression', () => {
const { code } = generate(
test.todo('ConditionalExpression') createRoot({
children: [
{
type: NodeTypes.IF,
loc: locStub,
branches: [],
codegenNode: createSequenceExpression([
createSimpleExpression(`foo`, false),
createCallExpression(`bar`, [`baz`])
])
}
]
})
)
expect(code).toMatch(`return (foo, bar(baz))`)
expect(code).toMatchSnapshot()
})
test('ConditionalExpression', () => {
const { code } = generate(
createRoot({
children: [
{
type: NodeTypes.IF,
loc: locStub,
branches: [],
codegenNode: createSequenceExpression([
createSimpleExpression(`foo`, false),
createConditionalExpression(
createSimpleExpression(`ok`, false),
createCallExpression(`foo`),
createConditionalExpression(
createSimpleExpression(`orNot`, false),
createCallExpression(`bar`),
createCallExpression(`baz`)
)
)
])
}
]
})
)
expect(code).toMatch(
`return (foo, ok
? foo()
: orNot
? bar()
: baz())`
)
expect(code).toMatchSnapshot()
})
}) })

View File

@ -1,4 +1,12 @@
import { NodeTypes } from '../src' import {
NodeTypes,
CallExpression,
ElementNode,
locStub,
Namespaces,
ElementTypes
} from '../src'
import { CREATE_VNODE } from '../src/runtimeConstants'
const leadingBracketRE = /^\[/ const leadingBracketRE = /^\[/
const bracketsRE = /^\[|\]$/g const bracketsRE = /^\[|\]$/g
@ -26,3 +34,24 @@ export function createObjectMatcher(obj: any) {
})) }))
} }
} }
export function createElementWithCodegen(
args: CallExpression['arguments']
): ElementNode {
return {
type: NodeTypes.ELEMENT,
loc: locStub,
ns: Namespaces.HTML,
tag: 'div',
tagType: ElementTypes.ELEMENT,
isSelfClosing: false,
props: [],
children: [],
codegenNode: {
type: NodeTypes.JS_CALL_EXPRESSION,
loc: locStub,
callee: CREATE_VNODE,
arguments: args
}
}
}

View File

@ -217,7 +217,7 @@ export interface ConditionalExpression extends Node {
// Some expressions, e.g. sequence and conditional expressions, are never // Some expressions, e.g. sequence and conditional expressions, are never
// associated with template nodes, so their source locations are just a stub. // associated with template nodes, so their source locations are just a stub.
// Container types like CompoundExpression also don't need a real location. // Container types like CompoundExpression also don't need a real location.
const locStub: SourceLocation = { export const locStub: SourceLocation = {
source: '', source: '',
start: { line: 1, column: 1, offset: 0 }, start: { line: 1, column: 1, offset: 0 },
end: { line: 1, column: 1, offset: 0 } end: { line: 1, column: 1, offset: 0 }