quasar 2.15.3 → 2.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/dist/api/AppFullscreen.json +1 -1
  2. package/dist/icon-set/bootstrap-icons.umd.prod.js +1 -1
  3. package/dist/icon-set/eva-icons.umd.prod.js +1 -1
  4. package/dist/icon-set/fontawesome-v5-pro.umd.prod.js +1 -1
  5. package/dist/icon-set/fontawesome-v5.umd.prod.js +1 -1
  6. package/dist/icon-set/fontawesome-v6-pro.umd.prod.js +1 -1
  7. package/dist/icon-set/fontawesome-v6.umd.prod.js +1 -1
  8. package/dist/icon-set/ionicons-v4.umd.prod.js +1 -1
  9. package/dist/icon-set/line-awesome.umd.prod.js +1 -1
  10. package/dist/icon-set/material-icons-outlined.umd.prod.js +1 -1
  11. package/dist/icon-set/material-icons-round.umd.prod.js +1 -1
  12. package/dist/icon-set/material-icons-sharp.umd.prod.js +1 -1
  13. package/dist/icon-set/material-icons.umd.prod.js +1 -1
  14. package/dist/icon-set/material-symbols-outlined.umd.prod.js +1 -1
  15. package/dist/icon-set/material-symbols-rounded.umd.prod.js +1 -1
  16. package/dist/icon-set/material-symbols-sharp.umd.prod.js +1 -1
  17. package/dist/icon-set/mdi-v3.umd.prod.js +1 -1
  18. package/dist/icon-set/mdi-v4.umd.prod.js +1 -1
  19. package/dist/icon-set/mdi-v5.umd.prod.js +1 -1
  20. package/dist/icon-set/mdi-v6.umd.prod.js +1 -1
  21. package/dist/icon-set/mdi-v7.umd.prod.js +1 -1
  22. package/dist/icon-set/svg-bootstrap-icons.umd.prod.js +1 -1
  23. package/dist/icon-set/svg-eva-icons.umd.prod.js +1 -1
  24. package/dist/icon-set/svg-fontawesome-v5.umd.prod.js +1 -1
  25. package/dist/icon-set/svg-fontawesome-v6.umd.prod.js +1 -1
  26. package/dist/icon-set/svg-ionicons-v4.umd.prod.js +1 -1
  27. package/dist/icon-set/svg-ionicons-v5.umd.prod.js +1 -1
  28. package/dist/icon-set/svg-ionicons-v6.umd.prod.js +1 -1
  29. package/dist/icon-set/svg-line-awesome.umd.prod.js +1 -1
  30. package/dist/icon-set/svg-material-icons-outlined.umd.prod.js +1 -1
  31. package/dist/icon-set/svg-material-icons-round.umd.prod.js +1 -1
  32. package/dist/icon-set/svg-material-icons-sharp.umd.prod.js +1 -1
  33. package/dist/icon-set/svg-material-icons.umd.prod.js +1 -1
  34. package/dist/icon-set/svg-material-symbols-outlined.umd.prod.js +1 -1
  35. package/dist/icon-set/svg-material-symbols-rounded.umd.prod.js +1 -1
  36. package/dist/icon-set/svg-material-symbols-sharp.umd.prod.js +1 -1
  37. package/dist/icon-set/svg-mdi-v6.umd.prod.js +1 -1
  38. package/dist/icon-set/svg-mdi-v7.umd.prod.js +1 -1
  39. package/dist/icon-set/svg-themify.umd.prod.js +1 -1
  40. package/dist/icon-set/themify.umd.prod.js +1 -1
  41. package/dist/lang/ar-TN.umd.prod.js +1 -1
  42. package/dist/lang/ar.umd.prod.js +1 -1
  43. package/dist/lang/az-Latn.umd.prod.js +1 -1
  44. package/dist/lang/bg.umd.prod.js +1 -1
  45. package/dist/lang/bn.umd.prod.js +1 -1
  46. package/dist/lang/ca.umd.prod.js +1 -1
  47. package/dist/lang/cs.umd.prod.js +1 -1
  48. package/dist/lang/da.umd.prod.js +1 -1
  49. package/dist/lang/de-CH.umd.prod.js +1 -1
  50. package/dist/lang/de-DE.umd.prod.js +1 -1
  51. package/dist/lang/de.umd.prod.js +1 -1
  52. package/dist/lang/el.umd.prod.js +1 -1
  53. package/dist/lang/en-GB.umd.prod.js +1 -1
  54. package/dist/lang/en-US.umd.prod.js +1 -1
  55. package/dist/lang/eo.umd.prod.js +1 -1
  56. package/dist/lang/es.umd.prod.js +1 -1
  57. package/dist/lang/et.umd.prod.js +1 -1
  58. package/dist/lang/eu.umd.prod.js +1 -1
  59. package/dist/lang/fa-IR.umd.prod.js +1 -1
  60. package/dist/lang/fa.umd.prod.js +1 -1
  61. package/dist/lang/fi.umd.prod.js +1 -1
  62. package/dist/lang/fr.umd.prod.js +1 -1
  63. package/dist/lang/gn.umd.prod.js +1 -1
  64. package/dist/lang/he.umd.prod.js +1 -1
  65. package/dist/lang/hi.umd.prod.js +1 -1
  66. package/dist/lang/hr.umd.prod.js +1 -1
  67. package/dist/lang/hu.umd.prod.js +1 -1
  68. package/dist/lang/id.umd.prod.js +1 -1
  69. package/dist/lang/is.umd.prod.js +1 -1
  70. package/dist/lang/it.umd.prod.js +1 -1
  71. package/dist/lang/ja.umd.prod.js +1 -1
  72. package/dist/lang/kk.umd.prod.js +1 -1
  73. package/dist/lang/km.umd.prod.js +1 -1
  74. package/dist/lang/ko-KR.umd.prod.js +1 -1
  75. package/dist/lang/kur-CKB.umd.prod.js +1 -1
  76. package/dist/lang/lt.umd.prod.js +1 -1
  77. package/dist/lang/lu.umd.prod.js +1 -1
  78. package/dist/lang/lv.umd.prod.js +1 -1
  79. package/dist/lang/mk.umd.prod.js +1 -1
  80. package/dist/lang/ml.umd.prod.js +1 -1
  81. package/dist/lang/mm.umd.prod.js +1 -1
  82. package/dist/lang/ms-MY.umd.prod.js +1 -1
  83. package/dist/lang/ms.umd.prod.js +1 -1
  84. package/dist/lang/my.umd.prod.js +1 -1
  85. package/dist/lang/nb-NO.umd.prod.js +1 -1
  86. package/dist/lang/nl.umd.prod.js +1 -1
  87. package/dist/lang/pl.umd.prod.js +1 -1
  88. package/dist/lang/pt-BR.umd.prod.js +1 -1
  89. package/dist/lang/pt.umd.prod.js +1 -1
  90. package/dist/lang/ro.umd.prod.js +1 -1
  91. package/dist/lang/ru.umd.prod.js +1 -1
  92. package/dist/lang/sk.umd.prod.js +1 -1
  93. package/dist/lang/sl.umd.prod.js +1 -1
  94. package/dist/lang/sm.umd.prod.js +1 -1
  95. package/dist/lang/sr-CYR.umd.prod.js +1 -1
  96. package/dist/lang/sr.umd.prod.js +1 -1
  97. package/dist/lang/sv.umd.prod.js +1 -1
  98. package/dist/lang/ta.umd.prod.js +1 -1
  99. package/dist/lang/th.umd.prod.js +1 -1
  100. package/dist/lang/tl.umd.prod.js +1 -1
  101. package/dist/lang/tr.umd.prod.js +1 -1
  102. package/dist/lang/ug.umd.prod.js +1 -1
  103. package/dist/lang/uk.umd.prod.js +1 -1
  104. package/dist/lang/uz-Cyrl.umd.prod.js +1 -1
  105. package/dist/lang/uz-Latn.umd.prod.js +1 -1
  106. package/dist/lang/vi.umd.prod.js +1 -1
  107. package/dist/lang/zh-CN.umd.prod.js +1 -1
  108. package/dist/lang/zh-TW.umd.prod.js +1 -1
  109. package/dist/quasar.cjs.prod.js +3 -3
  110. package/dist/quasar.esm.js +8 -7
  111. package/dist/quasar.esm.prod.js +3 -3
  112. package/dist/quasar.sass +1 -1
  113. package/dist/quasar.umd.js +8 -7
  114. package/dist/quasar.umd.prod.js +3 -3
  115. package/dist/web-types/web-types.json +1 -1
  116. package/package.json +3 -3
  117. package/src/components/toolbar/QToolbar.test.js +45 -0
  118. package/src/components/toolbar/QToolbarTitle.test.js +45 -0
  119. package/src/composables/use-interval/use-interval.test.js +173 -0
  120. package/src/composables/use-render-cache/use-render-cache.js +2 -2
  121. package/src/composables/use-render-cache/use-render-cache.test.js +73 -0
  122. package/src/composables/use-split-attrs/use-split-attrs.test.js +55 -0
  123. package/src/composables/use-tick/use-tick.test.js +118 -0
  124. package/src/composables/use-timeout/use-timeout.test.js +169 -0
  125. package/src/plugins/addressbar/AddressbarColor.test.js +53 -0
  126. package/src/plugins/app-fullscreen/AppFullscreen.json +3 -1
  127. package/src/plugins/app-fullscreen/AppFullscreen.test.js +206 -0
  128. package/src/plugins/app-fullscreen/test/mock-fullscreen.js +43 -0
  129. package/src/plugins/app-visibility/AppVisibility.test.js +45 -0
  130. package/src/plugins/dark/Dark.test.js +158 -0
  131. package/src/plugins/platform/Platform.js +2 -1
  132. package/src/plugins/private.body/Body.test.js +28 -0
  133. package/src/plugins/private.history/History.test.js +38 -0
  134. package/src/plugins/screen/Screen.test.js +453 -0
  135. package/src/utils/css-var/get-css-var.test.js +12 -0
  136. package/src/utils/css-var/set-css-var.test.js +18 -0
  137. package/src/utils/dom/dom.test.js +222 -0
  138. package/src/utils/private.render/render.test.js +187 -0
  139. package/src/utils/private.selection/selection.test.js +40 -0
  140. package/src/utils/private.vm/vm.test.js +175 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quasar",
