@cloudcome/utils-core 1.1.1 → 1.2.1

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 (293) hide show
  1. package/README.md +18 -0
  2. package/dist/array.cjs +129 -0
  3. package/dist/array.cjs.map +1 -0
  4. package/dist/array.d.ts +171 -0
  5. package/dist/array.mjs +129 -0
  6. package/dist/array.mjs.map +1 -0
  7. package/dist/async.cjs +219 -0
  8. package/dist/async.cjs.map +1 -0
  9. package/dist/async.d.ts +137 -0
  10. package/dist/async.mjs +219 -0
  11. package/dist/async.mjs.map +1 -0
  12. package/dist/base64.cjs +16 -0
  13. package/dist/base64.cjs.map +1 -0
  14. package/dist/base64.d.ts +7 -0
  15. package/dist/base64.mjs +16 -0
  16. package/dist/base64.mjs.map +1 -0
  17. package/dist/cache.cjs +79 -0
  18. package/dist/cache.cjs.map +1 -0
  19. package/dist/cache.d.ts +90 -0
  20. package/dist/cache.mjs +79 -0
  21. package/dist/cache.mjs.map +1 -0
  22. package/{src/color/contrast.ts → dist/color/contrast.d.ts} +2 -12
  23. package/dist/color/distance.d.ts +8 -0
  24. package/dist/color/helpers.d.ts +2 -0
  25. package/dist/color/hex-hsl.d.ts +3 -0
  26. package/{src/color/hex-hsv.ts → dist/color/hex-hsv.d.ts} +3 -11
  27. package/{src/color/hex-hwb.ts → dist/color/hex-hwb.d.ts} +3 -11
  28. package/dist/color/hex-rgb.d.ts +18 -0
  29. package/{src/color/hsl-lighten.ts → dist/color/hsl-lighten.d.ts} +2 -7
  30. package/{src/color/hsv-brighten.ts → dist/color/hsv-brighten.d.ts} +2 -7
  31. package/{src/color/luminance.ts → dist/color/luminance.d.ts} +2 -9
  32. package/{src/color/mix.ts → dist/color/mix.d.ts} +2 -10
  33. package/dist/color/rgb-hsl.d.ts +23 -0
  34. package/{src/color/rgb-hsv.ts → dist/color/rgb-hsv.d.ts} +3 -30
  35. package/dist/color/rgb-hwb.d.ts +29 -0
  36. package/{src/color/rgb-lab.ts → dist/color/rgb-lab.d.ts} +3 -11
  37. package/dist/color/rgb-whiter.d.ts +12 -0
  38. package/dist/color/rgb-xyz.d.ts +22 -0
  39. package/{src/color/types.ts → dist/color/types.d.ts} +30 -12
  40. package/{src/color/xyz-lab.ts → dist/color/xyz-lab.d.ts} +3 -32
  41. package/dist/color.cjs +250 -0
  42. package/dist/color.cjs.map +1 -0
  43. package/dist/color.mjs +250 -0
  44. package/dist/color.mjs.map +1 -0
  45. package/dist/const.cjs +14 -0
  46. package/dist/const.cjs.map +1 -0
  47. package/dist/const.mjs +15 -0
  48. package/dist/const.mjs.map +1 -0
  49. package/dist/core.cjs +250 -0
  50. package/dist/core.cjs.map +1 -0
  51. package/dist/core.mjs +251 -0
  52. package/dist/core.mjs.map +1 -0
  53. package/dist/crypto/md5.d.mts +1 -0
  54. package/dist/crypto/sha1.d.mts +1 -0
  55. package/dist/crypto/sha256.d.mts +1 -0
  56. package/dist/crypto/sha512.d.mts +1 -0
  57. package/dist/crypto.cjs +812 -0
  58. package/dist/crypto.cjs.map +1 -0
  59. package/{src/crypto.ts → dist/crypto.d.ts} +4 -20
  60. package/dist/crypto.mjs +812 -0
  61. package/dist/crypto.mjs.map +1 -0
  62. package/dist/date/const.d.ts +6 -0
  63. package/dist/date/core.d.ts +52 -0
  64. package/dist/date/days.d.ts +23 -0
  65. package/{src/date/is.ts → dist/date/is.d.ts} +8 -102
  66. package/dist/date/relative.d.ts +44 -0
  67. package/dist/date/start-end.d.ts +73 -0
  68. package/dist/date/timezone.d.ts +67 -0
  69. package/dist/date/weeks.d.ts +72 -0
  70. package/dist/date.cjs +239 -0
  71. package/dist/date.cjs.map +1 -0
  72. package/dist/date.mjs +241 -0
  73. package/dist/date.mjs.map +1 -0
  74. package/dist/dict.cjs +2 -0
  75. package/dist/dict.cjs.map +1 -0
  76. package/dist/dict.mjs +2 -0
  77. package/dist/dict.mjs.map +1 -0
  78. package/dist/each.cjs +18 -0
  79. package/dist/each.cjs.map +1 -0
  80. package/dist/each.mjs +19 -0
  81. package/dist/each.mjs.map +1 -0
  82. package/dist/easing.cjs +151 -0
  83. package/dist/easing.cjs.map +1 -0
  84. package/dist/easing.d.ts +46 -0
  85. package/dist/easing.mjs +151 -0
  86. package/dist/easing.mjs.map +1 -0
  87. package/dist/emitter.cjs +94 -0
  88. package/dist/emitter.cjs.map +1 -0
  89. package/dist/emitter.d.ts +68 -0
  90. package/dist/emitter.mjs +94 -0
  91. package/dist/emitter.mjs.map +1 -0
  92. package/dist/enum.cjs +58 -0
  93. package/dist/enum.cjs.map +1 -0
  94. package/dist/enum.d.ts +68 -0
  95. package/dist/enum.mjs +58 -0
  96. package/dist/enum.mjs.map +1 -0
  97. package/dist/env.cjs +28 -0
  98. package/dist/env.cjs.map +1 -0
  99. package/{src/env.ts → dist/env.d.ts} +6 -30
  100. package/dist/env.mjs +28 -0
  101. package/dist/env.mjs.map +1 -0
  102. package/dist/error.cjs +12 -0
  103. package/dist/error.cjs.map +1 -0
  104. package/{src/error.ts → dist/error.d.ts} +3 -12
  105. package/dist/error.mjs +12 -0
  106. package/dist/error.mjs.map +1 -0
  107. package/dist/exception.cjs +22 -0
  108. package/dist/exception.cjs.map +1 -0
  109. package/dist/exception.d.ts +31 -0
  110. package/dist/exception.mjs +22 -0
  111. package/dist/exception.mjs.map +1 -0
  112. package/dist/fn.cjs +76 -0
  113. package/dist/fn.cjs.map +1 -0
  114. package/dist/fn.d.ts +102 -0
  115. package/dist/fn.mjs +76 -0
  116. package/dist/fn.mjs.map +1 -0
  117. package/dist/index.cjs +5 -0
  118. package/dist/index.cjs.map +1 -0
  119. package/dist/index.d.ts +1 -0
  120. package/dist/index.mjs +5 -0
  121. package/dist/index.mjs.map +1 -0
  122. package/dist/merge.cjs +87 -0
  123. package/dist/merge.cjs.map +1 -0
  124. package/dist/merge.mjs +88 -0
  125. package/dist/merge.mjs.map +1 -0
  126. package/dist/number.cjs +14 -0
  127. package/dist/number.cjs.map +1 -0
  128. package/dist/number.d.ts +153 -0
  129. package/dist/number.mjs +14 -0
  130. package/dist/number.mjs.map +1 -0
  131. package/{src/object/each.ts → dist/object/each.d.ts} +3 -23
  132. package/dist/object/get-set.d.ts +111 -0
  133. package/dist/object/is.d.ts +32 -0
  134. package/dist/object/merge.d.ts +72 -0
  135. package/{src/object/process.ts → dist/object/process.d.ts} +4 -38
  136. package/dist/object.cjs +130 -0
  137. package/dist/object.cjs.map +1 -0
  138. package/dist/object.mjs +130 -0
  139. package/dist/object.mjs.map +1 -0
  140. package/dist/path.cjs +77 -0
  141. package/dist/path.cjs.map +1 -0
  142. package/dist/path.d.ts +82 -0
  143. package/dist/path.mjs +77 -0
  144. package/dist/path.mjs.map +1 -0
  145. package/dist/promise.cjs +62 -0
  146. package/dist/promise.cjs.map +1 -0
  147. package/{src/promise.ts → dist/promise.d.ts} +6 -67
  148. package/dist/promise.mjs +62 -0
  149. package/dist/promise.mjs.map +1 -0
  150. package/dist/qs.cjs +47 -0
  151. package/dist/qs.cjs.map +1 -0
  152. package/{src/qs.ts → dist/qs.d.ts} +3 -60
  153. package/dist/qs.mjs +47 -0
  154. package/dist/qs.mjs.map +1 -0
  155. package/dist/regexp.cjs +66 -0
  156. package/dist/regexp.cjs.map +1 -0
  157. package/dist/regexp.d.ts +65 -0
  158. package/dist/regexp.mjs +66 -0
  159. package/dist/regexp.mjs.map +1 -0
  160. package/dist/string.cjs +16 -0
  161. package/dist/string.cjs.map +1 -0
  162. package/dist/string.d.ts +80 -0
  163. package/dist/string.mjs +16 -0
  164. package/dist/string.mjs.map +1 -0
  165. package/dist/string2.cjs +157 -0
  166. package/dist/string2.cjs.map +1 -0
  167. package/dist/string2.mjs +158 -0
  168. package/dist/string2.mjs.map +1 -0
  169. package/dist/time/from.d.ts +14 -0
  170. package/dist/time/to.d.ts +38 -0
  171. package/dist/time.cjs +82 -0
  172. package/dist/time.cjs.map +1 -0
  173. package/dist/time.mjs +82 -0
  174. package/dist/time.mjs.map +1 -0
  175. package/dist/timer.cjs +119 -0
  176. package/dist/timer.cjs.map +1 -0
  177. package/dist/timer.d.ts +96 -0
  178. package/{src/timer.ts → dist/timer.mjs} +17 -124
  179. package/dist/timer.mjs.map +1 -0
  180. package/dist/tree.cjs +125 -0
  181. package/dist/tree.cjs.map +1 -0
  182. package/dist/tree.d.ts +210 -0
  183. package/dist/tree.mjs +125 -0
  184. package/dist/tree.mjs.map +1 -0
  185. package/dist/type.cjs +78 -0
  186. package/dist/type.cjs.map +1 -0
  187. package/{src/type.ts → dist/type.d.ts} +20 -96
  188. package/dist/type.mjs +78 -0
  189. package/dist/type.mjs.map +1 -0
  190. package/dist/types.cjs +2 -0
  191. package/dist/types.cjs.map +1 -0
  192. package/{src/types.ts → dist/types.d.ts} +12 -33
  193. package/dist/types.mjs +2 -0
  194. package/dist/types.mjs.map +1 -0
  195. package/dist/unique.cjs +46 -0
  196. package/dist/unique.cjs.map +1 -0
  197. package/dist/unique.d.ts +22 -0
  198. package/dist/unique.mjs +46 -0
  199. package/dist/unique.mjs.map +1 -0
  200. package/dist/url.cjs +37 -0
  201. package/dist/url.cjs.map +1 -0
  202. package/dist/url.d.ts +53 -0
  203. package/dist/url.mjs +37 -0
  204. package/dist/url.mjs.map +1 -0
  205. package/dist/version.cjs +33 -0
  206. package/dist/version.cjs.map +1 -0
  207. package/dist/version.d.ts +32 -0
  208. package/dist/version.mjs +33 -0
  209. package/dist/version.mjs.map +1 -0
  210. package/package.json +8 -2
  211. package/CHANGELOG.md +0 -52
  212. package/src/array.ts +0 -312
  213. package/src/async.ts +0 -379
  214. package/src/base64.ts +0 -20
  215. package/src/cache.ts +0 -146
  216. package/src/color/distance.ts +0 -28
  217. package/src/color/helpers.ts +0 -23
  218. package/src/color/hex-hsl.ts +0 -11
  219. package/src/color/hex-rgb.ts +0 -39
  220. package/src/color/rgb-hsl.ts +0 -53
  221. package/src/color/rgb-hwb.ts +0 -56
  222. package/src/color/rgb-whiter.ts +0 -22
  223. package/src/color/rgb-xyz.ts +0 -62
  224. package/src/crypto/md5.mjs +0 -357
  225. package/src/crypto/sha1.mjs +0 -300
  226. package/src/crypto/sha256.mjs +0 -310
  227. package/src/crypto/sha512.mjs +0 -459
  228. package/src/date/const.ts +0 -6
  229. package/src/date/core.ts +0 -162
  230. package/src/date/days.ts +0 -51
  231. package/src/date/relative.ts +0 -92
  232. package/src/date/start-end.ts +0 -246
  233. package/src/date/timezone.ts +0 -220
  234. package/src/date/weeks.ts +0 -100
  235. package/src/dts/global.d.ts +0 -27
  236. package/src/easing.ts +0 -166
  237. package/src/emitter.ts +0 -117
  238. package/src/enum.ts +0 -171
  239. package/src/exception.ts +0 -68
  240. package/src/fn.ts +0 -197
  241. package/src/index.ts +0 -1
  242. package/src/number.ts +0 -236
  243. package/src/object/get-set.ts +0 -273
  244. package/src/object/is.ts +0 -128
  245. package/src/object/merge.ts +0 -180
  246. package/src/path.ts +0 -188
  247. package/src/regexp.ts +0 -156
  248. package/src/string.ts +0 -146
  249. package/src/time/from.ts +0 -57
  250. package/src/time/to.ts +0 -106
  251. package/src/tree.ts +0 -394
  252. package/src/unique.ts +0 -77
  253. package/src/url.ts +0 -93
  254. package/src/version.ts +0 -71
  255. package/test/array.test.ts +0 -332
  256. package/test/async-real.test.ts +0 -39
  257. package/test/async.test.ts +0 -375
  258. package/test/base64.test.ts +0 -32
  259. package/test/cache.test.ts +0 -83
  260. package/test/color.test.ts +0 -163
  261. package/test/crypto.test.ts +0 -34
  262. package/test/date-tz.test.ts +0 -206
  263. package/test/date.test.ts +0 -353
  264. package/test/easing.test.ts +0 -33
  265. package/test/emitter.test.ts +0 -71
  266. package/test/enum.test.ts +0 -113
  267. package/test/env.test.ts +0 -69
  268. package/test/error.test.ts +0 -58
  269. package/test/exception.test.ts +0 -43
  270. package/test/fn.test.ts +0 -263
  271. package/test/helpers.ts +0 -23
  272. package/test/index.test.ts +0 -6
  273. package/test/number.test.ts +0 -213
  274. package/test/object.test.ts +0 -309
  275. package/test/path.test.ts +0 -156
  276. package/test/promise.test.ts +0 -199
  277. package/test/qs.test.ts +0 -79
  278. package/test/regexp.test.ts +0 -97
  279. package/test/string.test.ts +0 -150
  280. package/test/time.test.ts +0 -214
  281. package/test/timer.test.ts +0 -114
  282. package/test/tree.test.ts +0 -348
  283. package/test/type.test.ts +0 -226
  284. package/test/unique.test.ts +0 -71
  285. package/test/url.test.ts +0 -136
  286. package/test/version.test.ts +0 -52
  287. package/tsconfig.json +0 -31
  288. package/vite.config.mts +0 -114
  289. /package/{src/color.ts → dist/color.d.ts} +0 -0
  290. /package/{src/date.ts → dist/date.d.ts} +0 -0
  291. /package/{src/dict.ts → dist/dict.d.ts} +0 -0
  292. /package/{src/object.ts → dist/object.d.ts} +0 -0
  293. /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
- });