@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,213 +0,0 @@
1
- import { fileSizeAbbr } from '@/number';
2
- import { numberAbbr, numberConvert, numberFixed, numberFormat, randomNumber } from '@/number';
3
- import { describe, expect, it } from 'vitest';
4
-
5
- describe('randomNumber', () => {
6
- it('应在指定范围内生成随机整数', () => {
7
- for (let i = 0; i < 100; i++) {
8
- const result = randomNumber(1, 10);
9
- expect(result).toBeGreaterThanOrEqual(1);
10
- expect(result).toBeLessThanOrEqual(10);
11
- }
12
- });
13
-
14
- it('应处理 min 大于 max 的情况', () => {
15
- for (let i = 0; i < 100; i++) {
16
- const result = randomNumber(10, 1);
17
- expect(result).toBeGreaterThanOrEqual(1);
18
- expect(result).toBeLessThanOrEqual(10);
19
- }
20
- });
21
-
22
- it('应处理边界情况', () => {
23
- expect(randomNumber(0, 0)).toBe(0);
24
- expect(randomNumber(5, 5)).toBe(5);
25
- });
26
-
27
- it('应处理负数范围', () => {
28
- for (let i = 0; i < 100; i++) {
29
- const result = randomNumber(-10, -1);
30
- expect(result).toBeGreaterThanOrEqual(-10);
31
- expect(result).toBeLessThanOrEqual(-1);
32
- }
33
- });
34
-
35
- it('应处理负数和正数混合范围', () => {
36
- for (let i = 0; i < 100; i++) {
37
- const result = randomNumber(-5, 5);
38
- expect(result).toBeGreaterThanOrEqual(-5);
39
- expect(result).toBeLessThanOrEqual(5);
40
- }
41
- });
42
- });
43
-
44
- describe('numberAbbr', () => {
45
- it('应正确转换数字为带单位的缩写', () => {
46
- expect(numberAbbr(1500, ['', 'K', 'M'], { base: 1000 })).toBe('1K');
47
- expect(numberAbbr(123456, ['B', 'KB', 'MB'], { precision: 1 })).toBe('123.4KB');
48
- expect(numberAbbr(500, ['B', 'KB'])).toBe('500B');
49
- });
50
-
51
- it('应处理单位数组为空的情况', () => {
52
- expect(() => numberAbbr(1000, [])).toThrow('数字单位组不能为空');
53
- });
54
-
55
- it('应处理自定义进制基数', () => {
56
- expect(numberAbbr(1024, ['B', 'KB', 'MB'], { base: 1024 })).toBe('1KB');
57
- expect(numberAbbr(1048576, ['B', 'KB', 'MB'], { base: 1024 })).toBe('1MB');
58
- expect(numberAbbr(1048576, ['', '万', '亿'], { base: 10000 })).toBe('104万');
59
- expect(numberAbbr(10485769, ['', '万', '亿'], { base: 10000 })).toBe('1048万');
60
- expect(numberAbbr(10485769012, ['', '万', '亿'], { base: 10000 })).toBe('104亿');
61
- });
62
-
63
- it('应处理小数位数', () => {
64
- expect(numberAbbr(1234, ['', 'K', 'M'], { precision: 2 })).toBe('1.23K');
65
- expect(numberAbbr(1234567, ['', 'K', 'M'], { precision: 3 })).toBe('1.234M');
66
- });
67
-
68
- it('应处理不足基数的情况', () => {
69
- expect(numberAbbr(999, ['', 'K', 'M'])).toBe('999');
70
- expect(numberAbbr(999999, ['', 'K', 'M'])).toBe('999K');
71
- });
72
- });
73
-
74
- describe('numberFixed', () => {
75
- it('应正确执行四舍五入', () => {
76
- // biome-ignore lint/suspicious/noApproximativeNumericConstant: <explanation>
77
- expect(numberFixed(3.1415, { precision: 2 })).toBe(3.14);
78
- expect(numberFixed(3.145, { precision: 2 })).toBe(3.15);
79
- expect(numberFixed(3.5)).toBe(4);
80
- });
81
-
82
- it('应正确执行向上取整', () => {
83
- expect(numberFixed(3.1, { round: 1 })).toBe(4);
84
- expect(numberFixed(-3.1, { round: 1 })).toBe(-3);
85
- });
86
-
87
- it('应正确执行向下取整', () => {
88
- expect(numberFixed(3.9, { round: -1 })).toBe(3);
89
- expect(numberFixed(-3.9, { round: -1 })).toBe(-4);
90
- });
91
-
92
- it('应处理负数和小数位', () => {
93
- // biome-ignore lint/suspicious/noApproximativeNumericConstant: <explanation>
94
- expect(numberFixed(-3.1415, { precision: 3 })).toBe(-3.141);
95
- expect(numberFixed(-3.149, { precision: 2, round: -1 })).toBe(-3.15);
96
- });
97
-
98
- it('应支持默认参数', () => {
99
- expect(numberFixed(2.5)).toBe(3);
100
- expect(numberFixed(2.5, {})).toBe(3);
101
- });
102
-
103
- it('应处理精度为0的情况', () => {
104
- expect(numberFixed(99.9, { precision: 0 })).toBe(100);
105
- expect(numberFixed(99.4, { precision: 0, round: -1 })).toBe(99);
106
- });
107
- });
108
-
109
- describe('fileSizeAbbr', () => {
110
- it('应正确转换基础文件大小', () => {
111
- expect(fileSizeAbbr(1024)).toBe('1KB');
112
- expect(fileSizeAbbr(1048576)).toBe('1MB');
113
- expect(fileSizeAbbr(500)).toBe('500B');
114
- expect(fileSizeAbbr(1073741824)).toBe('1GB');
115
- });
116
-
117
- it('应处理自定义小数位', () => {
118
- expect(fileSizeAbbr(123456, 1)).toBe('120.5KB');
119
- expect(fileSizeAbbr(1050000, 2)).toBe('1MB');
120
- });
121
-
122
- it('应处理不足基数的情况', () => {
123
- expect(fileSizeAbbr(999)).toBe('999B');
124
- expect(fileSizeAbbr(1023)).toBe('1023B');
125
- });
126
-
127
- it('应处理大单位转换', () => {
128
- expect(fileSizeAbbr(1099511627776)).toBe('1TB');
129
- expect(fileSizeAbbr(2199023255552)).toBe('2TB');
130
- });
131
-
132
- it('应处理零值', () => {
133
- expect(fileSizeAbbr(0)).toBe('0B');
134
- });
135
-
136
- it('应处理边界情况', () => {
137
- expect(fileSizeAbbr(1024 * 1024 - 1)).toBe('1023KB');
138
- expect(fileSizeAbbr(1024 ** 3)).toBe('1GB');
139
- });
140
- });
141
-
142
- describe('numberConvert', () => {
143
- it('应正确将十进制数转换为默认 62 进制字符串', () => {
144
- expect(numberConvert(123456789)).toBe('8M0kX');
145
- });
146
-
147
- it('应正确将十进制数转换为自定义 16 进制字符串', () => {
148
- expect(numberConvert(255, '0123456789ABCDEF')).toBe('FF');
149
- });
150
-
151
- it('应正确处理大整数', () => {
152
- expect(numberConvert(9007199254740991n)).toBe('fFgnDxSe7');
153
- });
154
-
155
- it('应处理字符字典长度小于 2 的情况', () => {
156
- expect(() => numberConvert(123, 'A')).toThrow('进制转换字典长度不能小于 2');
157
- });
158
-
159
- it('应处理字符字典为空的情况', () => {
160
- expect(() => numberConvert(123, 'a')).toThrow('进制转换字典长度不能小于 2');
161
- });
162
-
163
- it('应处理负数', () => {
164
- expect(numberConvert(-123)).toBe('-1z');
165
- });
166
-
167
- it('应处理零', () => {
168
- expect(numberConvert(0)).toBe('0');
169
- });
170
- });
171
-
172
- describe('numberFormat', () => {
173
- it('应支持默认分隔符和步长', () => {
174
- expect(numberFormat(123456.789)).toBe('123,456.789');
175
- expect(numberFormat(1000)).toBe('1,000');
176
- expect(numberFormat(0)).toBe('0');
177
- expect(numberFormat(-123456)).toBe('-123,456');
178
- });
179
-
180
- it('应支持自定义分隔符', () => {
181
- expect(numberFormat(123456, '_')).toBe('123_456');
182
- expect(numberFormat(123456.789, '_')).toBe('123_456.789');
183
- });
184
-
185
- it('应支持自定义步长', () => {
186
- expect(numberFormat(123456, 2)).toBe('12,34,56');
187
- expect(numberFormat(123456.789, 2)).toBe('12,34,56.789');
188
- expect(numberFormat(100000, 3)).toBe('100,000');
189
- });
190
-
191
- it('应支持对象配置', () => {
192
- expect(numberFormat(123456, { separator: '.', step: 4 })).toBe('12.3456');
193
- expect(numberFormat(123456.789, { separator: ' ', step: 3 })).toBe('123 456.789');
194
- });
195
-
196
- it('应处理小数部分', () => {
197
- expect(numberFormat(1234.5678)).toBe('1,234.5678');
198
- expect(numberFormat(0.1234)).toBe('0.1234');
199
- expect(numberFormat(123456.789, { step: 3 })).toBe('123,456.789');
200
- });
201
-
202
- it('应处理特殊数值', () => {
203
- expect(numberFormat(999)).toBe('999');
204
- expect(numberFormat(1000)).toBe('1,000');
205
- expect(numberFormat(1000000)).toBe('1,000,000');
206
- expect(numberFormat(-123456.789)).toBe('-123,456.789');
207
- });
208
-
209
- it('应处理非整数步长参数', () => {
210
- expect(numberFormat(123456, 4)).toBe('12,3456');
211
- expect(numberFormat(123456, { step: 4 })).toBe('12,3456');
212
- });
213
- });
@@ -1,309 +0,0 @@
1
- import {
2
- isEmptyObject,
3
- isPlainObject,
4
- objectDefaults,
5
- objectEach,
6
- objectEachAsync,
7
- objectGet,
8
- objectMap,
9
- objectMerge,
10
- objectOmit,
11
- objectPick,
12
- objectSet,
13
- } from '@/object';
14
- import type { DeepPartial } from '@/types';
15
- import { describe, expect, it } from 'vitest';
16
-
17
- describe('objectEach', () => {
18
- it('应正确遍历对象的每个键值对', () => {
19
- const obj = { a: 1, b: 2, c: 3 };
20
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
21
- const results: any[] = [];
22
- objectEach(obj, (val, key) => {
23
- results.push([key, val]);
24
- });
25
- expect(results).toEqual([
26
- ['a', 1],
27
- ['b', 2],
28
- ['c', 3],
29
- ]);
30
- });
31
-
32
- it('应支持提前终止遍历', () => {
33
- const obj = { a: 1, b: 2, c: 3 };
34
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
35
- const results: any[] = [];
36
- objectEach(obj, (val, key) => {
37
- results.push([key, val]);
38
- if (key === 'b') {
39
- return false;
40
- }
41
- });
42
- expect(results).toEqual([
43
- ['a', 1],
44
- ['b', 2],
45
- ]);
46
- });
47
- });
48
-
49
- describe('objectEachAsync', () => {
50
- it('应正确异步遍历对象的每个键值对', async () => {
51
- const obj = { a: 1, b: 2, c: 3 };
52
- const results: [string, number][] = [];
53
- await objectEachAsync(obj, async (val, key) => {
54
- results.push([key, val]);
55
- });
56
- expect(results).toEqual([
57
- ['a', 1],
58
- ['b', 2],
59
- ['c', 3],
60
- ]);
61
- });
62
-
63
- it('应支持提前终止异步遍历', async () => {
64
- const obj = { a: 1, b: 2, c: 3 };
65
- const results: [string, number][] = [];
66
- await objectEachAsync(obj, async (val, key) => {
67
- results.push([key, val]);
68
- if (key === 'b') {
69
- return false;
70
- }
71
- });
72
- expect(results).toEqual([
73
- ['a', 1],
74
- ['b', 2],
75
- ]);
76
- });
77
- });
78
-
79
- describe('objectMerge', () => {
80
- it('应正确合并两个对象', () => {
81
- const obj1 = { a: 1, b: { x: 10 } };
82
- const obj2 = { b: { y: 20 }, c: 3 };
83
- const merged = objectMerge(obj1, obj2);
84
- expect(merged).toEqual({ a: 1, b: { x: 10, y: 20 }, c: 3 });
85
- });
86
-
87
- it('应正确处理循环引用', () => {
88
- const obj1 = { a: 1 };
89
- const obj2 = { c: obj1 };
90
- // { a: 1, b: <{b: obj1}> }
91
- // @ts-expect-error
92
- obj1.b = obj2;
93
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
94
- const merged = objectMerge({}, obj1) as any;
95
- expect(merged.a).toBe(1);
96
- expect(merged.b.c).toBe(merged);
97
- });
98
-
99
- it('应正确合并多个对象', () => {
100
- const obj1 = { a: 1 };
101
- const obj2 = { b: 2 };
102
- const obj3 = { c: 3 };
103
- const merged = objectMerge(obj1, obj2, obj3);
104
- expect(merged).toEqual({ a: 1, b: 2, c: 3 });
105
- });
106
-
107
- it('应正确合并数组', () => {
108
- const obj1 = { a: [1, 2, 3] };
109
- const obj2 = { a: [3, 4] };
110
- const merged = objectMerge(obj1, obj2);
111
- expect(merged).toEqual({ a: [3, 4, 3] });
112
- });
113
-
114
- it('不同类型的值应被覆盖,返回数组', () => {
115
- const obj1 = { a: 1 };
116
- const obj2 = [1];
117
- const merged = objectMerge(obj1, obj2);
118
- expect(merged).toEqual([1]);
119
- });
120
-
121
- it('不同类型的值应被覆盖,返回对象', () => {
122
- const obj1 = { a: 1 };
123
- const obj2 = [1];
124
- const merged = objectMerge(obj2, obj1);
125
- expect(merged).toEqual({ a: 1 });
126
- });
127
- });
128
-
129
- // 新增 objectDefaults 单测
130
- describe('objectDefaults', () => {
131
- it('应正确设置默认值', () => {
132
- type Obj = {
133
- a: number;
134
- b: number;
135
- c: number;
136
- };
137
- const obj: Partial<Obj> = { a: 1, b: undefined };
138
- const defaults = { a: 4, b: 2, c: 3 };
139
- const result = objectDefaults(obj, defaults);
140
- expect(result).toEqual({ a: 1, b: 2, c: 3 });
141
- });
142
-
143
- it('应支持多个默认对象', () => {
144
- type Obj = {
145
- a: number;
146
- b: number;
147
- c: number;
148
- };
149
- const obj: Partial<Obj> = { a: 1, b: undefined };
150
- const defaults1 = { a: 4, b: 2, c: 3 };
151
- const result = objectDefaults(obj, defaults1);
152
- expect(result).toEqual({ a: 1, b: 2, c: 3 });
153
- });
154
-
155
- it('不应覆盖已定义的值', () => {
156
- const obj = { a: 1, b: 2 };
157
- const defaults = { a: 5, b: 3, c: 4 };
158
- const result = objectDefaults(obj, defaults);
159
- expect(result).toEqual({ a: 1, b: 2, c: 4 });
160
- });
161
-
162
- it('应处理嵌套对象', () => {
163
- type Obj = {
164
- a: { x: number; y: number; z: number };
165
- b: { y: number };
166
- };
167
- const obj: DeepPartial<Obj> = { a: { x: 1 }, b: undefined };
168
- const defaults = { a: { x: 4, z: 3 }, b: { y: 2 } };
169
- const result = objectDefaults(obj, defaults);
170
- expect(result).toEqual({ a: { x: 1, z: 3 }, b: { y: 2 } });
171
- });
172
- });
173
-
174
- describe('objectPick', () => {
175
- it('应正确选择指定键的对象', () => {
176
- const obj = { a: 1, b: 2, c: 3 };
177
- const result = objectPick(obj, ['a', 'c']);
178
- expect(result).toEqual({ a: 1, c: 3 });
179
- });
180
-
181
- it('应忽略不存在的键', () => {
182
- const obj = { a: 1, b: 2, c: 3, d: 4 };
183
- const result = objectPick(obj, ['a', 'd']);
184
- expect(result).toEqual({ a: 1, d: 4 });
185
- });
186
-
187
- it('应返回空对象如果键数组为空', () => {
188
- const obj = { a: 1, b: 2, c: 3 };
189
- const result = objectPick(obj, []);
190
- expect(result).toEqual({});
191
- });
192
- });
193
-
194
- describe('objectOmit', () => {
195
- it('应正确排除指定键的对象', () => {
196
- const obj = { a: 1, b: 2, c: 3 };
197
- const result = objectOmit(obj, ['a', 'c']);
198
- expect(result).toEqual({ b: 2 });
199
- });
200
-
201
- it('应忽略不存在的键', () => {
202
- const obj = { a: 1, b: 2, c: 3, d: 4 };
203
- const result = objectOmit(obj, ['a', 'd']);
204
- expect(result).toEqual({ b: 2, c: 3 });
205
- });
206
-
207
- it('应返回原对象如果键数组为空', () => {
208
- const obj = { a: 1, b: 2, c: 3 };
209
- const result = objectOmit(obj, []);
210
- expect(result).toEqual({ a: 1, b: 2, c: 3 });
211
- });
212
- });
213
-
214
- describe('objectMap', () => {
215
- it('应正确映射对象的每个键值对', () => {
216
- const obj = { a: 1, b: 2, c: 3 };
217
- const result = objectMap(obj, (val, key) => val * 2);
218
- expect(result).toEqual({ a: 2, b: 4, c: 6 });
219
- });
220
-
221
- it('应支持将值映射为不同类型的值', () => {
222
- const obj = { a: 1, b: 2, c: 3 };
223
- const result = objectMap(obj, (val, key) => String(val * 2));
224
- expect(result).toEqual({ a: '2', b: '4', c: '6' });
225
- });
226
-
227
- it('应返回空对象如果输入对象为空', () => {
228
- const obj = {};
229
- const result = objectMap(obj, (val, key) => val);
230
- expect(result).toEqual({});
231
- });
232
- });
233
-
234
- describe('objectGet', () => {
235
- it('应正确获取嵌套属性值(字符串路径)', () => {
236
- const obj = { a: { b: { c: 42 } } };
237
- const result = objectGet(obj, 'a.b.c');
238
- expect(result.value).toBe(42);
239
- });
240
-
241
- it('应正确获取嵌套属性值(数组路径)', () => {
242
- const obj = { a: { b: { c: 42 } } };
243
- const result = objectGet(obj, ['a', 'b', 'c']);
244
- expect(result.value).toBe(42);
245
- });
246
-
247
- it('应返回 undefined 如果路径不存在', () => {
248
- const obj = { a: { b: { c: 42 } } };
249
- const result = objectGet(obj, 'a.b.x');
250
- expect(result.value).toBeUndefined();
251
- });
252
- });
253
-
254
- describe('objectSet', () => {
255
- it('应正确设置嵌套属性值', () => {
256
- const obj = { a: { b: { c: 42 } } };
257
- objectSet(obj, 'a.b.c', 100);
258
- expect(obj.a.b.c).toBe(100);
259
- });
260
-
261
- it('应正确创建未定义的中间节点', () => {
262
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
263
- const obj: Record<string, any> = {};
264
- objectSet(obj, 'a.b.c', 42);
265
- expect(obj.a.b.c).toBe(42);
266
- });
267
-
268
- it('应在 beforeSet 返回 false 时阻止设置值', () => {
269
- const obj = { a: { b: { c: 42 } } };
270
- objectSet(obj, 'a.b.c', 100, {
271
- beforeSet: () => false,
272
- });
273
- expect(obj.a.b.c).toBe(42);
274
- });
275
-
276
- it('应在 undefinedSet 返回自定义值时使用该值', () => {
277
- // biome-ignore lint/suspicious/noExplicitAny: <explanation>
278
- const obj: Record<string, any> = {};
279
- objectSet(obj, 'a.b.c', 42, {
280
- undefinedSet: () => ({ custom: 'value' }),
281
- });
282
- expect(obj.a.b).toEqual({ custom: 'value', c: 42 });
283
- });
284
- });
285
-
286
- describe('isEmptyObject', () => {
287
- it('应该正确识别空对象', () => {
288
- expect(isEmptyObject({})).toBe(true);
289
- expect(isEmptyObject(Object.create(null))).toBe(true);
290
- });
291
-
292
- it('应该识别非空对象', () => {
293
- expect(isEmptyObject({ a: 1 })).toBe(false);
294
- expect(isEmptyObject({ [Symbol('key')]: 'value' })).toBe(false);
295
- });
296
- });
297
-
298
- describe('isPlainObject', () => {
299
- it('应识别普通对象', () => {
300
- expect(isPlainObject({})).toBe(true);
301
- expect(isPlainObject(Object.create(null))).toBe(true);
302
- });
303
-
304
- it('应排除非纯对象', () => {
305
- const o = {};
306
- Object.setPrototypeOf(o, { aa: 1 });
307
- expect(isPlainObject(o)).toBe(false);
308
- });
309
- });
package/test/path.test.ts DELETED
@@ -1,156 +0,0 @@
1
- import path from 'node:path/posix';
2
- import { isAbsolutePath, isRelativePath, pathJoin, pathNormalize, pathRelativize, pathResolve } from '@/path';
3
- import { describe, expect, it } from 'vitest';
4
-
5
- function testNormalize(value: string) {
6
- expect(pathNormalize(value)).toBe(path.normalize(value));
7
- }
8
-
9
- function testJoin(from: string, ...to: string[]) {
10
- expect(pathJoin.apply(pathJoin, [from, ...to])).toBe(path.join.apply(path, [from, ...to]));
11
- }
12
-
13
- describe('pathNormalize', () => {
14
- it('应正确标准化路径', () => {
15
- testNormalize('/path///to///file');
16
- testNormalize('path/to/file');
17
- testNormalize('/path/to/./file');
18
- testNormalize('/path/to/../file');
19
- testNormalize('/path/to/../../file');
20
- testNormalize('/path/to/../../../file');
21
- testNormalize('/path/to/../../../../file');
22
- testNormalize('/path/to/../../file/');
23
- testNormalize('/path/to/./file/');
24
- testNormalize('/path/to/./');
25
- testNormalize('/path/to/../');
26
- testNormalize('/path/to/../../');
27
- testNormalize('/path/to/../../../');
28
- testNormalize('/path/to/../../../../');
29
- testNormalize('/path/to/./././file');
30
- testNormalize('/path/to/.././file');
31
- testNormalize('/path/to/../.././file');
32
- testNormalize('/path/to/../../.././file');
33
- testNormalize('/path/to/../../../.././file');
34
- testNormalize('/path/to/./../file');
35
- testNormalize('/path/to/./../../file');
36
- testNormalize('/path/to/./../../../file');
37
- testNormalize('/path/to/./../../../../file');
38
- testNormalize('/path/to/././file');
39
- testNormalize('/path/to/../././file');
40
- testNormalize('/path/to/../../././file');
41
- testNormalize('/path/to/../../../././file');
42
- testNormalize('/path/to/../../../../././file');
43
- });
44
-
45
- it('应正确处理绝对路径和相对路径', () => {
46
- testNormalize('/path/to/file');
47
- testNormalize('path/to/file');
48
- testNormalize('/./path/to/file');
49
- testNormalize('./path/to/file');
50
- testNormalize('../path/to/file');
51
- testNormalize('/path/to/./file');
52
- testNormalize('path/to/./file');
53
- testNormalize('/path/to/../file');
54
- testNormalize('path/to/../file');
55
- testNormalize('/path/to/../../file');
56
- testNormalize('path/to/../../file');
57
- testNormalize('/path/to/../../../file');
58
- testNormalize('path/to/../../../file');
59
- testNormalize('/path/to/../../../../file');
60
- testNormalize('path/to/../../../../file');
61
- });
62
- });
63
-
64
- describe('pathJoin', () => {
65
- it('应正确合并路径', () => {
66
- testJoin('/path', 'to', 'file');
67
- testJoin('path', 'to', 'file');
68
- testJoin('/path', '/to', 'file');
69
- testJoin('path', '/to', 'file');
70
- testJoin('/path', 'to', '/file');
71
- testJoin('path', 'to', '/file');
72
- testJoin('/path', '/to', '/file');
73
- testJoin('path', '/to', '/file');
74
- testJoin('/path', 'to', 'file/');
75
- testJoin('path', 'to', 'file/');
76
- testJoin('/path', 'to/', 'file');
77
- testJoin('path', 'to/', 'file');
78
- testJoin('/path', 'to/', 'file/');
79
- testJoin('path', 'to/', 'file/');
80
- testJoin('/path', '/to', 'file/');
81
- testJoin('path', '/to', 'file/');
82
- testJoin('/path', '/to/', 'file');
83
- testJoin('path', '/to/', 'file');
84
- testJoin('/path', '/to/', 'file/');
85
- testJoin('path', '/to/', 'file/');
86
- testJoin('/path', 'to', '/file/');
87
- testJoin('path', 'to', '/file/');
88
- testJoin('/path', '/to', '/file/');
89
- testJoin('path', '/to', '/file/');
90
- });
91
- });
92
-
93
- describe('isAbsolutePath', () => {
94
- it('应正确判断绝对路径', () => {
95
- expect(isAbsolutePath('/path/to/file')).toBe(true);
96
- expect(isAbsolutePath('/')).toBe(true);
97
- expect(isAbsolutePath('/path/../to/file')).toBe(true);
98
- expect(isAbsolutePath('/path/./to/file')).toBe(true);
99
- });
100
-
101
- it('应正确判断非绝对路径', () => {
102
- expect(isAbsolutePath('path/to/file')).toBe(false);
103
- expect(isAbsolutePath('./path/to/file')).toBe(false);
104
- expect(isAbsolutePath('../path/to/file')).toBe(false);
105
- expect(isAbsolutePath('')).toBe(false);
106
- });
107
- });
108
-
109
- describe('isRelativePath', () => {
110
- it('应正确判断相对路径', () => {
111
- expect(isRelativePath('path/to/file')).toBe(true);
112
- expect(isRelativePath('./path/to/file')).toBe(true);
113
- expect(isRelativePath('../path/to/file')).toBe(true);
114
- expect(isRelativePath('')).toBe(true);
115
- });
116
-
117
- it('应正确判断非相对路径', () => {
118
- expect(isRelativePath('/path/to/file')).toBe(false);
119
- expect(isRelativePath('/')).toBe(false);
120
- expect(isRelativePath('/path/../to/file')).toBe(false);
121
- expect(isRelativePath('/path/./to/file')).toBe(false);
122
- });
123
- });
124
-
125
- describe('pathResolve', () => {
126
- it('应正确解析路径', () => {
127
- expect(pathResolve('/path', 'to', 'file')).toBe('/path/to/file');
128
- expect(pathResolve('/path', '/to', 'file')).toBe('/to/file');
129
- expect(pathResolve('/path', 'to', '/file')).toBe('/file');
130
- expect(pathResolve('path', 'to', 'file')).toBe('path/to/file');
131
- expect(pathResolve('path', '/to', 'file')).toBe('/to/file');
132
- expect(pathResolve('path', 'to', '/file')).toBe('/file');
133
- expect(pathResolve('/path', 'to/../file')).toBe('/path/file');
134
- expect(pathResolve('/path', 'to/./file')).toBe('/path/to/file');
135
- expect(pathResolve('/path', 'to/../../file')).toBe('/file');
136
- });
137
- });
138
-
139
- describe('pathRelativize', () => {
140
- it('应正确相对化路径', () => {
141
- // 绝对路径应保持不变
142
- expect(pathRelativize('/path/to/file')).toBe('/path/to/file');
143
- expect(pathRelativize('/')).toBe('/');
144
-
145
- // 已带'./'前缀的相对路径应保持不变
146
- expect(pathRelativize('./path/to/file')).toBe('./path/to/file');
147
- expect(pathRelativize('./')).toBe('./');
148
-
149
- // 不带'./'前缀的相对路径应添加'./'前缀
150
- expect(pathRelativize('path/to/file')).toBe('./path/to/file');
151
- expect(pathRelativize('file')).toBe('./file');
152
-
153
- // 带'../'前缀的相对路径应保持不变
154
- expect(pathRelativize('../path/to/file')).toBe('../path/to/file');
155
- });
156
- });