codegen.spec.ts 20 KB

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