apiLifecycle.spec.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import {
  2. type InjectionKey,
  3. type Ref,
  4. createComponent,
  5. createTextNode,
  6. getCurrentInstance,
  7. inject,
  8. nextTick,
  9. onUpdated,
  10. provide,
  11. ref,
  12. renderEffect,
  13. setText,
  14. } from '../src'
  15. import { makeRender } from './_utils'
  16. const define = makeRender<any>()
  17. describe('apiLifecycle', () => {
  18. // TODO: test
  19. // #136
  20. test('should trigger updated hooks across components. (parent -> child)', async () => {
  21. const handleUpdated = vi.fn()
  22. const handleUpdatedChild = vi.fn()
  23. const count = ref(0)
  24. const { render, host } = define({
  25. setup() {
  26. onUpdated(() => handleUpdated())
  27. return (() => {
  28. const n0 = createTextNode()
  29. renderEffect(() => setText(n0, count.value))
  30. const n1 = createComponent(Child, { count: () => count.value })
  31. return [n0, n1]
  32. })()
  33. },
  34. })
  35. const Child = {
  36. props: { count: Number },
  37. setup() {
  38. onUpdated(() => handleUpdatedChild())
  39. return (() => {
  40. const props = getCurrentInstance()!.props
  41. const n2 = createTextNode()
  42. renderEffect(() => setText(n2, props.count))
  43. return n2
  44. })()
  45. },
  46. }
  47. render()
  48. expect(host.innerHTML).toBe('00')
  49. expect(handleUpdated).toHaveBeenCalledTimes(0)
  50. expect(handleUpdatedChild).toHaveBeenCalledTimes(0)
  51. count.value++
  52. await nextTick()
  53. expect(host.innerHTML).toBe('11')
  54. expect(handleUpdated).toHaveBeenCalledTimes(1)
  55. expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
  56. })
  57. // #136
  58. test('should trigger updated hooks across components. (child -> parent)', async () => {
  59. const handleUpdated = vi.fn()
  60. const handleUpdatedChild = vi.fn()
  61. const key: InjectionKey<Ref<number>> = Symbol()
  62. const { render, host } = define({
  63. setup() {
  64. const count = ref(0)
  65. provide(key, count)
  66. onUpdated(() => handleUpdated())
  67. return (() => {
  68. const n0 = createTextNode()
  69. renderEffect(() => setText(n0, count.value))
  70. const n1 = createComponent(Child, { count: () => count.value })
  71. return [n0, n1]
  72. })()
  73. },
  74. })
  75. let update: any
  76. const Child = {
  77. props: { count: Number },
  78. setup() {
  79. onUpdated(() => handleUpdatedChild())
  80. const count = inject(key)!
  81. update = () => count.value++
  82. return (() => {
  83. const n2 = createTextNode()
  84. renderEffect(() => setText(n2, count.value))
  85. return n2
  86. })()
  87. },
  88. }
  89. render()
  90. expect(host.innerHTML).toBe('00')
  91. expect(handleUpdated).toHaveBeenCalledTimes(0)
  92. expect(handleUpdatedChild).toHaveBeenCalledTimes(0)
  93. update()
  94. await nextTick()
  95. expect(host.innerHTML).toBe('11')
  96. expect(handleUpdated).toHaveBeenCalledTimes(1)
  97. expect(handleUpdatedChild).toHaveBeenCalledTimes(1)
  98. })
  99. })