codegen.spec.ts 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. import {
  2. locStub,
  3. generate,
  4. NodeTypes,
  5. RootNode,
  6. createSimpleExpression,
  7. createObjectExpression,
  8. createObjectProperty,
  9. createArrayExpression,
  10. createCompoundExpression,
  11. createInterpolation,
  12. createCallExpression,
  13. createConditionalExpression,
  14. ForCodegenNode,
  15. createCacheExpression,
  16. createTemplateLiteral,
  17. createBlockStatement,
  18. createIfStatement,
  19. createAssignmentExpression,
  20. IfConditionalExpression,
  21. createVNodeCall,
  22. VNodeCall,
  23. DirectiveArguments,
  24. ConstantTypes
  25. } from '../src'
  26. import {
  27. CREATE_VNODE,
  28. TO_DISPLAY_STRING,
  29. RESOLVE_DIRECTIVE,
  30. helperNameMap,
  31. RESOLVE_COMPONENT,
  32. CREATE_COMMENT,
  33. FRAGMENT,
  34. RENDER_LIST,
  35. CREATE_ELEMENT_VNODE
  36. } from '../src/runtimeHelpers'
  37. import { createElementWithCodegen, genFlagText } from './testUtils'
  38. import { PatchFlags } from '@vue/shared'
  39. function createRoot(options: Partial<RootNode> = {}): RootNode {
  40. return {
  41. type: NodeTypes.ROOT,
  42. children: [],
  43. helpers: [],
  44. components: [],
  45. directives: [],
  46. imports: [],
  47. hoists: [],
  48. cached: 0,
  49. temps: 0,
  50. codegenNode: createSimpleExpression(`null`, false),
  51. loc: locStub,
  52. ...options
  53. }
  54. }
  55. describe('compiler: codegen', () => {
  56. test('module mode preamble', () => {
  57. const root = createRoot({
  58. helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
  59. })
  60. const { code } = generate(root, { mode: 'module' })
  61. expect(code).toMatch(
  62. `import { ${helperNameMap[CREATE_VNODE]} as _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} as _${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`
  63. )
  64. expect(code).toMatchSnapshot()
  65. })
  66. test('module mode preamble w/ optimizeImports: true', () => {
  67. const root = createRoot({
  68. helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
  69. })
  70. const { code } = generate(root, { mode: 'module', optimizeImports: true })
  71. expect(code).toMatch(
  72. `import { ${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]} } from "vue"`
  73. )
  74. expect(code).toMatch(
  75. `const _${helperNameMap[CREATE_VNODE]} = ${helperNameMap[CREATE_VNODE]}, _${helperNameMap[RESOLVE_DIRECTIVE]} = ${helperNameMap[RESOLVE_DIRECTIVE]}`
  76. )
  77. expect(code).toMatchSnapshot()
  78. })
  79. test('function mode preamble', () => {
  80. const root = createRoot({
  81. helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
  82. })
  83. const { code } = generate(root, { mode: 'function' })
  84. expect(code).toMatch(`const _Vue = Vue`)
  85. expect(code).toMatch(
  86. `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = _Vue`
  87. )
  88. expect(code).toMatchSnapshot()
  89. })
  90. test('function mode preamble w/ prefixIdentifiers: true', () => {
  91. const root = createRoot({
  92. helpers: [CREATE_VNODE, RESOLVE_DIRECTIVE]
  93. })
  94. const { code } = generate(root, {
  95. mode: 'function',
  96. prefixIdentifiers: true
  97. })
  98. expect(code).not.toMatch(`const _Vue = Vue`)
  99. expect(code).toMatch(
  100. `const { ${helperNameMap[CREATE_VNODE]}: _${helperNameMap[CREATE_VNODE]}, ${helperNameMap[RESOLVE_DIRECTIVE]}: _${helperNameMap[RESOLVE_DIRECTIVE]} } = Vue`
  101. )
  102. expect(code).toMatchSnapshot()
  103. })
  104. test('assets + temps', () => {
  105. const root = createRoot({
  106. components: [`Foo`, `bar-baz`, `barbaz`, `Qux__self`],
  107. directives: [`my_dir_0`, `my_dir_1`],
  108. temps: 3
  109. })
  110. const { code } = generate(root, { mode: 'function' })
  111. expect(code).toMatch(
  112. `const _component_Foo = _${helperNameMap[RESOLVE_COMPONENT]}("Foo")\n`
  113. )
  114. expect(code).toMatch(
  115. `const _component_bar_baz = _${helperNameMap[RESOLVE_COMPONENT]}("bar-baz")\n`
  116. )
  117. expect(code).toMatch(
  118. `const _component_barbaz = _${helperNameMap[RESOLVE_COMPONENT]}("barbaz")\n`
  119. )
  120. // implicit self reference from SFC filename
  121. expect(code).toMatch(
  122. `const _component_Qux = _${helperNameMap[RESOLVE_COMPONENT]}("Qux", true)\n`
  123. )
  124. expect(code).toMatch(
  125. `const _directive_my_dir_0 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_0")\n`
  126. )
  127. expect(code).toMatch(
  128. `const _directive_my_dir_1 = _${helperNameMap[RESOLVE_DIRECTIVE]}("my_dir_1")\n`
  129. )
  130. expect(code).toMatch(`let _temp0, _temp1, _temp2`)
  131. expect(code).toMatchSnapshot()
  132. })
  133. test('hoists', () => {
  134. const root = createRoot({
  135. hoists: [
  136. createSimpleExpression(`hello`, false, locStub),
  137. createObjectExpression(
  138. [
  139. createObjectProperty(
  140. createSimpleExpression(`id`, true, locStub),
  141. createSimpleExpression(`foo`, true, locStub)
  142. )
  143. ],
  144. locStub
  145. )
  146. ]
  147. })
  148. const { code } = generate(root)
  149. expect(code).toMatch(`const _hoisted_1 = hello`)
  150. expect(code).toMatch(`const _hoisted_2 = { id: "foo" }`)
  151. expect(code).toMatchSnapshot()
  152. })
  153. test('temps', () => {
  154. const root = createRoot({
  155. temps: 3
  156. })
  157. const { code } = generate(root)
  158. expect(code).toMatch(`let _temp0, _temp1, _temp2`)
  159. expect(code).toMatchSnapshot()
  160. })
  161. test('static text', () => {
  162. const { code } = generate(
  163. createRoot({
  164. codegenNode: {
  165. type: NodeTypes.TEXT,
  166. content: 'hello',
  167. loc: locStub
  168. }
  169. })
  170. )
  171. expect(code).toMatch(`return "hello"`)
  172. expect(code).toMatchSnapshot()
  173. })
  174. test('interpolation', () => {
  175. const { code } = generate(
  176. createRoot({
  177. codegenNode: createInterpolation(`hello`, locStub)
  178. })
  179. )
  180. expect(code).toMatch(`return _${helperNameMap[TO_DISPLAY_STRING]}(hello)`)
  181. expect(code).toMatchSnapshot()
  182. })
  183. test('comment', () => {
  184. const { code } = generate(
  185. createRoot({
  186. codegenNode: {
  187. type: NodeTypes.COMMENT,
  188. content: 'foo',
  189. loc: locStub
  190. }
  191. })
  192. )
  193. expect(code).toMatch(`return _${helperNameMap[CREATE_COMMENT]}("foo")`)
  194. expect(code).toMatchSnapshot()
  195. })
  196. test('compound expression', () => {
  197. const { code } = generate(
  198. createRoot({
  199. codegenNode: createCompoundExpression([
  200. `_ctx.`,
  201. createSimpleExpression(`foo`, false, locStub),
  202. ` + `,
  203. {
  204. type: NodeTypes.INTERPOLATION,
  205. loc: locStub,
  206. content: createSimpleExpression(`bar`, false, locStub)
  207. },
  208. // nested compound
  209. createCompoundExpression([` + `, `nested`])
  210. ])
  211. })
  212. )
  213. expect(code).toMatch(
  214. `return _ctx.foo + _${helperNameMap[TO_DISPLAY_STRING]}(bar) + nested`
  215. )
  216. expect(code).toMatchSnapshot()
  217. })
  218. test('ifNode', () => {
  219. const { code } = generate(
  220. createRoot({
  221. codegenNode: {
  222. type: NodeTypes.IF,
  223. loc: locStub,
  224. branches: [],
  225. codegenNode: createConditionalExpression(
  226. createSimpleExpression('foo', false),
  227. createSimpleExpression('bar', false),
  228. createSimpleExpression('baz', false)
  229. ) as IfConditionalExpression
  230. }
  231. })
  232. )
  233. expect(code).toMatch(/return foo\s+\? bar\s+: baz/)
  234. expect(code).toMatchSnapshot()
  235. })
  236. test('forNode', () => {
  237. const { code } = generate(
  238. createRoot({
  239. codegenNode: {
  240. type: NodeTypes.FOR,
  241. loc: locStub,
  242. source: createSimpleExpression('foo', false),
  243. valueAlias: undefined,
  244. keyAlias: undefined,
  245. objectIndexAlias: undefined,
  246. children: [],
  247. parseResult: {} as any,
  248. codegenNode: {
  249. type: NodeTypes.VNODE_CALL,
  250. tag: FRAGMENT,
  251. isBlock: true,
  252. disableTracking: true,
  253. props: undefined,
  254. children: createCallExpression(RENDER_LIST),
  255. patchFlag: '1',
  256. dynamicProps: undefined,
  257. directives: undefined,
  258. loc: locStub
  259. } as ForCodegenNode
  260. }
  261. })
  262. )
  263. expect(code).toMatch(`openBlock(true)`)
  264. expect(code).toMatchSnapshot()
  265. })
  266. test('forNode with constant expression', () => {
  267. const { code } = generate(
  268. createRoot({
  269. codegenNode: {
  270. type: NodeTypes.FOR,
  271. loc: locStub,
  272. source: createSimpleExpression(
  273. '1 + 2',
  274. false,
  275. locStub,
  276. ConstantTypes.CAN_STRINGIFY
  277. ),
  278. valueAlias: undefined,
  279. keyAlias: undefined,
  280. objectIndexAlias: undefined,
  281. children: [],
  282. parseResult: {} as any,
  283. codegenNode: {
  284. type: NodeTypes.VNODE_CALL,
  285. tag: FRAGMENT,
  286. isBlock: true,
  287. disableTracking: false,
  288. props: undefined,
  289. children: createCallExpression(RENDER_LIST),
  290. patchFlag: genFlagText(PatchFlags.STABLE_FRAGMENT),
  291. dynamicProps: undefined,
  292. directives: undefined,
  293. loc: locStub
  294. } as ForCodegenNode
  295. }
  296. })
  297. )
  298. expect(code).toMatch(`openBlock()`)
  299. expect(code).toMatchSnapshot()
  300. })
  301. test('Element (callExpression + objectExpression + TemplateChildNode[])', () => {
  302. const { code } = generate(
  303. createRoot({
  304. codegenNode: createElementWithCodegen(
  305. // string
  306. `"div"`,
  307. // ObjectExpression
  308. createObjectExpression(
  309. [
  310. createObjectProperty(
  311. createSimpleExpression(`id`, true, locStub),
  312. createSimpleExpression(`foo`, true, locStub)
  313. ),
  314. createObjectProperty(
  315. createSimpleExpression(`prop`, false, locStub),
  316. createSimpleExpression(`bar`, false, locStub)
  317. ),
  318. // compound expression as computed key
  319. createObjectProperty(
  320. {
  321. type: NodeTypes.COMPOUND_EXPRESSION,
  322. loc: locStub,
  323. children: [
  324. `foo + `,
  325. createSimpleExpression(`bar`, false, locStub)
  326. ]
  327. },
  328. createSimpleExpression(`bar`, false, locStub)
  329. )
  330. ],
  331. locStub
  332. ),
  333. // ChildNode[]
  334. [
  335. createElementWithCodegen(
  336. `"p"`,
  337. createObjectExpression(
  338. [
  339. createObjectProperty(
  340. // should quote the key!
  341. createSimpleExpression(`some-key`, true, locStub),
  342. createSimpleExpression(`foo`, true, locStub)
  343. )
  344. ],
  345. locStub
  346. )
  347. )
  348. ],
  349. // flag
  350. PatchFlags.FULL_PROPS + ''
  351. )
  352. })
  353. )
  354. expect(code).toMatch(`
  355. return _${helperNameMap[CREATE_ELEMENT_VNODE]}("div", {
  356. id: "foo",
  357. [prop]: bar,
  358. [foo + bar]: bar
  359. }, [
  360. _${helperNameMap[CREATE_ELEMENT_VNODE]}("p", { "some-key": "foo" })
  361. ], ${PatchFlags.FULL_PROPS})`)
  362. expect(code).toMatchSnapshot()
  363. })
  364. test('ArrayExpression', () => {
  365. const { code } = generate(
  366. createRoot({
  367. codegenNode: createArrayExpression([
  368. createSimpleExpression(`foo`, false),
  369. createCallExpression(`bar`, [`baz`])
  370. ])
  371. })
  372. )
  373. expect(code).toMatch(`return [
  374. foo,
  375. bar(baz)
  376. ]`)
  377. expect(code).toMatchSnapshot()
  378. })
  379. test('ConditionalExpression', () => {
  380. const { code } = generate(
  381. createRoot({
  382. codegenNode: createConditionalExpression(
  383. createSimpleExpression(`ok`, false),
  384. createCallExpression(`foo`),
  385. createConditionalExpression(
  386. createSimpleExpression(`orNot`, false),
  387. createCallExpression(`bar`),
  388. createCallExpression(`baz`)
  389. )
  390. )
  391. })
  392. )
  393. expect(code).toMatch(
  394. `return ok
  395. ? foo()
  396. : orNot
  397. ? bar()
  398. : baz()`
  399. )
  400. expect(code).toMatchSnapshot()
  401. })
  402. test('CacheExpression', () => {
  403. const { code } = generate(
  404. createRoot({
  405. cached: 1,
  406. codegenNode: createCacheExpression(
  407. 1,
  408. createSimpleExpression(`foo`, false)
  409. )
  410. }),
  411. {
  412. mode: 'module',
  413. prefixIdentifiers: true
  414. }
  415. )
  416. expect(code).toMatch(`_cache[1] || (_cache[1] = foo)`)
  417. expect(code).toMatchSnapshot()
  418. })
  419. test('CacheExpression w/ isVNode: true', () => {
  420. const { code } = generate(
  421. createRoot({
  422. cached: 1,
  423. codegenNode: createCacheExpression(
  424. 1,
  425. createSimpleExpression(`foo`, false),
  426. true
  427. )
  428. }),
  429. {
  430. mode: 'module',
  431. prefixIdentifiers: true
  432. }
  433. )
  434. expect(code).toMatch(
  435. `
  436. _cache[1] || (
  437. _setBlockTracking(-1),
  438. _cache[1] = foo,
  439. _setBlockTracking(1),
  440. _cache[1]
  441. )
  442. `.trim()
  443. )
  444. expect(code).toMatchSnapshot()
  445. })
  446. test('TemplateLiteral', () => {
  447. const { code } = generate(
  448. createRoot({
  449. codegenNode: createCallExpression(`_push`, [
  450. createTemplateLiteral([
  451. `foo`,
  452. createCallExpression(`_renderAttr`, ['id', 'foo']),
  453. `bar`
  454. ])
  455. ])
  456. }),
  457. { ssr: true, mode: 'module' }
  458. )
  459. expect(code).toMatchInlineSnapshot(`
  460. "
  461. export function ssrRender(_ctx, _push, _parent, _attrs) {
  462. _push(\`foo\${_renderAttr(id, foo)}bar\`)
  463. }"
  464. `)
  465. })
  466. describe('IfStatement', () => {
  467. test('if', () => {
  468. const { code } = generate(
  469. createRoot({
  470. codegenNode: createBlockStatement([
  471. createIfStatement(
  472. createSimpleExpression('foo', false),
  473. createBlockStatement([createCallExpression(`ok`)])
  474. )
  475. ])
  476. }),
  477. { ssr: true, mode: 'module' }
  478. )
  479. expect(code).toMatchInlineSnapshot(`
  480. "
  481. export function ssrRender(_ctx, _push, _parent, _attrs) {
  482. if (foo) {
  483. ok()
  484. }
  485. }"
  486. `)
  487. })
  488. test('if/else', () => {
  489. const { code } = generate(
  490. createRoot({
  491. codegenNode: createBlockStatement([
  492. createIfStatement(
  493. createSimpleExpression('foo', false),
  494. createBlockStatement([createCallExpression(`foo`)]),
  495. createBlockStatement([createCallExpression('bar')])
  496. )
  497. ])
  498. }),
  499. { ssr: true, mode: 'module' }
  500. )
  501. expect(code).toMatchInlineSnapshot(`
  502. "
  503. export function ssrRender(_ctx, _push, _parent, _attrs) {
  504. if (foo) {
  505. foo()
  506. } else {
  507. bar()
  508. }
  509. }"
  510. `)
  511. })
  512. test('if/else-if', () => {
  513. const { code } = generate(
  514. createRoot({
  515. codegenNode: createBlockStatement([
  516. createIfStatement(
  517. createSimpleExpression('foo', false),
  518. createBlockStatement([createCallExpression(`foo`)]),
  519. createIfStatement(
  520. createSimpleExpression('bar', false),
  521. createBlockStatement([createCallExpression(`bar`)])
  522. )
  523. )
  524. ])
  525. }),
  526. { ssr: true, mode: 'module' }
  527. )
  528. expect(code).toMatchInlineSnapshot(`
  529. "
  530. export function ssrRender(_ctx, _push, _parent, _attrs) {
  531. if (foo) {
  532. foo()
  533. } else if (bar) {
  534. bar()
  535. }
  536. }"
  537. `)
  538. })
  539. test('if/else-if/else', () => {
  540. const { code } = generate(
  541. createRoot({
  542. codegenNode: createBlockStatement([
  543. createIfStatement(
  544. createSimpleExpression('foo', false),
  545. createBlockStatement([createCallExpression(`foo`)]),
  546. createIfStatement(
  547. createSimpleExpression('bar', false),
  548. createBlockStatement([createCallExpression(`bar`)]),
  549. createBlockStatement([createCallExpression('baz')])
  550. )
  551. )
  552. ])
  553. }),
  554. { ssr: true, mode: 'module' }
  555. )
  556. expect(code).toMatchInlineSnapshot(`
  557. "
  558. export function ssrRender(_ctx, _push, _parent, _attrs) {
  559. if (foo) {
  560. foo()
  561. } else if (bar) {
  562. bar()
  563. } else {
  564. baz()
  565. }
  566. }"
  567. `)
  568. })
  569. })
  570. test('AssignmentExpression', () => {
  571. const { code } = generate(
  572. createRoot({
  573. codegenNode: createAssignmentExpression(
  574. createSimpleExpression(`foo`, false),
  575. createSimpleExpression(`bar`, false)
  576. )
  577. })
  578. )
  579. expect(code).toMatchInlineSnapshot(`
  580. "
  581. return function render(_ctx, _cache) {
  582. with (_ctx) {
  583. return foo = bar
  584. }
  585. }"
  586. `)
  587. })
  588. describe('VNodeCall', () => {
  589. function genCode(node: VNodeCall) {
  590. return generate(
  591. createRoot({
  592. codegenNode: node
  593. })
  594. ).code.match(/with \(_ctx\) \{\s+([^]+)\s+\}\s+\}$/)![1]
  595. }
  596. const mockProps = createObjectExpression([
  597. createObjectProperty(`foo`, createSimpleExpression(`bar`, true))
  598. ])
  599. const mockChildren = createCompoundExpression(['children'])
  600. const mockDirs = createArrayExpression([
  601. createArrayExpression([`foo`, createSimpleExpression(`bar`, false)])
  602. ]) as DirectiveArguments
  603. test('tag only', () => {
  604. expect(genCode(createVNodeCall(null, `"div"`))).toMatchInlineSnapshot(`
  605. "return _createElementVNode(\\"div\\")
  606. "
  607. `)
  608. expect(genCode(createVNodeCall(null, FRAGMENT))).toMatchInlineSnapshot(`
  609. "return _createElementVNode(_Fragment)
  610. "
  611. `)
  612. })
  613. test('with props', () => {
  614. expect(genCode(createVNodeCall(null, `"div"`, mockProps)))
  615. .toMatchInlineSnapshot(`
  616. "return _createElementVNode(\\"div\\", { foo: \\"bar\\" })
  617. "
  618. `)
  619. })
  620. test('with children, no props', () => {
  621. expect(genCode(createVNodeCall(null, `"div"`, undefined, mockChildren)))
  622. .toMatchInlineSnapshot(`
  623. "return _createElementVNode(\\"div\\", null, children)
  624. "
  625. `)
  626. })
  627. test('with children + props', () => {
  628. expect(genCode(createVNodeCall(null, `"div"`, mockProps, mockChildren)))
  629. .toMatchInlineSnapshot(`
  630. "return _createElementVNode(\\"div\\", { foo: \\"bar\\" }, children)
  631. "
  632. `)
  633. })
  634. test('with patchFlag and no children/props', () => {
  635. expect(genCode(createVNodeCall(null, `"div"`, undefined, undefined, '1')))
  636. .toMatchInlineSnapshot(`
  637. "return _createElementVNode(\\"div\\", null, null, 1)
  638. "
  639. `)
  640. })
  641. test('as block', () => {
  642. expect(
  643. genCode(
  644. createVNodeCall(
  645. null,
  646. `"div"`,
  647. mockProps,
  648. mockChildren,
  649. undefined,
  650. undefined,
  651. undefined,
  652. true
  653. )
  654. )
  655. ).toMatchInlineSnapshot(`
  656. "return (_openBlock(), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children))
  657. "
  658. `)
  659. })
  660. test('as for block', () => {
  661. expect(
  662. genCode(
  663. createVNodeCall(
  664. null,
  665. `"div"`,
  666. mockProps,
  667. mockChildren,
  668. undefined,
  669. undefined,
  670. undefined,
  671. true,
  672. true
  673. )
  674. )
  675. ).toMatchInlineSnapshot(`
  676. "return (_openBlock(true), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children))
  677. "
  678. `)
  679. })
  680. test('with directives', () => {
  681. expect(
  682. genCode(
  683. createVNodeCall(
  684. null,
  685. `"div"`,
  686. mockProps,
  687. mockChildren,
  688. undefined,
  689. undefined,
  690. mockDirs
  691. )
  692. )
  693. ).toMatchInlineSnapshot(`
  694. "return _withDirectives(_createElementVNode(\\"div\\", { foo: \\"bar\\" }, children), [
  695. [foo, bar]
  696. ])
  697. "
  698. `)
  699. })
  700. test('block + directives', () => {
  701. expect(
  702. genCode(
  703. createVNodeCall(
  704. null,
  705. `"div"`,
  706. mockProps,
  707. mockChildren,
  708. undefined,
  709. undefined,
  710. mockDirs,
  711. true
  712. )
  713. )
  714. ).toMatchInlineSnapshot(`
  715. "return _withDirectives((_openBlock(), _createElementBlock(\\"div\\", { foo: \\"bar\\" }, children)), [
  716. [foo, bar]
  717. ])
  718. "
  719. `)
  720. })
  721. })
  722. })