codegen.spec.ts 20 KB

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