codegen.spec.ts 20 KB

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