@cloudcome/utils-core 1.1.1 → 1.2.0

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 (291) hide show
  1. package/dist/array.cjs +129 -0
  2. package/dist/array.cjs.map +1 -0
  3. package/dist/array.d.ts +171 -0
  4. package/dist/array.mjs +129 -0
  5. package/dist/array.mjs.map +1 -0
  6. package/dist/async.cjs +219 -0
  7. package/dist/async.cjs.map +1 -0
  8. package/dist/async.d.ts +137 -0
  9. package/dist/async.mjs +219 -0
  10. package/dist/async.mjs.map +1 -0
  11. package/dist/base64.cjs +16 -0
  12. package/dist/base64.cjs.map +1 -0
  13. package/dist/base64.d.ts +7 -0
  14. package/dist/base64.mjs +16 -0
  15. package/dist/base64.mjs.map +1 -0
  16. package/dist/cache.cjs +79 -0
  17. package/dist/cache.cjs.map +1 -0
  18. package/dist/cache.d.ts +90 -0
  19. package/dist/cache.mjs +79 -0
  20. package/dist/cache.mjs.map +1 -0
  21. package/{src/color/contrast.ts → dist/color/contrast.d.ts} +2 -12
  22. package/dist/color/distance.d.ts +8 -0
  23. package/dist/color/helpers.d.ts +2 -0
  24. package/dist/color/hex-hsl.d.ts +3 -0
  25. package/{src/color/hex-hsv.ts → dist/color/hex-hsv.d.ts} +3 -11
  26. package/{src/color/hex-hwb.ts → dist/color/hex-hwb.d.ts} +3 -11
  27. package/dist/color/hex-rgb.d.ts +18 -0
  28. package/{src/color/hsl-lighten.ts → dist/color/hsl-lighten.d.ts} +2 -7
  29. package/{src/color/hsv-brighten.ts → dist/color/hsv-brighten.d.ts} +2 -7
  30. package/{src/color/luminance.ts → dist/color/luminance.d.ts} +2 -9
  31. package/{src/color/mix.ts → dist/color/mix.d.ts} +2 -10
  32. package/dist/color/rgb-hsl.d.ts +23 -0
  33. package/{src/color/rgb-hsv.ts → dist/color/rgb-hsv.d.ts} +3 -30
  34. package/dist/color/rgb-hwb.d.ts +29 -0
  35. package/{src/color/rgb-lab.ts → dist/color/rgb-lab.d.ts} +3 -11
  36. package/dist/color/rgb-whiter.d.ts +12 -0
  37. package/dist/color/rgb-xyz.d.ts +22 -0
  38. package/{src/color/types.ts → dist/color/types.d.ts} +30 -12
  39. package/{src/color/xyz-lab.ts → dist/color/xyz-lab.d.ts} +3 -32
  40. package/dist/color.cjs +250 -0
  41. package/dist/color.cjs.map +1 -0
  42. package/dist/color.mjs +250 -0
  43. package/dist/color.mjs.map +1 -0
  44. package/dist/const.cjs +14 -0
  45. package/dist/const.cjs.map +1 -0
  46. package/dist/const.mjs +15 -0
  47. package/dist/const.mjs.map +1 -0
  48. package/dist/core.cjs +250 -0
  49. package/dist/core.cjs.map +1 -0
  50. package/dist/core.mjs +251 -0
  51. package/dist/core.mjs.map +1 -0
  52. package/dist/crypto/md5.d.mts +1 -0
  53. package/dist/crypto/sha1.d.mts +1 -0
  54. package/dist/crypto/sha256.d.mts +1 -0
  55. package/dist/crypto/sha512.d.mts +1 -0
  56. package/dist/crypto.cjs +812 -0
  57. package/dist/crypto.cjs.map +1 -0
  58. package/{src/crypto.ts → dist/crypto.d.ts} +4 -20
  59. package/dist/crypto.mjs +812 -0
  60. package/dist/crypto.mjs.map +1 -0
  61. package/dist/date/const.d.ts +6 -0
  62. package/dist/date/core.d.ts +52 -0
  63. package/dist/date/days.d.ts +23 -0
  64. package/{src/date/is.ts → dist/date/is.d.ts} +8 -102
  65. package/dist/date/relative.d.ts +44 -0
  66. package/dist/date/start-end.d.ts +73 -0
  67. package/dist/date/timezone.d.ts +67 -0
  68. package/dist/date/weeks.d.ts +72 -0
  69. package/dist/date.cjs +239 -0
  70. package/dist/date.cjs.map +1 -0
  71. package/dist/date.mjs +241 -0
  72. package/dist/date.mjs.map +1 -0
  73. package/dist/dict.cjs +2 -0
  74. package/dist/dict.cjs.map +1 -0
  75. package/dist/dict.mjs +2 -0
  76. package/dist/dict.mjs.map +1 -0
  77. package/dist/each.cjs +18 -0
  78. package/dist/each.cjs.map +1 -0
  79. package/dist/each.mjs +19 -0
  80. package/dist/each.mjs.map +1 -0
  81. package/dist/easing.cjs +151 -0
  82. package/dist/easing.cjs.map +1 -0
  83. package/dist/easing.d.ts +46 -0
  84. package/dist/easing.mjs +151 -0
  85. package/dist/easing.mjs.map +1 -0
  86. package/dist/emitter.cjs +94 -0
  87. package/dist/emitter.cjs.map +1 -0
  88. package/dist/emitter.d.ts +68 -0
  89. package/dist/emitter.mjs +94 -0
  90. package/dist/emitter.mjs.map +1 -0
  91. package/dist/enum.cjs +58 -0
  92. package/dist/enum.cjs.map +1 -0
  93. package/dist/enum.d.ts +68 -0
  94. package/dist/enum.mjs +58 -0
  95. package/dist/enum.mjs.map +1 -0
  96. package/dist/env.cjs +28 -0
  97. package/dist/env.cjs.map +1 -0
  98. package/{src/env.ts → dist/env.d.ts} +6 -30
  99. package/dist/env.mjs +28 -0
  100. package/dist/env.mjs.map +1 -0
  101. package/dist/error.cjs +12 -0
  102. package/dist/error.cjs.map +1 -0
  103. package/{src/error.ts → dist/error.d.ts} +3 -12
  104. package/dist/error.mjs +12 -0
  105. package/dist/error.mjs.map +1 -0
  106. package/dist/exception.cjs +22 -0
  107. package/dist/exception.cjs.map +1 -0
  108. package/dist/exception.d.ts +31 -0
  109. package/dist/exception.mjs +22 -0
  110. package/dist/exception.mjs.map +1 -0
  111. package/dist/fn.cjs +76 -0
  112. package/dist/fn.cjs.map +1 -0
  113. package/dist/fn.d.ts +102 -0
  114. package/dist/fn.mjs +76 -0
  115. package/dist/fn.mjs.map +1 -0
  116. package/dist/index.cjs +5 -0
  117. package/dist/index.cjs.map +1 -0
  118. package/dist/index.d.ts +1 -0
  119. package/dist/index.mjs +5 -0
  120. package/dist/index.mjs.map +1 -0
  121. package/dist/merge.cjs +87 -0
  122. package/dist/merge.cjs.map +1 -0
  123. package/dist/merge.mjs +88 -0
  124. package/dist/merge.mjs.map +1 -0
  125. package/dist/number.cjs +14 -0
  126. package/dist/number.cjs.map +1 -0
  127. package/dist/number.d.ts +153 -0
  128. package/dist/number.mjs +14 -0
  129. package/dist/number.mjs.map +1 -0
  130. package/{src/object/each.ts → dist/object/each.d.ts} +3 -23
  131. package/dist/object/get-set.d.ts +111 -0
  132. package/dist/object/is.d.ts +32 -0
  133. package/dist/object/merge.d.ts +72 -0
  134. package/{src/object/process.ts → dist/object/process.d.ts} +4 -38
  135. package/dist/object.cjs +130 -0
  136. package/dist/object.cjs.map +1 -0
  137. package/dist/object.mjs +130 -0
  138. package/dist/object.mjs.map +1 -0
  139. package/dist/path.cjs +77 -0
  140. package/dist/path.cjs.map +1 -0
  141. package/dist/path.d.ts +82 -0
  142. package/dist/path.mjs +77 -0
  143. package/dist/path.mjs.map +1 -0
  144. package/dist/promise.cjs +62 -0
  145. package/dist/promise.cjs.map +1 -0
  146. package/{src/promise.ts → dist/promise.d.ts} +6 -67
  147. package/dist/promise.mjs +62 -0
  148. package/dist/promise.mjs.map +1 -0
  149. package/dist/qs.cjs +47 -0
  150. package/dist/qs.cjs.map +1 -0
  151. package/{src/qs.ts → dist/qs.d.ts} +3 -60
  152. package/dist/qs.mjs +47 -0
  153. package/dist/qs.mjs.map +1 -0
  154. package/dist/regexp.cjs +66 -0
  155. package/dist/regexp.cjs.map +1 -0
  156. package/dist/regexp.d.ts +65 -0
  157. package/dist/regexp.mjs +66 -0
  158. package/dist/regexp.mjs.map +1 -0
  159. package/dist/string.cjs +16 -0
  160. package/dist/string.cjs.map +1 -0
  161. package/dist/string.d.ts +80 -0
  162. package/dist/string.mjs +16 -0
  163. package/dist/string.mjs.map +1 -0
  164. package/dist/string2.cjs +157 -0
  165. package/dist/string2.cjs.map +1 -0
  166. package/dist/string2.mjs +158 -0
  167. package/dist/string2.mjs.map +1 -0
  168. package/dist/time/from.d.ts +14 -0
  169. package/dist/time/to.d.ts +38 -0
  170. package/dist/time.cjs +82 -0
  171. package/dist/time.cjs.map +1 -0
  172. package/dist/time.mjs +82 -0
  173. package/dist/time.mjs.map +1 -0
  174. package/dist/timer.cjs +119 -0
  175. package/dist/timer.cjs.map +1 -0
  176. package/dist/timer.d.ts +96 -0
  177. package/{src/timer.ts → dist/timer.mjs} +17 -124
  178. package/dist/timer.mjs.map +1 -0
  179. package/dist/tree.cjs +125 -0
  180. package/dist/tree.cjs.map +1 -0
  181. package/{src/tree.ts → dist/tree.d.ts} +41 -225
  182. package/dist/tree.mjs +125 -0
  183. package/dist/tree.mjs.map +1 -0
  184. package/dist/type.cjs +78 -0
  185. package/dist/type.cjs.map +1 -0
  186. package/{src/type.ts → dist/type.d.ts} +20 -96
  187. package/dist/type.mjs +78 -0
  188. package/dist/type.mjs.map +1 -0
  189. package/dist/types.cjs +2 -0
  190. package/dist/types.cjs.map +1 -0
  191. package/{src/types.ts → dist/types.d.ts} +12 -33
  192. package/dist/types.mjs +2 -0
  193. package/dist/types.mjs.map +1 -0
  194. package/dist/unique.cjs +46 -0
  195. package/dist/unique.cjs.map +1 -0
  196. package/dist/unique.d.ts +22 -0
  197. package/dist/unique.mjs +46 -0
  198. package/dist/unique.mjs.map +1 -0
  199. package/dist/url.cjs +37 -0
  200. package/dist/url.cjs.map +1 -0
  201. package/dist/url.d.ts +53 -0
  202. package/dist/url.mjs +37 -0
  203. package/dist/url.mjs.map +1 -0
  204. package/dist/version.cjs +33 -0
  205. package/dist/version.cjs.map +1 -0
  206. package/dist/version.d.ts +32 -0
  207. package/dist/version.mjs +33 -0
  208. package/dist/version.mjs.map +1 -0
  209. package/package.json +8 -2
  210. package/CHANGELOG.md +0 -52
  211. package/src/array.ts +0 -312
  212. package/src/async.ts +0 -379
  213. package/src/base64.ts +0 -20
  214. package/src/cache.ts +0 -146
  215. package/src/color/distance.ts +0 -28
  216. package/src/color/helpers.ts +0 -23
  217. package/src/color/hex-hsl.ts +0 -11
  218. package/src/color/hex-rgb.ts +0 -39
  219. package/src/color/rgb-hsl.ts +0 -53
  220. package/src/color/rgb-hwb.ts +0 -56
  221. package/src/color/rgb-whiter.ts +0 -22
  222. package/src/color/rgb-xyz.ts +0 -62
  223. package/src/crypto/md5.mjs +0 -357
  224. package/src/crypto/sha1.mjs +0 -300
  225. package/src/crypto/sha256.mjs +0 -310
  226. package/src/crypto/sha512.mjs +0 -459
  227. package/src/date/const.ts +0 -6
  228. package/src/date/core.ts +0 -162
  229. package/src/date/days.ts +0 -51
  230. package/src/date/relative.ts +0 -92
  231. package/src/date/start-end.ts +0 -246
  232. package/src/date/timezone.ts +0 -220
  233. package/src/date/weeks.ts +0 -100
  234. package/src/dts/global.d.ts +0 -27
  235. package/src/easing.ts +0 -166
  236. package/src/emitter.ts +0 -117
  237. package/src/enum.ts +0 -171
  238. package/src/exception.ts +0 -68
  239. package/src/fn.ts +0 -197
  240. package/src/index.ts +0 -1
  241. package/src/number.ts +0 -236
  242. package/src/object/get-set.ts +0 -273
  243. package/src/object/is.ts +0 -128
  244. package/src/object/merge.ts +0 -180
  245. package/src/path.ts +0 -188
  246. package/src/regexp.ts +0 -156
  247. package/src/string.ts +0 -146
  248. package/src/time/from.ts +0 -57
  249. package/src/time/to.ts +0 -106
  250. package/src/unique.ts +0 -77
  251. package/src/url.ts +0 -93
  252. package/src/version.ts +0 -71
  253. package/test/array.test.ts +0 -332
  254. package/test/async-real.test.ts +0 -39
  255. package/test/async.test.ts +0 -375
  256. package/test/base64.test.ts +0 -32
  257. package/test/cache.test.ts +0 -83
  258. package/test/color.test.ts +0 -163
  259. package/test/crypto.test.ts +0 -34
  260. package/test/date-tz.test.ts +0 -206
  261. package/test/date.test.ts +0 -353
  262. package/test/easing.test.ts +0 -33
  263. package/test/emitter.test.ts +0 -71
  264. package/test/enum.test.ts +0 -113
  265. package/test/env.test.ts +0 -69
  266. package/test/error.test.ts +0 -58
  267. package/test/exception.test.ts +0 -43
  268. package/test/fn.test.ts +0 -263
  269. package/test/helpers.ts +0 -23
  270. package/test/index.test.ts +0 -6
  271. package/test/number.test.ts +0 -213
  272. package/test/object.test.ts +0 -309
  273. package/test/path.test.ts +0 -156
  274. package/test/promise.test.ts +0 -199
  275. package/test/qs.test.ts +0 -79
  276. package/test/regexp.test.ts +0 -97
  277. package/test/string.test.ts +0 -150
  278. package/test/time.test.ts +0 -214
  279. package/test/timer.test.ts +0 -114
  280. package/test/tree.test.ts +0 -348
  281. package/test/type.test.ts +0 -226
  282. package/test/unique.test.ts +0 -71
  283. package/test/url.test.ts +0 -136
  284. package/test/version.test.ts +0 -52
  285. package/tsconfig.json +0 -31
  286. package/vite.config.mts +0 -114
  287. /package/{src/color.ts → dist/color.d.ts} +0 -0
  288. /package/{src/date.ts → dist/date.d.ts} +0 -0
  289. /package/{src/dict.ts → dist/dict.d.ts} +0 -0
  290. /package/{src/object.ts → dist/object.d.ts} +0 -0
  291. /package/{src/time.ts → dist/time.d.ts} +0 -0