3
- "version": "2.15.3",
3
+ "version": "2.15.4",
4
4
  "description": "Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time",
5
5
  "main": "dist/quasar.cjs.prod.js",
6
6
  "module": "dist/quasar.esm.prod.js",
@@ -63,8 +63,8 @@
63
63
  "table": "^6.8.2",
64
64
  "typescript": "^5.4.5",
65
65
  "vue": "^3",
66
- "eslint-config-quasar": "0.0.1",
67
- "@quasar/extras": "1.16.11"
66
+ "@quasar/extras": "1.16.11",
67
+ "eslint-config-quasar": "0.0.1"
68
68
  },
69
69
  "vetur": {
70
70
  "tags": "dist/vetur/quasar-tags.json",
@@ -0,0 +1,45 @@
1
+ import { mount, flushPromises } from '@vue/test-utils'
2
+ import { describe, test, expect } from 'vitest'
3
+
4
+ import QToolbar from './QToolbar.js'
5
+
6
+ describe('[QToolbar API]', () => {
7
+ describe('[Props]', () => {
8
+ describe('[(prop)inset]', () => {
9
+ test('is defined correctly', () => {
10
+ expect(QToolbar.props.inset).toBeDefined()
11
+ })
12
+
13
+ test('type Boolean has effect', async () => {
14
+ const wrapper = mount(QToolbar)
15
+ const target = wrapper.get('.q-toolbar')
16
+
17
+ expect(
18
+ target.classes()
19
+ ).not.toContain('q-toolbar--inset')
20
+
21
+ await wrapper.setProps({ inset: true })
22
+ await flushPromises()
23
+
24
+ expect(
25
+ target.classes()
26
+ ).toContain('q-toolbar--inset')
27
+ })
28
+ })
29
+ })
30
+
31
+ describe('[Slots]', () => {
32
+ describe('[(slot)default]', () => {
33
+ test('renders the content', () => {
34
+ const slotContent = 'some-slot-content'
35
+ const wrapper = mount(QToolbar, {
36
+ slots: {
37
+ default: () => slotContent
38
+ }
39
+ })
40
+
41
+ expect(wrapper.html()).toContain(slotContent)
42
+ })
43
+ })
44
+ })
45
+ })
@@ -0,0 +1,45 @@
1
+ import { mount, flushPromises } from '@vue/test-utils'
2
+ import { describe, test, expect } from 'vitest'
3
+
4
+ import QToolbarTitle from './QToolbarTitle.js'
5
+
6
+ describe('[QToolbarTitle API]', () => {
7
+ describe('[Props]', () => {
8
+ describe('[(prop)shrink]', () => {
9
+ test('is defined correctly', () => {
10
+ expect(QToolbarTitle.props.shrink).toBeDefined()
11
+ })
12
+
13
+ test('type Boolean has effect', async () => {
14
+ const wrapper = mount(QToolbarTitle)
15
+ const target = wrapper.get('.q-toolbar__title')
16
+
17
+ expect(
18
+ target.classes()
19
+ ).not.toContain('col-shrink')
20
+
21
+ await wrapper.setProps({ shrink: true })
22
+ await flushPromises()
23
+
24
+ expect(
25
+ target.classes()
26
+ ).toContain('col-shrink')
27
+ })
28
+ })
29
+ })
30
+
31
+ describe('[Slots]', () => {
32
+ describe('[(slot)default]', () => {
33
+ test('renders the content', () => {
34
+ const slotContent = 'some-slot-content'
35
+ const wrapper = mount(QToolbarTitle, {
36
+ slots: {
37
+ default: () => slotContent
38
+ }
39
+ })
40
+
41
+ expect(wrapper.html()).toContain(slotContent)
42
+ })
43
+ })
44
+ })
45
+ })
@@ -0,0 +1,173 @@
1
+ import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { defineComponent } from 'vue'
4
+
5
+ import useInterval from './use-interval.js'
6
+
7
+ let wrapper
8
+
9
+ beforeEach(() => {
10
+ vi.useFakeTimers()
11
+ })
12
+
13
+ afterEach(() => {
14
+ vi.clearAllTimers()
15
+ vi.restoreAllMocks()
16
+
17
+ if (wrapper !== null) {
18
+ wrapper.unmount()
19
+ wrapper = null
20
+ }
21
+ })
22
+
23
+ describe('[useInterval API]', () => {
24
+ describe('[Functions]', () => {
25
+ describe('[(function)default]', () => {
26
+ test('correctly registers an interval (int)', () => {
27
+ const fn = vi.fn()
28
+
29
+ wrapper = mount(
30
+ defineComponent({
31
+ template: '<div />',
32
+ setup () {
33
+ const { registerInterval } = useInterval()
34
+
35
+ registerInterval(fn, 100)
36
+ return {}
37
+ }
38
+ })
39
+ )
40
+
41
+ expect(fn).not.toHaveBeenCalled()
42
+ vi.advanceTimersByTime(99)
43
+ expect(fn).not.toHaveBeenCalled()
44
+ vi.advanceTimersByTime(1)
45
+ expect(fn).toHaveBeenCalledTimes(1)
46
+
47
+ vi.advanceTimersByTime(100)
48
+
49
+ expect(fn).toHaveBeenCalledTimes(2)
50
+ })
51
+
52
+ test('correctly registers an interval (str)', () => {
53
+ const fn = vi.fn()
54
+
55
+ wrapper = mount(
56
+ defineComponent({
57
+ template: '<div />',
58
+ setup () {
59
+ const { registerInterval } = useInterval()
60
+
61
+ registerInterval(fn, '100')
62
+ return {}
63
+ }
64
+ })
65
+ )
66
+
67
+ expect(fn).not.toHaveBeenCalled()
68
+ vi.advanceTimersByTime(99)
69
+ expect(fn).not.toHaveBeenCalled()
70
+ vi.advanceTimersByTime(1)
71
+ expect(fn).toHaveBeenCalledTimes(1)
72
+
73
+ vi.advanceTimersByTime(100)
74
+
75
+ expect(fn).toHaveBeenCalledTimes(2)
76
+ })
77
+
78
+ test('removeInterval works correctly', () => {
79
+ const fn = vi.fn()
80
+
81
+ wrapper = mount(
82
+ defineComponent({
83
+ template: '<div />',
84
+ setup () {
85
+ const {
86
+ registerInterval,
87
+ removeInterval
88
+ } = useInterval()
89
+
90
+ registerInterval(fn, 100)
91
+ return { registerInterval, removeInterval }
92
+ }
93
+ })
94
+ )
95
+
96
+ expect(fn).not.toHaveBeenCalled()
97
+ vi.advanceTimersByTime(200)
98
+ expect(fn).toHaveBeenCalledTimes(2)
99
+
100
+ wrapper.vm.removeInterval()
101
+ vi.advanceTimersToNextTimer()
102
+
103
+ expect(fn).toHaveBeenCalledTimes(2)
104
+
105
+ wrapper.vm.registerInterval(fn, 100)
106
+ wrapper.unmount()
107
+
108
+ vi.advanceTimersToNextTimer()
109
+ vi.runAllTimers()
110
+
111
+ expect(fn).toHaveBeenCalledTimes(2)
112
+ })
113
+
114
+ test('unmount stops timeout', () => {
115
+ const fn = vi.fn()
116
+
117
+ wrapper = mount(
118
+ defineComponent({
119
+ template: '<div />',
120
+ setup () {
121
+ const { registerInterval } = useInterval()
122
+
123
+ registerInterval(fn, 100)
124
+ return {}
125
+ }
126
+ })
127
+ )
128
+
129
+ expect(fn).not.toHaveBeenCalled()
130
+
131
+ wrapper.unmount()
132
+ wrapper = null
133
+
134
+ vi.advanceTimersToNextTimer()
135
+ vi.runAllTimers()
136
+
137
+ expect(fn).not.toHaveBeenCalled()
138
+ })
139
+
140
+ test('can override timeout', () => {
141
+ const fn1 = vi.fn()
142
+ const fn2 = vi.fn()
143
+
144
+ wrapper = mount(
145
+ defineComponent({
146
+ template: '<div />',
147
+ setup () {
148
+ const { registerInterval } = useInterval()
149
+ return { registerInterval }
150
+ }
151
+ })
152
+ )
153
+
154
+ wrapper.vm.registerInterval(fn1, 100)
155
+ vi.advanceTimersByTime(99)
156
+ expect(fn1).not.toHaveBeenCalled()
157
+
158
+ wrapper.vm.registerInterval(fn2, 200)
159
+ vi.advanceTimersByTime(199)
160
+ expect(fn1).not.toHaveBeenCalled()
161
+ expect(fn2).not.toHaveBeenCalled()
162
+
163
+ vi.advanceTimersByTime(1)
164
+ expect(fn1).not.toHaveBeenCalled()
165
+ expect(fn2).toHaveBeenCalledTimes(1)
166
+
167
+ vi.advanceTimersToNextTimer()
168
+ expect(fn1).not.toHaveBeenCalled()
169
+ expect(fn2).toHaveBeenCalledTimes(2)
170
+ })
171
+ })
172
+ })
173
+ })
@@ -25,7 +25,7 @@ export default function () {
25
25
  },
26
26
 
27
27
  hasCache (key) {
28
- return cache.hasOwnProperty(key)
28
+ return Object.hasOwnProperty.call(cache, key)
29
29
  },
30
30
 
31
31
  clearCache (key) {
@@ -33,7 +33,7 @@ export default function () {
33
33
  delete cache[ key ]
34
34
  }
35
35
  else {
36
- cache = {}
36
+ cache = Object.create(null)
37
37
  }
38
38
  }
39
39
  }
