@cloudcome/utils-browser 1.1.1 → 1.1.2

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 (79) hide show
  1. package/dist/base64.cjs +15 -0
  2. package/dist/base64.cjs.map +1 -0
  3. package/dist/base64.d.ts +14 -0
  4. package/dist/base64.mjs +15 -0
  5. package/dist/base64.mjs.map +1 -0
  6. package/{src/cache.ts → dist/cache.cjs} +20 -48
  7. package/dist/cache.cjs.map +1 -0
  8. package/dist/cache.d.ts +49 -0
  9. package/dist/cache.mjs +87 -0
  10. package/dist/cache.mjs.map +1 -0
  11. package/dist/canvas.cjs +58 -0
  12. package/dist/canvas.cjs.map +1 -0
  13. package/dist/canvas.d.ts +92 -0
  14. package/dist/canvas.mjs +58 -0
  15. package/dist/canvas.mjs.map +1 -0
  16. package/dist/clipboard.cjs +16 -0
  17. package/dist/clipboard.cjs.map +1 -0
  18. package/{src/clipboard.ts → dist/clipboard.d.ts} +1 -12
  19. package/dist/clipboard.mjs +16 -0
  20. package/dist/clipboard.mjs.map +1 -0
  21. package/dist/cookie.cjs +50 -0
  22. package/dist/cookie.cjs.map +1 -0
  23. package/dist/cookie.d.ts +55 -0
  24. package/dist/cookie.mjs +50 -0
  25. package/dist/cookie.mjs.map +1 -0
  26. package/dist/dom.cjs +18 -0
  27. package/dist/dom.cjs.map +1 -0
  28. package/{src/dom.ts → dist/dom.d.ts} +3 -21
  29. package/dist/dom.mjs +18 -0
  30. package/dist/dom.mjs.map +1 -0
  31. package/dist/download.cjs +16 -0
  32. package/dist/download.cjs.map +1 -0
  33. package/dist/download.d.ts +12 -0
  34. package/dist/download.mjs +16 -0
  35. package/dist/download.mjs.map +1 -0
  36. package/dist/image.cjs +35 -0
  37. package/dist/image.cjs.map +1 -0
  38. package/dist/image.d.ts +9 -0
  39. package/dist/image.mjs +35 -0
  40. package/dist/image.mjs.map +1 -0
  41. package/dist/index.cjs +5 -0
  42. package/dist/index.cjs.map +1 -0
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.mjs +5 -0
  45. package/dist/index.mjs.map +1 -0
  46. package/dist/timer.cjs +41 -0
  47. package/dist/timer.cjs.map +1 -0
  48. package/dist/timer.d.ts +9 -0
  49. package/dist/timer.mjs +41 -0
  50. package/dist/timer.mjs.map +1 -0
  51. package/dist/video.cjs +14 -0
  52. package/dist/video.cjs.map +1 -0
  53. package/dist/video.d.ts +9 -0
  54. package/dist/video.mjs +14 -0
  55. package/dist/video.mjs.map +1 -0
  56. package/package.json +9 -3
  57. package/CHANGELOG.md +0 -27
  58. package/src/base64.ts +0 -25
  59. package/src/canvas.ts +0 -147
  60. package/src/cookie.ts +0 -118
  61. package/src/download.ts +0 -22
  62. package/src/dts/global.d.ts +0 -27
  63. package/src/image.ts +0 -45
  64. package/src/index.ts +0 -1
  65. package/src/timer.ts +0 -56
  66. package/src/video.ts +0 -19
  67. package/test/base64.test.ts +0 -47
  68. package/test/cache.test.ts +0 -199
  69. package/test/canvas.test.ts +0 -124
  70. package/test/clipboard.test.ts +0 -18
  71. package/test/cookie.test.ts +0 -52
  72. package/test/dom.test.ts +0 -67
  73. package/test/download.test.ts +0 -15
  74. package/test/image.test.ts +0 -75
  75. package/test/index.test.ts +0 -6
  76. package/test/timer.test.ts +0 -109
  77. package/test/video.test.ts +0 -36
  78. package/tsconfig.json +0 -31
  79. package/vite.config.mts +0 -100
