| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- import {
- locStub,
- generate,
- NodeTypes,
- RootNode,
- createSimpleExpression,
- createObjectExpression,
- createObjectProperty,
- createArrayExpression,
- createCompoundExpression,
- createInterpolation,
- createSequenceExpression,
- createCallExpression,
- createConditionalExpression,
- IfCodegenNode,
- ForCodegenNode,
- createCacheExpression
- } from '../src'
- import {
- CREATE_VNODE,
- TO_STRING,
- RESOLVE_DIRECTIVE,
- helperNameMap,
- RESOLVE_COMPONENT,
- CREATE_COMMENT
- } from '../src/runtimeHelpers'
- import { createElementWithCodegen } from './testUtils'
- import { PatchFlags } from '@vue/shared'
- function createRoot(options: Partial<RootNode> = {}): RootNode {
- return {
- type: NodeTypes.ROOT,
- children: [],
- helpers: [],
- components: [],
- directives: [],
- hoists: [],
- cached: 0,
- codegenNode: createSimpleExpression(`null`, false),
- loc: locStub,
- ...options
- }
- }
- describe('compiler: codegen', () => {
- test('module mode preamble', () => {
- const root = createRoot({
- helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
- })
- const { code } = generate(root, { mode: 'module' })
- expect(code).toMatch(
- `import { ${helperNameMap[CREATE_VNODE]}, ${
- helperNameMap[RESOLVE_DIRECTIVE]
- } } from "vue"`
- )
- expect(code).toMatchSnapshot()
- })
- test('function mode preamble', () => {
- const root = createRoot({
- helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
- })
- const { code } = generate(root, { mode: 'function' })
- expect(code).toMatch(`const _Vue = Vue`)
- expect(code).toMatch(
- `const { ${helperNameMap[CREATE_VNODE]}: _${
- helperNameMap[CREATE_VNODE]
- }, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${
- helperNameMap[RESOLVE_DIRECTIVE]
- } } = _Vue`
- )
- expect(code).toMatchSnapshot()
- })
- test('function mode preamble w/ prefixIdentifiers: true', () => {
- const root = createRoot({
- helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
- })
- const { code } = generate(root, {
- mode: 'function',
- prefixIdentifiers: true
- })
- expect(code).not.toMatch(`const _Vue = Vue`)
- expect(code).toMatch(
- `const { ${helperNameMap[CREATE_VNODE]}, ${
- helperNameMap[RESOLVE_DIRECTIVE]
- } } = Vue`
- )
- expect(code).toMatchSnapshot()
- })
- test('assets', () => {
- const root = createRoot({
- components: [`Foo`, `bar-baz`, `barbaz`],
- directives: [`my_dir`]
- })
- const { code } = generate(root, { mode: 'function' })
- expect(code).toMatch(
- `const _component_Foo = _${helperNameMap[RESOLVE_COMPONENT]}("Foo")\n`
- )
- expect(code).toMatch(
- `const _component_bar_baz = _${
- helperNameMap[RESOLVE_COMPONENT]
- }("bar-baz")\n`
- )
- expect(code).toMatch(
- `const _component_barbaz = _${
- helperNameMap[RESOLVE_COMPONENT]
- }("barbaz")\n`
- )
- expect(code).toMatch(
- `const _directive_my_dir = _${
- helperNameMap[RESOLVE_DIRECTIVE]
- }("my_dir")\n`
- )
- expect(code).toMatchSnapshot()
- })
- test('hoists', () => {
- const root = createRoot({
- hoists: [
- createSimpleExpression(`hello`, false, locStub),
- createObjectExpression(
- [
- createObjectProperty(
- createSimpleExpression(`id`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- )
- ],
- locStub
- )
- ]
- })
- const { code } = generate(root)
- expect(code).toMatch(`const _hoisted_1 = hello`)
- expect(code).toMatch(`const _hoisted_2 = { id: "foo" }`)
- expect(code).toMatchSnapshot()
- })
- test('prefixIdentifiers: true should inject _ctx statement', () => {
- const { code } = generate(createRoot(), { prefixIdentifiers: true })
- expect(code).toMatch(`const _ctx = this\n`)
- expect(code).toMatchSnapshot()
- })
- test('static text', () => {
- const { code } = generate(
- createRoot({
- codegenNode: {
- type: NodeTypes.TEXT,
- content: 'hello',
- loc: locStub
- }
- })
- )
- expect(code).toMatch(`return "hello"`)
- expect(code).toMatchSnapshot()
- })
- test('interpolation', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createInterpolation(`hello`, locStub)
- })
- )
- expect(code).toMatch(`return _${helperNameMap[TO_STRING]}(hello)`)
- expect(code).toMatchSnapshot()
- })
- test('comment', () => {
- const { code } = generate(
- createRoot({
- codegenNode: {
- type: NodeTypes.COMMENT,
- content: 'foo',
- loc: locStub
- }
- })
- )
- expect(code).toMatch(`return _${helperNameMap[CREATE_COMMENT]}("foo")`)
- expect(code).toMatchSnapshot()
- })
- test('compound expression', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createCompoundExpression([
- `_ctx.`,
- createSimpleExpression(`foo`, false, locStub),
- ` + `,
- {
- type: NodeTypes.INTERPOLATION,
- loc: locStub,
- content: createSimpleExpression(`bar`, false, locStub)
- }
- ])
- })
- )
- expect(code).toMatch(`return _ctx.foo + _${helperNameMap[TO_STRING]}(bar)`)
- expect(code).toMatchSnapshot()
- })
- test('ifNode', () => {
- const { code } = generate(
- createRoot({
- codegenNode: {
- type: NodeTypes.IF,
- loc: locStub,
- branches: [],
- codegenNode: createSequenceExpression([
- createSimpleExpression('foo', false),
- createSimpleExpression('bar', false)
- ]) as IfCodegenNode
- }
- })
- )
- expect(code).toMatch(`return (foo, bar)`)
- expect(code).toMatchSnapshot()
- })
- test('forNode', () => {
- const { code } = generate(
- createRoot({
- codegenNode: {
- type: NodeTypes.FOR,
- loc: locStub,
- source: createSimpleExpression('foo', false),
- valueAlias: undefined,
- keyAlias: undefined,
- objectIndexAlias: undefined,
- children: [],
- codegenNode: createSequenceExpression([
- createSimpleExpression('foo', false),
- createSimpleExpression('bar', false)
- ]) as ForCodegenNode
- }
- })
- )
- expect(code).toMatch(`return (foo, bar)`)
- expect(code).toMatchSnapshot()
- })
- test('Element (callExpression + objectExpression + TemplateChildNode[])', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createElementWithCodegen([
- // string
- `"div"`,
- // ObjectExpression
- createObjectExpression(
- [
- createObjectProperty(
- createSimpleExpression(`id`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- ),
- createObjectProperty(
- createSimpleExpression(`prop`, false, locStub),
- createSimpleExpression(`bar`, false, locStub)
- ),
- // compound expression as computed key
- createObjectProperty(
- {
- type: NodeTypes.COMPOUND_EXPRESSION,
- loc: locStub,
- children: [
- `foo + `,
- createSimpleExpression(`bar`, false, locStub)
- ]
- },
- createSimpleExpression(`bar`, false, locStub)
- )
- ],
- locStub
- ),
- // ChildNode[]
- [
- createElementWithCodegen([
- `"p"`,
- createObjectExpression(
- [
- createObjectProperty(
- // should quote the key!
- createSimpleExpression(`some-key`, true, locStub),
- createSimpleExpression(`foo`, true, locStub)
- )
- ],
- locStub
- )
- ])
- ],
- // flag
- PatchFlags.FULL_PROPS + ''
- ])
- })
- )
- expect(code).toMatch(`
- return _${helperNameMap[CREATE_VNODE]}("div", {
- id: "foo",
- [prop]: bar,
- [foo + bar]: bar
- }, [
- _${helperNameMap[CREATE_VNODE]}("p", { "some-key": "foo" })
- ], ${PatchFlags.FULL_PROPS})`)
- expect(code).toMatchSnapshot()
- })
- test('ArrayExpression', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createArrayExpression([
- createSimpleExpression(`foo`, false),
- createCallExpression(`bar`, [`baz`])
- ])
- })
- )
- expect(code).toMatch(`return [
- foo,
- bar(baz)
- ]`)
- expect(code).toMatchSnapshot()
- })
- test('SequenceExpression', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createSequenceExpression([
- createSimpleExpression(`foo`, false),
- createCallExpression(`bar`, [`baz`])
- ])
- })
- )
- expect(code).toMatch(`return (foo, bar(baz))`)
- expect(code).toMatchSnapshot()
- })
- test('ConditionalExpression', () => {
- const { code } = generate(
- createRoot({
- codegenNode: createConditionalExpression(
- createSimpleExpression(`ok`, false),
- createCallExpression(`foo`),
- createConditionalExpression(
- createSimpleExpression(`orNot`, false),
- createCallExpression(`bar`),
- createCallExpression(`baz`)
- )
- )
- })
- )
- expect(code).toMatch(
- `return ok
- ? foo()
- : orNot
- ? bar()
- : baz()`
- )
- expect(code).toMatchSnapshot()
- })
- test('CacheExpression', () => {
- const { code } = generate(
- createRoot({
- cached: 1,
- codegenNode: createCacheExpression(
- 1,
- createSimpleExpression(`foo`, false)
- )
- }),
- {
- mode: 'module',
- prefixIdentifiers: true
- }
- )
- expect(code).toMatch(`const _cache = _ctx.$cache`)
- expect(code).toMatch(`_cache[1] || (_cache[1] = foo)`)
- expect(code).toMatchSnapshot()
- })
- test('CacheExpression w/ isVNode: true', () => {
- const { code } = generate(
- createRoot({
- cached: 1,
- codegenNode: createCacheExpression(
- 1,
- createSimpleExpression(`foo`, false),
- true
- )
- }),
- {
- mode: 'module',
- prefixIdentifiers: true
- }
- )
- expect(code).toMatch(`const _cache = _ctx.$cache`)
- expect(code).toMatch(
- `
- _cache[1] || (
- setBlockTracking(-1),
- _cache[1] = foo,
- setBlockTracking(1),
- _cache[1]
- )
- `.trim()
- )
- expect(code).toMatchSnapshot()
- })
- })
|