codegen.spec.ts 20 KB

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