@@ -1,199 +0,0 @@
1
- import { type Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { StorageCache, createLocalCache, createSessionCache } from '../src/cache';
3
-
4
- describe('StorageCache', () => {
5
- let storage: Storage;
6
- let cache: StorageCache<string>;
7
-
8
- beforeEach(() => {
9
- storage = {
10
- getItem: vi.fn(),
11
- setItem: vi.fn(),
12
- removeItem: vi.fn(),
13
- clear: vi.fn(),
14
- length: 0,
15
- key: vi.fn(),
16
- } as unknown as Storage;
17
- cache = new StorageCache(storage);
18
- });
19
-
20
- afterEach(() => {
21
- vi.clearAllMocks();
22
- });
23
-
24
- describe('constructor', () => {
25
- it('应该正确初始化实例', () => {
26
- expect(cache).toBeInstanceOf(StorageCache);
27
- expect(cache.storage).toBe(storage);
28
- expect(cache.namespace).toBe('');
29
- });
30
-
31
- it('应该支持命名空间', () => {
32
- const cacheWithNamespace = new StorageCache(storage, 'test');
33
- expect(cacheWithNamespace.namespace).toBe('test');
34
- });
35
- });
36
-
37
- describe('get()', () => {
38
- it('应该返回null当缓存不存在时', () => {
39
- (storage.getItem as Mock).mockReturnValue(null);
40
- expect(cache.get('key')).toBeNull();
41
- expect(storage.getItem).toBeCalledWith('key');
42
- });
43
-
44
- it('应该返回null当缓存过期时', () => {
45
- const expiredCache = JSON.stringify({
46
- id: 'key',
47
- data: 'value',
48
- createdAt: Date.now() - 10000,
49
- maxAge: 5000,
50
- });
51
- (storage.getItem as Mock).mockReturnValue(expiredCache);
52
- expect(cache.get('key')).toBeNull();
53
- expect(storage.removeItem).toBeCalledWith('key');
54
- });
55
-
56
- it('应该返回缓存数据当缓存有效时', () => {
57
- const validCache = JSON.stringify({
58
- id: 'key',
59
- data: 'value',
60
- createdAt: Date.now(),
61
- maxAge: 5000,
62
- });
63
- (storage.getItem as Mock).mockReturnValue(validCache);
64
- const result = cache.get('key');
65
- expect(result?.data).toBe('value');
66
- });
67
-
68
- it('应该返回null当缓存数据解析失败时', () => {
69
- (storage.getItem as Mock).mockReturnValue('invalid json');
70
- expect(cache.get('key')).toBeNull();
71
- });
72
- });
73
-
74
- describe('set()', () => {
75
- it('应该成功设置缓存', () => {
76
- cache.set('key', 'value');
77
- expect(storage.setItem).toBeCalled();
78
- });
79
-
80
- it('应该支持设置缓存过期时间', () => {
81
- cache.set('key', 'value', { maxAge: 1000 });
82
- const [, value] = (storage.setItem as Mock).mock.calls[0];
83
- const cacheData = JSON.parse(value);
84
- expect(cacheData.maxAge).toBe(1000);
85
- });
86
- });
87
-
88
- describe('del()', () => {
89
- it('应该成功删除缓存', () => {
90
- cache.del('key');
91
- expect(storage.removeItem).toBeCalledWith('key');
92
- });
93
-
94
- it('应该处理删除缓存失败的情况', () => {
95
- (storage.removeItem as Mock).mockImplementation(() => {
96
- throw new Error('Remove failed');
97
- });
98
- expect(() => cache.del('key')).not.toThrow();
99
- });
100
- });
101
-
102
- describe('命名空间', () => {
103
- it('应该在键前添加命名空间', () => {
104
- const cacheWithNamespace = new StorageCache(storage, 'test');
105
- cacheWithNamespace.set('key', 'value');
106
- expect(storage.setItem).toBeCalledWith('test:key', expect.anything());
107
- });
108
-
109
- it('应该在获取缓存时使用命名空间', () => {
110
- const cacheWithNamespace = new StorageCache(storage, 'test');
111
- cacheWithNamespace.get('key');
112
- expect(storage.getItem).toBeCalledWith('test:key');
113
- });
114
-
115
- it('应该在删除缓存时使用命名空间', () => {
116
- const cacheWithNamespace = new StorageCache(storage, 'test');
117
- cacheWithNamespace.del('key');
118
- expect(storage.removeItem).toBeCalledWith('test:key');
119
- });
120
- });
121
-
122
- describe('clear()', () => {
123
- it('应该清空所有缓存', () => {
124
- cache.clear();
125
- expect(storage.clear).toBeCalled();
126
- });
127
-
128
- it('应该处理清空缓存失败的情况', () => {
129
- (storage.clear as Mock).mockImplementation(() => {
130
- throw new Error('Clear failed');
131
- });
132
- expect(() => cache.clear()).not.toThrow();
133
- });
134
- });
135
-
136
- describe('缓存数据格式', () => {
137
- it('应该正确序列化缓存数据', () => {
138
- cache.set('key', 'value');
139
- const [, value] = (storage.setItem as Mock).mock.calls[0];
140
- const cacheData = JSON.parse(value);
141
- expect(cacheData).toEqual({
142
- id: 'key',
143
- data: 'value',
144
- createdAt: expect.any(Number),
145
- maxAge: 0,
146
- });
147
- });
148
-
149
- it('应该正确处理非字符串数据', () => {
150
- const objCache = new StorageCache<object>(storage);
151
- objCache.set('key', { foo: 'bar' });
152
- const [, value] = (storage.setItem as Mock).mock.calls[0];
153
- const cacheData = JSON.parse(value);
154
- expect(cacheData.data).toEqual({ foo: 'bar' });
155
- });
156
- });
157
-
158
- describe('存储失败', () => {
159
- it('应该处理getItem失败的情况', () => {
160
- (storage.getItem as Mock).mockImplementation(() => {
161
- throw new Error('Get failed');
162
- });
163
- expect(() => cache.get('key')).not.toThrow();
164
- });
165
-
166
- it('应该处理setItem失败的情况', () => {
167
- (storage.setItem as Mock).mockImplementation(() => {
168
- throw new Error('Set failed');
169
- });
170
- expect(() => cache.set('key', 'value')).not.toThrow();
171
- });
172
- });
173
- });
174
-
175
- describe('createLocalCache', () => {
176
- it('应该创建使用localStorage的缓存实例', () => {
177
- const cache = createLocalCache<string>() as StorageCache<string>;
178
- expect(cache).toBeInstanceOf(StorageCache);
179
- expect(cache.storage).toBe(localStorage);
180
- });
181
-
182
- it('应该支持命名空间', () => {
183
- const cache = createLocalCache<string>('test') as StorageCache<string>;
184
- expect(cache.namespace).toBe('test');
185
- });
186
- });
187
-
188
- describe('createSessionCache', () => {
189
- it('应该创建使用sessionStorage的缓存实例', () => {
190
- const cache = createSessionCache<string>() as StorageCache<string>;
191
- expect(cache).toBeInstanceOf(StorageCache);
192
- expect(cache.storage).toBe(sessionStorage);
193
- });
194
-
195
- it('应该支持命名空间', () => {
196
- const cache = createSessionCache<string>('test') as StorageCache<string>;
197
- expect(cache.namespace).toBe('test');
198
- });
199
- });
@@ -1,124 +0,0 @@
1
- import { canvasDrawImage, canvasToBase64, canvasToBlob } from '@/canvas';
2
- import { imageLoad } from '@/image';
3
- import { loadImage } from 'canvas';
4
- import { describe, expect, it, vi } from 'vitest';
5
-
6
- describe('canvasToBase64', () => {
7
- it('应返回默认 png 格式的 base64 字符串', () => {
8
- const canvas = document.createElement('canvas');
9
- canvas.width = 100;
10
- canvas.height = 100;
11
-
12
- const result = canvasToBase64(canvas);
13
- expect(result).toMatch(/^data:image\/png;base64,/);
14
- });
15
-
16
- it('应返回指定格式和质量的 base64 字符串', () => {
17
- const canvas = document.createElement('canvas');
18
- canvas.width = 100;
19
- canvas.height = 100;
20
-
21
- const result = canvasToBase64(canvas, 'image/jpeg', 0.8);
22
- expect(result).toMatch(/^data:image\/jpeg;base64,/);
23
- });
24
- });
25
-
26
- describe('canvasToBlob', () => {
27
- it('应返回默认 png 格式的 Blob 对象', async () => {
28
- const canvas = document.createElement('canvas');
29
- canvas.width = 100;
30
- canvas.height = 100;
31
-
32
- const blob = await canvasToBlob(canvas);
33
- expect(blob).toBeInstanceOf(Blob);
34
- expect(blob.type).toBe('image/png');
35
- });
36
-
37
- it('应返回指定格式和质量的 Blob 对象', async () => {
38
- const canvas = document.createElement('canvas');
39
- canvas.width = 100;
40
- canvas.height = 100;
41
-
42
- const blob = await canvasToBlob(canvas, 'image/jpeg', 0.9);
43
- expect(blob).toBeInstanceOf(Blob);
44
- expect(blob.type).toBe('image/jpeg');
45
- });
46
-
47
- it('当 canvas toBlob 失败时应拒绝', async () => {
48
- const canvas = document.createElement('canvas');
49
- vi.spyOn(canvas, 'toBlob').mockImplementationOnce((callback) => callback(null));
50
-
51
- await expect(canvasToBlob(canvas)).rejects.toThrow('canvas 导出二进制对象失败');
52
- });
53
- });
54
-
55
- describe('canvasDrawImage', () => {
56
- it(
57
- '应使用默认选项绘制图像',
58
- async () => {
59
- const canvas = document.createElement('canvas');
60
- canvas.width = 200;
61
- canvas.height = 200;
62
- const ctx = canvas.getContext('2d');
63
- if (!ctx) throw new Error('Canvas context is null');
64
-
65
- const spy = vi.spyOn(ctx, 'drawImage').mockImplementation(() => true);
66
- const src = 'https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png';
67
- const img = await imageLoad(src);
68
-
69
- await canvasDrawImage(canvas, img.src);
70
- expect(spy).toHaveBeenCalledWith(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
71
- },
72
- { timeout: 0 },
73
- );
74
-
75
- it(
76
- '应使用自定义选项绘制图像',
77
- async () => {
78
- const canvas = document.createElement('canvas');
79
- canvas.width = 200;
80
- canvas.height = 200;
81
- const ctx = canvas.getContext('2d');
82
- if (!ctx) throw new Error('Canvas context is null');
83
-
84
- const spy = vi.spyOn(ctx, 'drawImage').mockImplementation(() => true);
85
- const src = 'https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png';
86
- const img = await imageLoad(src);
87
-
88
- const options = {
89
- srcLeft: 10,
90
- srcTop: 10,
91
- srcWidth: 50,
92
- srcHeight: 50,
93
- destLeft: 20,
94
- destTop: 20,
95
- destWidth: 100,
96
- destHeight: 100,
97
- };
98
- await canvasDrawImage(canvas, img.src, options);
99
- expect(spy).toHaveBeenCalledWith(
100
- img,
101
- options.srcLeft,
102
- options.srcTop,
103
- options.srcWidth,
104
- options.srcHeight,
105
- options.destLeft,
106
- options.destTop,
107
- options.destWidth,
108
- options.destHeight,
109
- );
110
- },
111
- { timeout: 0 },
112
- );
113
-
114
- it(
115
- '当 canvas context 为 null 时应抛出错误',
116
- async () => {
117
- const canvas = document.createElement('canvas');
118
- vi.spyOn(canvas, 'getContext').mockReturnValueOnce(null);
119
-
120
- await expect(canvasDrawImage(canvas, 'https://example.com/image.png')).rejects.toThrow('canvas context is null');
121
- },
122
- { timeout: 0 },
123
- );
124
- });
@@ -1,18 +0,0 @@
1
- import { copyText } from '@/clipboard';
2
- import { beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- describe('copyText', () => {
5
- beforeEach(() => {
6
- vi.resetAllMocks();
7
- document.body.innerHTML = '';
8
- });
9
-
10
- it('应在复制后移除 textarea 元素', () => {
11
- const execCommandMock = vi.fn();
12
- document.execCommand = execCommandMock;
13
-
14
- copyText('test text');
15
-
16
- expect(document.body.querySelector('textarea')).toBeNull();
17
- });
18
- });
@@ -1,52 +0,0 @@
1
- import { cookieDel, cookieGet, cookieSet } from '@/cookie';
2
- import { beforeEach, describe, expect, it } from 'vitest';
3
-
4
- describe('Cookie 工具函数', () => {
5
- beforeEach(() => {
6
- // 清空所有 Cookie
7
- for (const cookie of document.cookie.split(';')) {
8
- const eqPos = cookie.indexOf('=');
9
- const name = eqPos > -1 ? cookie.slice(0, eqPos) : cookie;
10
- document.cookie = `${name}=;expires=Thu, 01 Jan 1970 00:00:00 GMT`;
11
- }
12
- });
13
-
14
- describe('cookieGet', () => {
15
- it('应返回已存在 cookie 的值', () => {
16
- document.cookie = 'testKey=testValue';
17
- expect(cookieGet('testKey')).toBe('testValue');
18
- });
19
-
20
- it('对于不存在的 cookie 应返回空字符串', () => {
21
- expect(cookieGet('nonExistingKey')).toBe('');
22
- });
23
- });
24
-
25
- describe('cookieSet', () => {
26
- it('应使用默认选项设置 cookie', () => {
27
- cookieSet('defaultKey', 'defaultValue');
28
- expect(document.cookie).toContain('defaultKey=defaultValue');
29
- });
30
-
31
- it('应使用自定义选项设置 cookie', () => {
32
- cookieSet('customKey', 'customValue', {
33
- expires: new Date('2030-01-01'),
34
- path: '/',
35
- domain: location.host,
36
- secure: true,
37
- sameSite: 'none',
38
- httpOnly: false,
39
- maxAge: 3600,
40
- });
41
- expect(document.cookie).toEqual('');
42
- });
43
- });
44
-
45
- describe('cookieDel', () => {
46
- it('应通过设置过期时间为过去来删除 cookie', () => {
47
- document.cookie = 'deleteKey=deleteValue';
48
- cookieDel('deleteKey');
49
- expect(document.cookie).not.toContain('deleteKey=deleteValue');
50
- });
51
- });
52
- });
package/test/dom.test.ts DELETED
@@ -1,67 +0,0 @@
1
- import { getStyle, setStyle } from '@/dom';
2
- import { describe, expect, it, vi } from 'vitest';
3
-
4
- describe('setStyle', () => {
5
- it('应该能够通过字符串设置样式', () => {
6
- const el = document.createElement('div');
7
- setStyle(el, 'color: red; background: blue;');
8
-
9
- expect(el.style.color).toBe('red');
10
- expect(el.style.background).toBe('blue');
11
- });
12
-
13
- it('应该能够通过对象设置样式', () => {
14
- const el = document.createElement('div');
15
- setStyle(el, { color: 'red', width: '16px' });
16
-
17
- expect(el.style.color).toBe('red');
18
- expect(el.style.width).toBe('16px');
19
- });
20
-
21
- it('应该能够设置自定义属性', () => {
22
- const el = document.createElement('div');
23
- setStyle(el, { '--custom-property': 'value' });
24
-
25
- expect(el.style.getPropertyValue('--custom-property')).toBe('value');
26
- });
27
-
28
- it('使用字符串设置样式时应覆盖现有样式', () => {
29
- const el = document.createElement('div');
30
- el.style.color = 'green';
31
- setStyle(el, 'color: red;');
32
-
33
- expect(el.style.color).toBe('red');
34
- });
35
-
36
- it('使用对象设置样式时应合并样式', () => {
37
- const el = document.createElement('div');
38
- el.style.color = 'green';
39
- setStyle(el, { width: '100px' });
40
-
41
- expect(el.style.color).toBe('green');
42
- expect(el.style.width).toBe('100px');
43
- });
44
- });
45
-
46
- describe('getStyle', () => {
47
- it('应该能够获取计算样式', () => {
48
- const el = document.createElement('div');
49
- el.style.color = 'red';
50
-
51
- vi.spyOn(window, 'getComputedStyle').mockReturnValue({
52
- getPropertyValue: (prop: string) => (prop === 'color' ? 'red' : ''),
53
- } as CSSStyleDeclaration);
54
-
55
- expect(getStyle(el, 'color')).toBe('red');
56
- });
57
-
58
- it('对于不存在的属性应返回空字符串', () => {
59
- const el = document.createElement('div');
60
-
61
- const mockStyle = new CSSStyleDeclaration();
62
- vi.spyOn(mockStyle, 'getPropertyValue').mockReturnValue('');
63
- vi.spyOn(window, 'getComputedStyle').mockReturnValue(mockStyle);
64
-
65
- expect(getStyle(el, 'color')).toBe('');
66
- });
67
- });
@@ -1,15 +0,0 @@
1
- import { downloadBlob, downloadURL } from '@/download';
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- it('download', () => {
5
- downloadURL('/');
6
- downloadURL('/', 'file');
7
-
8
- URL.createObjectURL = vi.fn(() => '/');
9
- URL.revokeObjectURL = vi.fn();
10
-
11
- downloadBlob(new Blob());
12
- downloadBlob(new Blob(), 'file');
13
-
14
- expect(URL.createObjectURL).toBeTypeOf('function');
15
- });
@@ -1,75 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { imageLoad } from '../src/image';
3
-
4
- describe('图片工具函数', () => {
5
- beforeEach(() => {
6
- vi.restoreAllMocks();
7
- });
8
-
9
- it('应该能够成功加载图片', async () => {
10
- const mockImage = new Image();
11
- vi.spyOn(window, 'Image').mockReturnValue(mockImage);
12
- vi.spyOn(document.body, 'appendChild');
13
- vi.spyOn(document.body, 'removeChild');
14
-
15
- const url = 'https://example.com/image.png';
16
- const promise = imageLoad(url);
17
-
18
- mockImage.onload?.({} as Event);
19
- const result = await promise;
20
-
21
- expect(result).toBe(mockImage);
22
- expect(mockImage.src).toBe(url);
23
- expect(mockImage.crossOrigin).toBe('anonymous');
24
- expect(document.body.appendChild).toHaveBeenCalledWith(mockImage);
25
- expect(document.body.removeChild).toHaveBeenCalledWith(mockImage);
26
- });
27
-
28
- it('图片加载失败时应抛出错误', async () => {
29
- const mockImage = new Image();
30
- vi.spyOn(window, 'Image').mockReturnValue(mockImage);
31
-
32
- const url = 'https://example.com/invalid.png';
33
- const promise = imageLoad(url);
34
-
35
- mockImage.onerror?.({} as Event);
36
-
37
- await expect(promise).rejects.toThrow('图片加载失败');
38
- });
39
-
40
- it('如果图片已经加载完成应立即返回', async () => {
41
- const mockImage = new Image();
42
- vi.spyOn(window, 'Image').mockReturnValue(mockImage);
43
- Object.defineProperty(mockImage, 'complete', { value: true });
44
- Object.defineProperty(mockImage, 'width', { value: 100 });
45
-
46
- const url = 'https://example.com/image.png';
47
- const result = await imageLoad(url);
48
-
49
- expect(result).toBe(mockImage);
50
- });
51
-
52
- it('应该为图片元素设置正确的样式', async () => {
53
- const mockImage = new Image();
54
- vi.spyOn(window, 'Image').mockReturnValue(mockImage);
55
-
56
- const url = 'https://example.com/image.png';
57
- const promise = imageLoad(url);
58
-
59
- mockImage.onload?.({} as Event);
60
- await promise;
61
-
62
- expect(mockImage.style.visibility).toBe('hidden');
63
- expect(mockImage.style.position).toBe('absolute');
64
- expect(mockImage.style.top).toBe('-99999%');
65
- expect(mockImage.style.left).toBe('-99999%');
66
- expect(mockImage.style.maxWidth).toBe('');
67
- expect(mockImage.style.maxHeight).toBe('');
68
- expect(mockImage.style.border).toBe('0px');
69
- expect(mockImage.style.width).toBe('auto');
70
- expect(mockImage.style.height).toBe('auto');
71
- expect(mockImage.style.margin).toBe('0px');
72
- expect(mockImage.style.padding).toBe('0px');
73
- expect(mockImage.style.transform).toBe('');
74
- });
75
- });
@@ -1,6 +0,0 @@
1
- import { VERSION } from '@/index';
2
- import { expect, it } from 'vitest';
3
-
4
- it('version', () => {
5
- expect(VERSION).toEqual(PKG_VERSION);
6
- });
@@ -1,109 +0,0 @@
1
- import { frameInterval } from '@/timer';
2
- import { type Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
-
4
- describe('帧间隔计时器', () => {
5
- let mockRAF: number;
6
- let mockCAF: Mock;
7
- let callbacks: FrameRequestCallback[] = [];
8
-
9
- beforeEach(() => {
10
- mockRAF = 0;
11
- callbacks = [];
12
- mockCAF = vi.fn();
13
-
14
- vi.stubGlobal('requestAnimationFrame', (cb: FrameRequestCallback) => {
15
- callbacks.push(cb);
16
- return ++mockRAF;
17
- });
18
-
19
- vi.stubGlobal('cancelAnimationFrame', mockCAF);
20
- });
21
-
22
- afterEach(() => {
23
- vi.unstubAllGlobals();
24
- });
25
-
26
- it('启动时应在每一帧调用回调函数', () => {
27
- const callback = vi.fn();
28
- const timer = frameInterval(callback);
29
-
30
- timer.start();
31
- callbacks[0]?.(0);
32
- const arg = callback.mock.calls[0][0];
33
- expect(Object.keys(arg)).toEqual(
34
- expect.arrayContaining([
35
- 'times',
36
- 'startAt',
37
- 'stopAt',
38
- 'pauseAt',
39
- 'resumeAt',
40
- 'currentAt',
41
- 'elapsedTime',
42
- 'runningTime',
43
- 'intervalTime',
44
- ]),
45
- );
46
- });
47
-
48
- it('应该支持 leading 选项', () => {
49
- const callback = vi.fn();
50
- const timer = frameInterval(callback, { leading: true });
51
-
52
- timer.start();
53
- expect(callback).toHaveBeenCalled();
54
- });
55
-
56
- it('停止时应支持 trailing 选项', () => {
57
- const callback = vi.fn();
58
- const timer = frameInterval(callback, { trailing: true });
59
-
60
- timer.start();
61
- callbacks[0]?.(0);
62
-
63
- timer.stop();
64
- expect(callback).toHaveBeenCalledTimes(2);
65
- expect(mockCAF).toHaveBeenCalledWith(mockRAF);
66
- });
67
-
68
- it('暂停时应支持 trailing 选项', () => {
69
- const callback = vi.fn();
70
- const timer = frameInterval(callback, { trailing: true });
71
-
72
- timer.start();
73
- callbacks[0]?.(0);
74
-
75
- timer.pause();
76
- expect(callback).toHaveBeenCalledTimes(2);
77
- expect(mockCAF).toHaveBeenCalledWith(mockRAF);
78
- });
79
-
80
- it('使用 immediate 标志时应立即恢复', () => {
81
- const callback = vi.fn();
82
- const timer = frameInterval(callback);
83
-
84
- timer.start();
85
- callbacks[0]?.(0);
86
- timer.pause();
87
-
88
- timer.resume(true);
89
- callbacks[1]?.(16);
90
-
91
- expect(callback).toHaveBeenCalledTimes(3);
92
- expect(callback.mock.calls[1][0].times).toBe(2);
93
- });
94
-
95
- it('不使用 immediate 标志时应下一帧恢复', () => {
96
- const callback = vi.fn();
97
- const timer = frameInterval(callback);
98
-
99
- timer.start();
100
- callbacks[0]?.(0);
101
- timer.pause();
102
-
103
- timer.resume();
104
- callbacks[1]?.(16);
105
-
106
- expect(callback).toHaveBeenCalledTimes(1);
107
- expect(callback.mock.calls[0][0].times).toBe(1);
108
- });
109
- });