@@ -1,375 +0,0 @@
1
- import { AsyncQueue, asyncLimit, asyncShared } from '@/async';
2
- import { fnNoop } from '@/fn';
3
- import { promiseDelay } from '@/promise';
4
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
5
- import { createAfn } from './helpers';
6
-
7
- beforeEach(() => {
8
- vi.useFakeTimers();
9
- });
10
-
11
- describe('asyncShared', () => {
12
- it('应共享同一个异步函数的结果', async () => {
13
- const mockFn = vi.fn().mockImplementation(async (id: number) => {
14
- await new Promise((resolve) => setTimeout(resolve, 100));
15
- return id;
16
- });
17
-
18
- const sharedFn = asyncShared(mockFn);
19
- const result1 = sharedFn(1);
20
- const result2 = sharedFn(2);
21
- const result3 = sharedFn(3);
22
-
23
- await vi.runAllTimersAsync();
24
- await expect(result1).resolves.toBe(1);
25
- await expect(result2).resolves.toBe(1);
26
- await expect(result3).resolves.toBe(1);
27
- expect(mockFn).toHaveBeenCalledTimes(1); // 三次 calling,一次 execute
28
- });
29
-
30
- it('应遵守 maxAge 设置', async () => {
31
- const mockFn = vi.fn().mockImplementation(async (id: number) => {
32
- await new Promise((resolve) => setTimeout(resolve, 50));
33
- return id;
34
- });
35
-
36
- const sharedFn = asyncShared(mockFn, { maxAge: 100 });
37
- const result1 = sharedFn(1);
38
- await vi.runAllTimersAsync();
39
- await expect(result1).resolves.toBe(1);
40
-
41
- // 在 maxAge 时间内再次调用
42
- await vi.advanceTimersByTimeAsync(50);
43
- const result2 = sharedFn(1);
44
- await vi.runAllTimersAsync();
45
- await expect(result2).resolves.toBe(1);
46
- expect(mockFn).toHaveBeenCalledTimes(1); // 应使用缓存
47
-
48
- // 超过 maxAge 后再次调用
49
- await vi.advanceTimersByTimeAsync(100);
50
- const result3 = sharedFn(1);
51
- await vi.runAllTimersAsync();
52
- await expect(result3).resolves.toBe(1);
53
- expect(mockFn).toHaveBeenCalledTimes(2); // 应重新执行
54
- });
55
-
56
- it('应正确处理 trailing 选项', async () => {
57
- const mockFn = vi.fn().mockImplementation(async (id: number) => {
58
- await new Promise((resolve) => setTimeout(resolve, 100));
59
- return id;
60
- });
61
-
62
- const sharedFn = asyncShared(mockFn, { trailing: true });
63
- const result1 = sharedFn(1);
64
- const result2 = sharedFn(1); // 执行中再次调用
65
-
66
- await vi.runAllTimersAsync();
67
- await expect(result1).resolves.toBe(1);
68
- await expect(result2).resolves.toBe(1);
69
- expect(mockFn).toHaveBeenCalledTimes(2); // 应执行两次
70
-
71
- // 测试 trailing 选项在非执行期间的行为
72
- await vi.advanceTimersByTimeAsync(100);
73
- const result3 = sharedFn(1);
74
- await vi.runAllTimersAsync();
75
- await expect(result3).resolves.toBe(1);
76
- expect(mockFn).toHaveBeenCalledTimes(3); // 应再次执行
77
- });
78
-
79
- it('应正确处理错误情况', async () => {
80
- const error = new Error('test error');
81
- let times = 0;
82
- const mockFn = async () => {
83
- await promiseDelay();
84
- return times++ === 0 ? Promise.reject(error) : Promise.resolve('success');
85
- };
86
-
87
- const sharedFn = asyncShared(mockFn);
88
-
89
- const result1 = sharedFn();
90
- const result2 = sharedFn(); // 共享错误
91
-
92
- await vi.runAllTimersAsync();
93
- await expect(result1).rejects.toThrow(error);
94
- await expect(result2).rejects.toThrow(error);
95
-
96
- // 错误后再次调用应重新执行
97
- const result3 = sharedFn();
98
- await vi.runAllTimersAsync();
99
- await expect(result3).resolves.toBe('success');
100
- });
101
-
102
- it('应正确处理 onTrigger 回调', async () => {
103
- const mockFn = vi.fn().mockResolvedValue(1);
104
- const onTrigger = vi.fn();
105
-
106
- const sharedFn = asyncShared(mockFn, { onTrigger });
107
- sharedFn(1);
108
- sharedFn(1);
109
-
110
- await vi.runAllTimersAsync();
111
- expect(onTrigger).toHaveBeenCalledTimes(2); // 应调用两次
112
- });
113
-
114
- it('应正确处理 onExecute 回调', async () => {
115
- const mockFn = vi.fn().mockResolvedValue(1);
116
- const onTrigger = vi.fn();
117
- const onExecute = vi.fn();
118
-
119
- const sharedFn = asyncShared(mockFn, { onTrigger, onExecute });
120
- sharedFn(1);
121
- sharedFn(1);
122
-
123
- await vi.runAllTimersAsync();
124
- expect(onTrigger).toHaveBeenCalledTimes(2); // 应只触发一次
125
- expect(onExecute).toHaveBeenCalledTimes(1); // 应只调用一次
126
- });
127
-
128
- it('应正确处理 onSuccess 回调', async () => {
129
- const mockFn = vi.fn().mockResolvedValue(1);
130
- const onSuccess = vi.fn();
131
-
132
- const sharedFn = asyncShared(mockFn, { onSuccess });
133
- sharedFn(1);
134
- sharedFn(1);
135
-
136
- await vi.runAllTimersAsync();
137
- expect(onSuccess).toHaveBeenCalledTimes(1); // 应只调用一次
138
- expect(onSuccess).toHaveBeenCalledWith(1);
139
- });
140
-
141
- it('应正确处理 onError 回调', async () => {
142
- const error = new Error('test error');
143
- const mockFn = vi.fn().mockRejectedValue(error);
144
- const onError = vi.fn();
145
-
146
- const sharedFn = asyncShared(mockFn, { onError });
147
- sharedFn(1);
148
- sharedFn(1);
149
-
150
- await vi.runAllTimersAsync();
151
- expect(onError).toHaveBeenCalledTimes(1); // 应只调用一次
152
- expect(onError).toHaveBeenCalledWith(error);
153
- });
154
-
155
- it('应正确处理 onFinally 回调', async () => {
156
- const mockFn = vi.fn().mockResolvedValue(1);
157
- const onFinally = vi.fn();
158
-
159
- const sharedFn = asyncShared(mockFn, { onFinally });
160
- sharedFn(1);
161
- sharedFn(1);
162
-
163
- await vi.runAllTimersAsync();
164
- expect(onFinally).toHaveBeenCalledTimes(1); // 应只调用一次
165
- });
166
- });
167
-
168
- afterEach(() => {
169
- vi.restoreAllMocks();
170
- });
171
-
172
- describe('asyncLimit', () => {
173
- it('应正确处理空 Promise 数组', async () => {
174
- const results = await asyncLimit([], 2);
175
- expect(results).toEqual([]);
176
- });
177
-
178
- it('应在限制数量内并发执行 Promise', async () => {
179
- const delays = [100, 50, 200, 150];
180
- const results = asyncLimit(
181
- delays.map((delay) =>
182
- createAfn({
183
- delay: delay,
184
- result: delay,
185
- }),
186
- ),
187
- 2,
188
- );
189
-
190
- await vi.runAllTimersAsync();
191
- await expect(results).resolves.toEqual(delays);
192
- });
193
-
194
- it('应正确处理小于限制数量的 Promise', async () => {
195
- const delays = [100, 50];
196
- const results = asyncLimit(
197
- delays.map((delay) =>
198
- createAfn({
199
- delay: delay,
200
- result: delay,
201
- }),
202
- ),
203
- 5,
204
- );
205
-
206
- await vi.runAllTimersAsync();
207
- await expect(results).resolves.toEqual(delays);
208
- });
209
-
210
- it('应正确处理超过限制数量的 Promise', async () => {
211
- const delays = [100, 50, 200, 150, 300];
212
- const startTime = Date.now();
213
- const fn = vi.fn();
214
- const results = asyncLimit(
215
- delays.map((delay) =>
216
- createAfn({
217
- delay: delay,
218
- result: delay,
219
- onResolved() {
220
- fn(Date.now() - startTime);
221
- },
222
- }),
223
- ),
224
- 2,
225
- );
226
-
227
- await vi.runAllTimersAsync();
228
- await expect(results).resolves.toEqual(delays);
229
- expect(fn).toHaveBeenCalledTimes(5);
230
- });
231
- });
232
-
233
- describe('AsyncQueue', () => {
234
- it('应按顺序执行任务', async () => {
235
- const delays = [100, 50, 200];
236
- const queue = new AsyncQueue(
237
- delays.map((delay) =>
238
- createAfn({
239
- delay: delay,
240
- result: delay,
241
- }),
242
- ),
243
- );
244
-
245
- const startPromise = queue.start();
246
- await vi.runAllTimersAsync();
247
- await expect(startPromise).resolves.toEqual(delays);
248
- });
249
-
250
- it('应正确处理空任务队列', async () => {
251
- const queue = new AsyncQueue<number>([]);
252
- const result = await queue.start();
253
- expect(result).toEqual([]);
254
- });
255
-
256
- it('应正确处理单个任务', async () => {
257
- const queue = new AsyncQueue([createAfn({ delay: 100, result: 1 })]);
258
- const result = queue.start();
259
- await vi.runAllTimersAsync();
260
- await expect(result).resolves.toEqual([1]);
261
- });
262
-
263
- it('应正确处理多个任务', async () => {
264
- const delays = [100, 50, 200];
265
- const queue = new AsyncQueue(
266
- delays.map((delay) =>
267
- createAfn({
268
- delay: delay,
269
- result: delay,
270
- }),
271
- ),
272
- );
273
-
274
- const result = queue.start();
275
- await vi.runAllTimersAsync();
276
- await expect(result).resolves.toEqual(delays);
277
- });
278
-
279
- it('应正确处理任务失败', async () => {
280
- const error = new Error('test error');
281
- const queue = new AsyncQueue([() => Promise.reject(error)]);
282
-
283
- await expect(queue.start()).rejects.toThrow(error);
284
- });
285
-
286
- it('应正确处理任务添加和启动顺序', async () => {
287
- const queue = new AsyncQueue([]);
288
- const delay = 100;
289
- const promise1 = queue.push(() =>
290
- createAfn({
291
- delay: delay,
292
- result: delay,
293
- })(),
294
- );
295
-
296
- const promise2 = queue.start();
297
- await vi.runAllTimersAsync();
298
- await expect(promise1).resolves.toEqual(delay);
299
- await expect(promise2).resolves.toEqual([delay]);
300
- });
301
-
302
- it('应正确处理并发限制', async () => {
303
- const delays = [100, 50, 200, 150];
304
- const fn = vi.fn();
305
- const queue = new AsyncQueue(
306
- delays.map((delay) =>
307
- createAfn({
308
- delay: delay,
309
- result: delay,
310
- onResolved() {
311
- fn();
312
- },
313
- }),
314
- ),
315
- { limit: 2 },
316
- );
317
-
318
- queue.start();
319
- expect(fn).toHaveBeenCalledTimes(0);
320
- await vi.advanceTimersByTimeAsync(50);
321
- expect(fn).toHaveBeenCalledTimes(1);
322
- await vi.advanceTimersByTimeAsync(50);
323
- expect(fn).toHaveBeenCalledTimes(2);
324
- await vi.runAllTimersAsync();
325
- expect(fn).toHaveBeenCalledTimes(4);
326
- });
327
-
328
- it('应正确处理任务停止', async () => {
329
- const delays = [100, 50, 200];
330
- const queue = new AsyncQueue(
331
- delays.map((delay) =>
332
- createAfn({
333
- delay: delay,
334
- result: delay,
335
- }),
336
- ),
337
- );
338
-
339
- const startPromise = queue.start();
340
- const stopPromise = queue.stop();
341
- await vi.runAllTimersAsync();
342
- await expect(startPromise).resolves.toEqual([100, 50, 200]);
343
- await expect(stopPromise).resolves.toEqual([100, 50, 200]);
344
- });
345
-
346
- it('应正确处理多次停止', async () => {
347
- const delays = [100, 50, 200];
348
- const queue = new AsyncQueue(
349
- delays.map((delay) =>
350
- createAfn({
351
- delay: delay,
352
- result: delay,
353
- }),
354
- ),
355
- );
356
-
357
- const startPromise = queue.start();
358
- const stopPromise1 = queue.stop();
359
- const stopPromise2 = queue.stop();
360
- await vi.runAllTimersAsync();
361
- await expect(startPromise).resolves.toEqual([100, 50, 200]);
362
- await expect(stopPromise1).resolves.toEqual([100, 50, 200]);
363
- await expect(stopPromise2).resolves.toEqual([100, 50, 200]);
364
- });
365
-
366
- it('应正确处理停止后添加任务', async () => {
367
- const queue = new AsyncQueue([]);
368
- const stopPromise = queue.stop();
369
- const pushPromise = queue.push(createAfn({ delay: 100, result: 1 }));
370
- pushPromise.catch(fnNoop);
371
- await vi.runAllTimersAsync();
372
- await expect(stopPromise).resolves.toEqual([]);
373
- await expect(pushPromise).rejects.toThrow('异步队列已被终止,无法添加新的任务');
374
- });
375
- });
@@ -1,32 +0,0 @@
1
- import { base64toBlob } from '@/base64';
2
- import { describe, expect, test } from 'vitest';
3
-
4
- describe('base64toBlob', () => {
5
- // 通用验证方法
6
- const validateBlob = (base64: string, expectedType: string) => {
7
- const blob = base64toBlob(base64);
8
- expect(blob).toBeInstanceOf(Blob);
9
- expect(blob.type).toBe(expectedType);
10
- return blob;
11
- };
12
-
13
- test('PNG 转换验证', () => {
14
- const pngBase64 =
15
- 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
16
- const blob = validateBlob(pngBase64, 'image/png');
17
- expect(blob.size).toBe(70); // 实际解码后的字节长度
18
- });
19
-
20
- test('JPEG 转换验证', () => {
21
- const jpegBase64 =
22
- 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAf/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AJVAAP/aAAwDAQACEQMRAD8AlUAA//Z';
23
- const blob = validateBlob(jpegBase64, 'image/jpeg');
24
- expect(blob.size).toBe(302);
25
- });
26
-
27
- test('无数据前缀处理', () => {
28
- const rawBase64 =
29
- 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
30
- expect(() => base64toBlob(rawBase64)).toThrowError();
31
- });
32
- });
@@ -1,83 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { MemoryCache, createMemCache } from '../src/cache';
3
-
4
- describe('内存缓存', () => {
5
- let cache: MemoryCache<string>;
6
-
7
- beforeEach(() => {
8
- cache = createMemCache<string>();
9
- vi.useFakeTimers();
10
- });
11
-
12
- afterEach(() => {
13
- vi.useRealTimers();
14
- });
15
-
16
- it('应该能够设置和获取缓存', () => {
17
- cache.set('key1', 'value1');
18
- expect(cache.get('key1')?.data).toBe('value1');
19
- });
20
-
21
- it('获取不存在的缓存应该返回 null', () => {
22
- expect(cache.get('non-existent')).toBeNull();
23
- });
24
-
25
- it('应该能够删除缓存', () => {
26
- cache.set('key1', 'value1');
27
- cache.del('key1');
28
- expect(cache.get('key1')).toBeNull();
29
- });
30
-
31
- it('缓存过期后应该返回 null', () => {
32
- cache.set('key1', 'value1', { maxAge: 1000 });
33
- vi.advanceTimersByTime(1001);
34
- expect(cache.get('key1')).toBeNull();
35
- });
36
-
37
- it('未设置 maxAge 的缓存应该不会过期', () => {
38
- cache.set('key1', 'value1');
39
- vi.advanceTimersByTime(10000);
40
- expect(cache.get('key1')?.data).toBe('value1');
41
- });
42
-
43
- it('createMemCache 应该返回一个新的 MemoryCache 实例', () => {
44
- const newCache = createMemCache<string>();
45
- expect(newCache).toBeInstanceOf(MemoryCache);
46
- });
47
-
48
- it('expiredAt 应该优先于 maxAge', () => {
49
- const future = Date.now() + 5000;
50
- cache.set('key1', 'value1', { maxAge: 10000, expiredAt: future });
51
- vi.advanceTimersByTime(6000);
52
- expect(cache.get('key1')).toBeNull();
53
- });
54
-
55
- it('应该能够清空缓存', () => {
56
- cache.set('key1', 'value1');
57
- cache.set('key2', 'value2');
58
- cache.clear();
59
- expect(cache.get('key1')).toBeNull();
60
- expect(cache.get('key2')).toBeNull();
61
- });
62
-
63
- it('normalizeCached 应该正确处理过期时间', () => {
64
- const now = Date.now();
65
- const cached = cache.normalizeCached('key1', 'value1', {
66
- maxAge: 1000,
67
- expiredAt: now + 2000,
68
- });
69
- expect(cached.expiredAt).toBe(now + 2000);
70
- });
71
-
72
- it('isExpired 应该正确判断缓存是否过期', () => {
73
- const cached = {
74
- id: 'key1',
75
- data: 'value1',
76
- createdAt: Date.now(),
77
- expiredAt: Date.now() + 1000,
78
- };
79
- expect(cache.isExpired(cached)).toBe(false);
80
- vi.advanceTimersByTime(1001);
81
- expect(cache.isExpired(cached)).toBe(true);
82
- });
83
- });
@@ -1,163 +0,0 @@
1
- import type { HEX, HSL, HSV, HWB, RGB } from '@/color';
2
- import {
3
- distance,
4
- hexToHsl,
5
- hexToHsv,
6
- hexToHwb,
7
- hexToRgb,
8
- hslToHex,
9
- hslToRgb,
10
- hsvToHex,
11
- hsvToRgb,
12
- hwbToHex,
13
- hwbToRgb,
14
- mix,
15
- rgbToHex,
16
- rgbToHsl,
17
- rgbToHsv,
18
- rgbToHwb,
19
- rgbToXyz,
20
- xyzToLab,
21
- } from '@/color';
22
- import { expect, test } from 'vitest';
23
-
24
- test('颜色值转换', () => {
25
- expect(hexToRgb('#00ff00')).toEqual<RGB>({ r: 0, g: 255, b: 0 });
26
- expect(hexToRgb('#f5222d')).toEqual<RGB>({ r: 245, g: 34, b: 45 });
27
- expect(rgbToHex({ r: 245, g: 34, b: 45 })).toEqual('#f5222d');
28
-
29
- expect(rgbToHsv({ r: 245, g: 34, b: 45 })).toEqual<HSV>({
30
- h: 356.87203791469193,
31
- s: 86.12244897959184,
32
- v: 96.07843137254902,
33
- });
34
- expect(hsvToRgb({ h: 357, s: 86, v: 96 })).toEqual<RGB>({
35
- r: 244.79999999999998,
36
- g: 34.272000000000006,
37
- b: 44.79839999999996,
38
- });
39
-
40
- expect(hexToHsv('#f5222d')).toEqual<HSV>({
41
- h: 356.87203791469193,
42
- s: 86.12244897959184,
43
- v: 96.07843137254902,
44
- });
45
- expect(
46
- hsvToHex({
47
- h: 356.87203791469193,
48
- s: 86.12244897959184,
49
- v: 96.07843137254902,
50
- }),
51
- ).toEqual('#f5222d');
52
-
53
- expect(
54
- rgbToHsl({
55
- r: 245,
56
- g: 34,
57
- b: 45,
58
- }),
59
- ).toEqual<HSL>({
60
- h: 356.87203791469193,
61
- l: 54.70588235294118,
62
- s: 91.34199134199136,
63
- });
64
- expect(
65
- hslToRgb({
66
- h: 356.87203791469193,
67
- l: 54.70588235294118,
68
- s: 91.34199134199136,
69
- }),
70
- ).toEqual<RGB>({
71
- r: 245.00000000000003,
72
- g: 34.00000000000001,
73
- b: 45.00000000000001,
74
- });
75
-
76
- expect(
77
- rgbToHsl({
78
- r: 0,
79
- g: 100,
80
- b: 213,
81
- }),
82
- ).toEqual<HSL>({
83
- h: 211.83098591549296,
84
- s: 100,
85
- l: 41.76470588235294,
86
- });
87
- expect(hexToHsl('#123456')).toEqual<HSL>({
88
- h: 210,
89
- s: 65.3846153846154,
90
- l: 20.392156862745097,
91
- });
92
- expect(
93
- hslToHex({
94
- h: 210,
95
- s: 65,
96
- l: 20,
97
- }),
98
- ).toEqual<HEX>('#123354');
99
-
100
- expect(
101
- rgbToHwb({
102
- r: 12,
103
- g: 34,
104
- b: 56,
105
- }),
106
- ).toEqual<HWB>({
107
- h: 210,
108
- w: 4.705882352941177,
109
- b: 78.03921568627452,
110
- });
111
- expect(
112
- hwbToRgb({
113
- h: 210,
114
- w: 4.705882352941177,
115
- b: 78.03921568627452,
116
- }),
117
- ).toEqual<RGB>({
118
- r: 12,
119
- g: 33.99999999999998,
120
- b: 55.99999999999996,
121
- });
122
-
123
- expect(hexToHwb('#fedcba')).toEqual<HWB>({
124
- h: 30.000000000000014,
125
- w: 72.94117647058823,
126
- b: 0.39215686274509665,
127
- });
128
- expect(
129
- hwbToHex({
130
- h: 30.000000000000014,
131
- w: 72.94117647058823,
132
- b: 0.39215686274509665,
133
- }),
134
- ).toEqual<HEX>('#fedcba');
135
- });
136
-
137
- test('mix', () => {
138
- expect(rgbToHex(mix(hexToRgb('#00ff00'), hexToRgb('#ff0000')))).toEqual('#808000');
139
- expect(hsvToHex(mix(hexToHsv('#00ff00'), hexToHsv('#ff0000')))).toEqual('#ffff00');
140
- });
141
-
142
- test('lab', () => {
143
- const color1 = '#9ea9b5';
144
- const color2 = '#8592a1';
145
-
146
- const rgb1 = hexToRgb(color1);
147
- const rgb2 = hexToRgb(color2);
148
-
149
- const xyz1 = rgbToXyz(rgb1);
150
- const xyz2 = rgbToXyz(rgb2);
151
-
152
- const lab1 = xyzToLab(xyz1);
153
- const lab2 = xyzToLab(xyz2);
154
-
155
- const d = distance(lab1, lab2);
156
-
157
- // console.log(lab1);
158
- // console.log(lab2);
159
- // console.log(d);
160
-
161
- expect(d).toBeLessThan(1);
162
- expect(d).toBeGreaterThan(0);
163
- });
@@ -1,34 +0,0 @@
1
- import { md5String, sha1String, sha256String, sha512String } from '@/crypto';
2
- import { describe, expect, it } from 'vitest';
3
-
4
- describe('crypto', () => {
5
- it('md5String 应正确计算 MD5 哈希值', () => {
6
- expect(md5String('hello world')).toBe('5eb63bbbe01eeed093cb22bb8f5acdc3');
7
- expect(md5String('')).toBe('d41d8cd98f00b204e9800998ecf8427e');
8
- expect(md5String('123456')).toBe('e10adc3949ba59abbe56e057f20f883e');
9
- });
10
-
11
- it('sha1String 应正确计算 SHA1 哈希值', () => {
12
- expect(sha1String('hello world')).toBe('2aae6c35c94fcfb415dbe95f408b9ce91ee846ed');
13
- expect(sha1String('')).toBe('da39a3ee5e6b4b0d3255bfef95601890afd80709');
14
- expect(sha1String('123456')).toBe('7c4a8d09ca3762af61e59520943dc26494f8941b');
15
- });
16
-
17
- it('sha256String 应正确计算 SHA256 哈希值', () => {
18
- expect(sha256String('hello world')).toBe('b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9');
19
- expect(sha256String('')).toBe('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
20
- expect(sha256String('123456')).toBe('8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92');
21
- });
22
-
23
- it('sha512String 应正确计算 SHA512 哈希值', () => {
24
- expect(sha512String('hello world')).toBe(
25
- '309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f',
26
- );
27
- expect(sha512String('')).toBe(
28
- 'cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e',
29
- );
30
- expect(sha512String('123456')).toBe(
31
- 'ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413',
32
- );
33
- });
34
- });