codegen.spec.ts 20 KB

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