@@ -0,0 +1,73 @@
1
+ import { describe, test, expect } from 'vitest'
2
+
3
+ import useRenderCache from './use-render-cache.js'
4
+
5
+ describe('[useRenderCache API]', () => {
6
+ describe('[Functions]', () => {
7
+ describe('[(function)default]', () => {
8
+ test('has correct return value', () => {
9
+ const result = useRenderCache()
10
+ expect(result).toStrictEqual({
11
+ getCache: expect.any(Function),
12
+ setCache: expect.any(Function),
13
+ hasCache: expect.any(Function),
14
+ clearCache: expect.any(Function)
15
+ })
16
+ })
17
+
18
+ test('getCache() returns undefined', () => {
19
+ const { getCache } = useRenderCache()
20
+ expect(getCache('key')).toBeUndefined()
21
+ })
22
+
23
+ test('setCache() sets cache', () => {
24
+ const { setCache, getCache } = useRenderCache()
25
+ setCache('key', 'value')
26
+ expect(getCache('key')).toBe('value')
27
+
28
+ setCache('key', 'second-value')
29
+ expect(getCache('key')).toBe('second-value')
30
+
31
+ setCache('another-key', 'another-value')
32
+ expect(getCache('another-key')).toBe('another-value')
33
+ expect(getCache('key')).toBe('second-value')
34
+ })
35
+
36
+ test('hasCache() returns true', () => {
37
+ const { hasCache, setCache } = useRenderCache()
38
+ setCache('key', 0)
39
+ setCache('key2', 10)
40
+ expect(hasCache('key')).toBe(true)
41
+ expect(hasCache('key2')).toBe(true)
42
+ })
43
+
44
+ test('clearCache() clears cache', () => {
45
+ const { clearCache, setCache, getCache, hasCache } = useRenderCache()
46
+ setCache('key', 0)
47
+ setCache('key2', 0)
48
+
49
+ clearCache()
50
+
51
+ expect(hasCache('key')).toBe(false)
52
+ expect(getCache('key')).toBeUndefined()
53
+
54
+ expect(hasCache('key2')).toBe(false)
55
+ expect(getCache('key2')).toBeUndefined()
56
+ })
57
+
58
+ test('clearCache(key) clears only the key', () => {
59
+ const { clearCache, setCache, getCache, hasCache } = useRenderCache()
60
+ setCache('key', 0)
61
+ setCache('key2', 0)
62
+
63
+ clearCache('key')
64
+
65
+ expect(hasCache('key')).toBe(false)
66
+ expect(getCache('key')).toBeUndefined()
67
+
68
+ expect(hasCache('key2')).toBe(true)
69
+ expect(getCache('key2')).toBe(0)
70
+ })
71
+ })
72
+ })
73
+ })
@@ -0,0 +1,55 @@
1
+ import { describe, test, expect } from 'vitest'
2
+ import { mount } from '@vue/test-utils'
3
+ import { defineComponent } from 'vue'
4
+
5
+ import useSplitAttrs from './use-split-attrs.js'
6
+
7
+ describe('[useSplitAttrs API]', () => {
8
+ describe('[Functions]', () => {
9
+ describe('[(function)default]', () => {
10
+ test.each([
11
+ [ 'no attrs', {}, [] ],
12
+ [ 'attrs', { a: '1' }, [] ],
13
+ [ 'listeners', {}, [ 'b' ] ],
14
+ [ 'attrs and listeners', { a: '1' }, [ 'b' ] ],
15
+ [ 'multiple attrs and listeners', { a: '1', b: '2' }, [ 'f1', 'f2' ] ]
16
+ ])('correctly splits: %s', (_, attrs, listeners) => {
17
+ const attrHtml = Object.keys(attrs).map(
18
+ key => `${ key }="${ attrs[ key ] }"`
19
+ ).join(' ')
20
+
21
+ const fn = () => {}
22
+ const fnList = {}
23
+ const listenerHtml = listeners.map(key => {
24
+ fnList[ 'on' + key.toUpperCase() ] = fn
25
+ return `@${ key }="fn"`
26
+ }).join(' ')
27
+
28
+ const ChildComponent = {
29
+ name: 'ChildComponent',
30
+ template: '<div />',
31
+ setup () {
32
+ const result = useSplitAttrs()
33
+ return { result }
34
+ }
35
+ }
36
+
37
+ const wrapper = mount(
38
+ defineComponent({
39
+ template: `<ChildComponent ${ attrHtml } ${ listenerHtml } />`,
40
+ components: { ChildComponent },
41
+ setup () {
42
+ return { fn }
43
+ }
44
+ })
45
+ )
46
+
47
+ const target = wrapper.findComponent({ name: 'ChildComponent' })
48
+ expect(target.vm.result).toStrictEqual({
49
+ attributes: expect.$ref(attrs),
50
+ listeners: expect.$ref(fnList)
51
+ })
52
+ })
53
+ })
54
+ })
55
+ })
@@ -0,0 +1,118 @@
1
+ import { describe, test, expect, vi, afterEach } from 'vitest'
2
+ import { mount, flushPromises } from '@vue/test-utils'
3
+ import { defineComponent } from 'vue'
4
+
5
+ import useTick from './use-tick.js'
6
+
7
+ let wrapper
8
+
9
+ afterEach(() => {
10
+ if (wrapper !== null) {
11
+ wrapper.unmount()
12
+ wrapper = null
13
+ }
14
+ })
15
+
16
+ describe('[useTick API]', () => {
17
+ describe('[Functions]', () => {
18
+ describe('[(function)default]', () => {
19
+ test('correctly registers a tick', async () => {
20
+ const fn = vi.fn()
21
+
22
+ wrapper = mount(
23
+ defineComponent({
24
+ template: '<div />',
25
+ setup () {
26
+ const { registerTick } = useTick()
27
+
28
+ registerTick(fn)
29
+ return {}
30
+ }
31
+ })
32
+ )
33
+
34
+ expect(fn).not.toHaveBeenCalled()
35
+ await flushPromises()
36
+ expect(fn).toHaveBeenCalledTimes(1)
37
+ })
38
+
39
+ test('removeTick works correctly', async () => {
40
+ const fn = vi.fn()
41
+
42
+ wrapper = mount(
43
+ defineComponent({
44
+ template: '<div />',
45
+ setup () {
46
+ const {
47
+ registerTick,
48
+ removeTick
49
+ } = useTick()
50
+
51
+ registerTick(fn)
52
+ return { registerTick, removeTick }
53
+ }
54
+ })
55
+ )
56
+
57
+ expect(fn).not.toHaveBeenCalled()
58
+ wrapper.vm.removeTick()
59
+
60
+ await flushPromises()
61
+ expect(fn).not.toHaveBeenCalled()
62
+ })
63
+
64
+ test('unmount stops tick', async () => {
65
+ const fn = vi.fn()
66
+
67
+ wrapper = mount(
68
+ defineComponent({
69
+ template: '<div />',
70
+ setup () {
71
+ const { registerTick } = useTick()
72
+
73
+ registerTick(fn)
74
+ return {}
75
+ }
76
+ })
77
+ )
78
+
79
+ expect(fn).not.toHaveBeenCalled()
80
+
81
+ wrapper.unmount()
82
+ wrapper = null
83
+
84
+ await flushPromises()
85
+
86
+ expect(fn).not.toHaveBeenCalled()
87
+ })
88
+
89
+ test('can override tick', async () => {
90
+ const fn1 = vi.fn()
91
+ const fn2 = vi.fn()
92
+
93
+ wrapper = mount(
94
+ defineComponent({
95
+ template: '<div />',
96
+ setup () {
97
+ const { registerTick } = useTick()
98
+ return { registerTick }
99
+ }
100
+ })
101
+ )
102
+
103
+ expect(fn1).not.toHaveBeenCalled()
104
+ wrapper.vm.registerTick(fn1)
105
+ expect(fn1).not.toHaveBeenCalled()
106
+
107
+ wrapper.vm.registerTick(fn2)
108
+ expect(fn1).not.toHaveBeenCalled()
109
+ expect(fn2).not.toHaveBeenCalled()
110
+
111
+ await flushPromises()
112
+
113
+ expect(fn1).not.toHaveBeenCalled()
114
+ expect(fn2).toHaveBeenCalledTimes(1)
115
+ })
116
+ })
117
+ })
118
+ })