useCssVars.spec.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {
  2. ref,
  3. render,
  4. useCssVars,
  5. h,
  6. reactive,
  7. nextTick,
  8. ComponentOptions,
  9. Suspense
  10. } from '@vue/runtime-dom'
  11. describe('useCssVars', () => {
  12. async function assertCssVars(getApp: (state: any) => ComponentOptions) {
  13. const state = reactive({ color: 'red' })
  14. const App = getApp(state)
  15. const root = document.createElement('div')
  16. render(h(App), root)
  17. await nextTick()
  18. for (const c of [].slice.call(root.children as any)) {
  19. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
  20. }
  21. state.color = 'green'
  22. await nextTick()
  23. for (const c of [].slice.call(root.children as any)) {
  24. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('green')
  25. }
  26. }
  27. test('basic', async () => {
  28. await assertCssVars(state => ({
  29. setup() {
  30. // test receiving render context
  31. useCssVars((ctx: any) => ({
  32. color: ctx.color
  33. }))
  34. return state
  35. },
  36. render() {
  37. return h('div')
  38. }
  39. }))
  40. })
  41. test('on fragment root', async () => {
  42. await assertCssVars(state => ({
  43. setup() {
  44. useCssVars(() => state)
  45. return () => [h('div'), h('div')]
  46. }
  47. }))
  48. })
  49. test('on HOCs', async () => {
  50. const Child = () => [h('div'), h('div')]
  51. await assertCssVars(state => ({
  52. setup() {
  53. useCssVars(() => state)
  54. return () => h(Child)
  55. }
  56. }))
  57. })
  58. test('on suspense root', async () => {
  59. const state = reactive({ color: 'red' })
  60. const root = document.createElement('div')
  61. let resolveAsync: any
  62. let asyncPromise: any
  63. const AsyncComp = {
  64. setup() {
  65. asyncPromise = new Promise(r => {
  66. resolveAsync = () => {
  67. r(() => h('p', 'default'))
  68. }
  69. })
  70. return asyncPromise
  71. }
  72. }
  73. const App = {
  74. setup() {
  75. useCssVars(() => state)
  76. return () =>
  77. h(Suspense, null, {
  78. default: h(AsyncComp),
  79. fallback: h('div', 'fallback')
  80. })
  81. }
  82. }
  83. render(h(App), root)
  84. await nextTick()
  85. // css vars use with fallback tree
  86. for (const c of [].slice.call(root.children as any)) {
  87. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
  88. }
  89. // AsyncComp resolve
  90. resolveAsync()
  91. await asyncPromise.then(() => {})
  92. // Suspense effects flush
  93. await nextTick()
  94. // css vars use with default tree
  95. for (const c of [].slice.call(root.children as any)) {
  96. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
  97. }
  98. state.color = 'green'
  99. await nextTick()
  100. for (const c of [].slice.call(root.children as any)) {
  101. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('green')
  102. }
  103. })
  104. test('with subTree changed', async () => {
  105. const state = reactive({ color: 'red' })
  106. const value = ref(true)
  107. const root = document.createElement('div')
  108. const App = {
  109. setup() {
  110. useCssVars(() => state)
  111. return () => (value.value ? [h('div')] : [h('div'), h('div')])
  112. }
  113. }
  114. render(h(App), root)
  115. await nextTick()
  116. // css vars use with fallback tree
  117. for (const c of [].slice.call(root.children as any)) {
  118. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe(`red`)
  119. }
  120. value.value = false
  121. await nextTick()
  122. for (const c of [].slice.call(root.children as any)) {
  123. expect((c as HTMLElement).style.getPropertyValue(`--color`)).toBe('red')
  124. }
  125. })
  126. })