if.spec.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import {
  2. append,
  3. children,
  4. createIf,
  5. insert,
  6. nextTick,
  7. ref,
  8. renderEffect,
  9. setText,
  10. template,
  11. } from '../src'
  12. import type { Mock } from 'vitest'
  13. import { makeRender } from './_utils'
  14. const define = makeRender()
  15. describe('createIf', () => {
  16. test('basic', async () => {
  17. // mock this template:
  18. // <div>
  19. // <p v-if="counter">{{counter}}</p>
  20. // <p v-else>zero</p>
  21. // </div>
  22. let spyIfFn: Mock<any, any>
  23. let spyElseFn: Mock<any, any>
  24. const count = ref(0)
  25. // templates can be reused through caching.
  26. const t0 = template('<div></div>')
  27. const t1 = template('<p></p>')
  28. const t2 = template('<p>zero</p>')
  29. const { host } = define(() => {
  30. const n0 = t0()
  31. const n1 = children(n0, 0)
  32. insert(
  33. createIf(
  34. () => count.value,
  35. // v-if
  36. (spyIfFn ||= vi.fn(() => {
  37. const n2 = t1()
  38. const n3 = children(n2, 0)
  39. renderEffect(() => {
  40. setText(n3, count.value)
  41. })
  42. return n2
  43. })),
  44. // v-else
  45. (spyElseFn ||= vi.fn(() => {
  46. const n4 = t2()
  47. return n4
  48. })),
  49. ),
  50. n1 as any as ParentNode,
  51. )
  52. return n0
  53. }).render()
  54. expect(host.innerHTML).toBe('<div><p>zero</p><!--if--></div>')
  55. expect(spyIfFn!).toHaveBeenCalledTimes(0)
  56. expect(spyElseFn!).toHaveBeenCalledTimes(1)
  57. count.value++
  58. await nextTick()
  59. expect(host.innerHTML).toBe('<div><p>1</p><!--if--></div>')
  60. expect(spyIfFn!).toHaveBeenCalledTimes(1)
  61. expect(spyElseFn!).toHaveBeenCalledTimes(1)
  62. count.value++
  63. await nextTick()
  64. expect(host.innerHTML).toBe('<div><p>2</p><!--if--></div>')
  65. expect(spyIfFn!).toHaveBeenCalledTimes(1)
  66. expect(spyElseFn!).toHaveBeenCalledTimes(1)
  67. count.value = 0
  68. await nextTick()
  69. expect(host.innerHTML).toBe('<div><p>zero</p><!--if--></div>')
  70. expect(spyIfFn!).toHaveBeenCalledTimes(1)
  71. expect(spyElseFn!).toHaveBeenCalledTimes(2)
  72. })
  73. test('should handle nested template', async () => {
  74. // mock this template:
  75. // <template v-if="ok1">
  76. // Hello <template v-if="ok2">Vapor</template>
  77. // </template>
  78. const ok1 = ref(true)
  79. const ok2 = ref(true)
  80. const t0 = template('Vapor')
  81. const t1 = template('Hello ')
  82. const { host } = define(() => {
  83. const n1 = createIf(
  84. () => ok1.value,
  85. () => {
  86. const n2 = t1()
  87. const n3 = createIf(
  88. () => ok2.value,
  89. () => {
  90. const n4 = t0()
  91. return n4
  92. },
  93. )
  94. append(n2, n3)
  95. return n2
  96. },
  97. )
  98. return [n1]
  99. }).render()
  100. expect(host.innerHTML).toBe('Hello Vapor<!--if--><!--if-->')
  101. ok1.value = false
  102. await nextTick()
  103. expect(host.innerHTML).toBe('<!--if-->')
  104. ok1.value = true
  105. await nextTick()
  106. expect(host.innerHTML).toBe('Hello Vapor<!--if--><!--if-->')
  107. ok2.value = false
  108. await nextTick()
  109. expect(host.innerHTML).toBe('Hello <!--if--><!--if-->')
  110. ok1.value = false
  111. await nextTick()
  112. expect(host.innerHTML).toBe('<!--if-->')
  113. })
  114. })