pure-md5 0.2.0 → 0.2.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 (177) hide show
  1. package/README.md +38 -24
  2. package/dist/adapters/ie11.cjs +1 -2
  3. package/dist/adapters/ie11.js +1 -2
  4. package/dist/adapters/node.cjs +1 -2
  5. package/dist/adapters/node.js +1 -2
  6. package/dist/adapters/webcrypto.cjs +1 -2
  7. package/dist/adapters/webcrypto.js +1 -2
  8. package/dist/index.cjs +1 -2
  9. package/dist/index.d.ts +149 -5
  10. package/dist/index.js +3 -2
  11. package/dist/md5.cjs +1 -0
  12. package/dist/md5.d.ts +20 -0
  13. package/dist/md5.js +1 -0
  14. package/dist/stream/md5-stream.cjs +1 -2
  15. package/dist/stream/md5-stream.js +1 -2
  16. package/dist/stream/whatwg-stream.cjs +1 -2
  17. package/dist/stream/whatwg-stream.js +1 -2
  18. package/dist/utils/detect.cjs +1 -2
  19. package/dist/utils/detect.js +3 -2
  20. package/package.json +10 -15
  21. package/pure-md5-0.2.1.tgz +0 -0
  22. package/test-tree-shake.mjs +12 -0
  23. package/.aliases +0 -19
  24. package/.bash_profile +0 -12
  25. package/.bash_prompt +0 -56
  26. package/.changeset/README.md +0 -32
  27. package/.changeset/config.json +0 -16
  28. package/.continue/mcpServers/new-mcp-server.yaml +0 -10
  29. package/.continue/rules +0 -29
  30. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  31. package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
  32. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  33. package/.github/PULL_REQUEST_TEMPLATE.md +0 -35
  34. package/.github/workflows/npm-publish.yml +0 -33
  35. package/.github/workflows/release.yml +0 -42
  36. package/CHANGELOG.md +0 -9
  37. package/CONTRIBUTING.md +0 -203
  38. package/MIGRATION_GUIDE_STREAMS.md +0 -374
  39. package/STREAM_API.md +0 -582
  40. package/STREAM_BENCHMARKS.md +0 -232
  41. package/STREAM_EXAMPLES.md +0 -669
  42. package/STREAM_OPTIMIZATION_REPORT.md +0 -136
  43. package/STREAM_TROUBLESHOOTING.md +0 -537
  44. package/WEB_CRYPTO_TESTS_SUMMARY.md +0 -140
  45. package/WHATWG_STREAMS.md +0 -191
  46. package/__tests__/adapters/node-crypto.test.ts +0 -167
  47. package/__tests__/adapters/web-crypto-node.test.ts +0 -73
  48. package/__tests__/adapters/web-crypto.test.ts +0 -195
  49. package/__tests__/add32.test.ts +0 -33
  50. package/__tests__/fallback.test.ts +0 -345
  51. package/__tests__/hex.test.ts +0 -38
  52. package/__tests__/hex_chr.test.ts +0 -20
  53. package/__tests__/index.test.ts +0 -87
  54. package/__tests__/integration/fixtures/test-file.txt +0 -1
  55. package/__tests__/integration/md5-stream-file.test.ts +0 -293
  56. package/__tests__/integration/node-crypto-file.test.ts +0 -86
  57. package/__tests__/integration/web-crypto.test.ts +0 -38
  58. package/__tests__/md51.test.ts +0 -73
  59. package/__tests__/md5block.test.ts +0 -61
  60. package/__tests__/md5cycle.test.ts +0 -48
  61. package/__tests__/round-functions.test.ts +0 -87
  62. package/__tests__/stream/fs-utils.test.ts +0 -209
  63. package/__tests__/stream/md5-stream-edge-cases.test.ts +0 -461
  64. package/__tests__/stream/md5-stream.test.ts +0 -418
  65. package/__tests__/stream/whatwg-stream.test.ts +0 -355
  66. package/__tests__/stream/whatwg-stream.test.ts.bak2 +0 -335
  67. package/benchmarks/md5-stream.bench.ts +0 -212
  68. package/benchmarks/whatwg-stream.bench.ts +0 -180
  69. package/dist/adapters/ie11.cjs.map +0 -1
  70. package/dist/adapters/ie11.js.map +0 -1
  71. package/dist/adapters/node.cjs.map +0 -1
  72. package/dist/adapters/node.js.map +0 -1
  73. package/dist/adapters/webcrypto.cjs.map +0 -1
  74. package/dist/adapters/webcrypto.js.map +0 -1
  75. package/dist/chunk-2YXXFGBV.js +0 -2
  76. package/dist/chunk-2YXXFGBV.js.map +0 -1
  77. package/dist/chunk-4KSCMS4Q.js +0 -2
  78. package/dist/chunk-4KSCMS4Q.js.map +0 -1
  79. package/dist/chunk-6P2QV5SR.js +0 -4
  80. package/dist/chunk-6P2QV5SR.js.map +0 -1
  81. package/dist/chunk-G5WHEAIQ.js +0 -2
  82. package/dist/chunk-G5WHEAIQ.js.map +0 -1
  83. package/dist/chunk-H2K353LR.js +0 -2
  84. package/dist/chunk-H2K353LR.js.map +0 -1
  85. package/dist/chunk-JKVD5LHZ.js +0 -2
  86. package/dist/chunk-JKVD5LHZ.js.map +0 -1
  87. package/dist/chunk-NWQ4N5RX.js +0 -2
  88. package/dist/chunk-NWQ4N5RX.js.map +0 -1
  89. package/dist/chunk-PHZ7FTYF.js +0 -2
  90. package/dist/chunk-PHZ7FTYF.js.map +0 -1
  91. package/dist/chunk-PNZTVQA7.js +0 -2
  92. package/dist/chunk-PNZTVQA7.js.map +0 -1
  93. package/dist/chunk-R4JB5MBR.js +0 -2
  94. package/dist/chunk-R4JB5MBR.js.map +0 -1
  95. package/dist/chunk-VFOAY6XI.js +0 -2
  96. package/dist/chunk-VFOAY6XI.js.map +0 -1
  97. package/dist/chunk-XB5BQIEX.js +0 -2
  98. package/dist/chunk-XB5BQIEX.js.map +0 -1
  99. package/dist/core/index.cjs +0 -2
  100. package/dist/core/index.cjs.map +0 -1
  101. package/dist/core/index.d.cts +0 -19
  102. package/dist/core/index.d.ts +0 -19
  103. package/dist/core/index.js +0 -2
  104. package/dist/core/index.js.map +0 -1
  105. package/dist/index.cjs.map +0 -1
  106. package/dist/index.d.cts +0 -84
  107. package/dist/index.js.map +0 -1
  108. package/dist/stream/adapter.cjs +0 -2
  109. package/dist/stream/adapter.cjs.map +0 -1
  110. package/dist/stream/adapter.d.cts +0 -63
  111. package/dist/stream/adapter.d.ts +0 -63
  112. package/dist/stream/adapter.js +0 -2
  113. package/dist/stream/adapter.js.map +0 -1
  114. package/dist/stream/fs-utils.cjs +0 -2
  115. package/dist/stream/fs-utils.cjs.map +0 -1
  116. package/dist/stream/fs-utils.d.cts +0 -137
  117. package/dist/stream/fs-utils.d.ts +0 -137
  118. package/dist/stream/fs-utils.js +0 -2
  119. package/dist/stream/fs-utils.js.map +0 -1
  120. package/dist/stream/index.cjs +0 -2
  121. package/dist/stream/index.cjs.map +0 -1
  122. package/dist/stream/index.d.cts +0 -4
  123. package/dist/stream/index.d.ts +0 -4
  124. package/dist/stream/index.js +0 -2
  125. package/dist/stream/index.js.map +0 -1
  126. package/dist/stream/light/index.cjs +0 -2
  127. package/dist/stream/light/index.cjs.map +0 -1
  128. package/dist/stream/light/index.d.cts +0 -4
  129. package/dist/stream/light/index.d.ts +0 -4
  130. package/dist/stream/light/index.js +0 -2
  131. package/dist/stream/light/index.js.map +0 -1
  132. package/dist/stream/md5-stream.cjs.map +0 -1
  133. package/dist/stream/md5-stream.js.map +0 -1
  134. package/dist/stream/whatwg-stream.cjs.map +0 -1
  135. package/dist/stream/whatwg-stream.js.map +0 -1
  136. package/dist/types-edGoGJ5V.d.cts +0 -42
  137. package/dist/types-edGoGJ5V.d.ts +0 -42
  138. package/dist/utils/detect.cjs.map +0 -1
  139. package/dist/utils/detect.js.map +0 -1
  140. package/planning/03-optimization-size-tree-shaking/01-es-modules-tree-shaking.md +0 -152
  141. package/planning/03-optimization-size-tree-shaking/02-consolidate-modules.md +0 -65
  142. package/planning/03-optimization-size-tree-shaking/03-remove-duplicate-add32.md +0 -93
  143. package/planning/03-optimization-size-tree-shaking/04-remove-runtime-check.md +0 -102
  144. package/planning/03-optimization-size-tree-shaking/05-optimize-loops-performance.md +0 -107
  145. package/planning/03-optimization-size-tree-shaking/06-tsup-formats-configuration.md +0 -227
  146. package/planning/03-optimization-size-tree-shaking/07-multiple-build-formats.md +0 -228
  147. package/planning/03-optimization-size-tree-shaking/08-benchmarks-metrics.md +0 -34
  148. package/planning/03-optimization-size-tree-shaking/MIGRATION_GUIDE.md +0 -260
  149. package/planning/03-optimization-size-tree-shaking/README.md +0 -173
  150. package/planning/03-optimization-size-tree-shaking/SUMMARY.md +0 -168
  151. package/planning/04-adapter-backend/03-backend-web-crypto.md +0 -149
  152. package/planning/04-adapter-backend/04-backend-node-crypto.md +0 -181
  153. package/planning/04-adapter-backend/05-backend-pure-js.md +0 -174
  154. package/planning/04-adapter-backend/06-backend-ie11.md +0 -158
  155. package/planning/04-adapter-backend/07-detection-environment.md +0 -232
  156. package/planning/04-adapter-backend/08-detection-backend.md +0 -210
  157. package/planning/04-adapter-backend/09-adapter-unified.md +0 -255
  158. package/planning/04-adapter-backend/10-fallback-mechanism.md +0 -333
  159. package/planning/04-adapter-backend/11-tests-backend-web-crypto.md +0 -191
  160. package/planning/04-adapter-backend/12-tests-backend-node-crypto.md +0 -222
  161. package/planning/04-adapter-backend/README.md +0 -45
  162. package/planning/05-documentation-publishing/01-README-optimization.md +0 -105
  163. package/planning/05-documentation-publishing/02-VitePress-site-evaluation.md +0 -136
  164. package/planning/05-documentation-publishing/03-Changeset-setup.md +0 -192
  165. package/planning/05-documentation-publishing/04-GitHub-templates.md +0 -252
  166. package/planning/05-documentation-publishing/README.md +0 -22
  167. package/planning/05-documentation-publishing/STATUS.md +0 -222
  168. package/planning/prd.md +0 -405
  169. package/planning/streams/01-create-md5stream-class.md +0 -69
  170. package/planning/streams/02-create-factory-api.md +0 -65
  171. package/planning/streams/03-fs-integration.md +0 -37
  172. package/planning/streams/04-whatwg-streams-support.md +0 -37
  173. package/planning/streams/05-audit-optimization.md +0 -121
  174. package/planning/streams/06-comprehensive-tests-docs.md +0 -137
  175. package/planning/streams/07-architecture-integration.md +0 -38
  176. package/planning/streams/README.md +0 -98
  177. package/tsup.config.ts +0 -24
@@ -1,195 +0,0 @@
1
- /**
2
- * Tests for Web Crypto Backend
3
- */
4
-
5
- import { WebCryptoBackend } from '../../src/adapters/webcrypto';
6
-
7
- describe('WebCryptoBackend', () => {
8
- let backend: WebCryptoBackend;
9
-
10
- beforeAll(async () => {
11
- const available = WebCryptoBackend.isAvailable();
12
- if (!available) {
13
- console.log('Web Crypto API not available, skipping tests');
14
- } else {
15
- backend = new WebCryptoBackend();
16
- }
17
- });
18
-
19
- describe('Basic hashing', () => {
20
- it('should hash string correctly', async () => {
21
- if (!backend) {
22
- console.log('Skipping test: Web Crypto API not available');
23
- return;
24
- }
25
-
26
- const result = await backend.hash('hello');
27
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
28
- });
29
-
30
- it('should hash empty string', async () => {
31
- if (!backend) {
32
- console.log('Skipping test: Web Crypto API not available');
33
- return;
34
- }
35
-
36
- const result = await backend.hash('');
37
- expect(result).toBe('d41d8cd98f00b204e9800998ecf8427e');
38
- });
39
-
40
- it('should hash special characters', async () => {
41
- if (!backend) {
42
- console.log('Skipping test: Web Crypto API not available');
43
- return;
44
- }
45
-
46
- const result = await backend.hash('!@#$%^&*()');
47
- expect(result).toBe('05b28d17a7b6e7024b6e5d8cc43a8bf7');
48
- });
49
-
50
- it('should hash unicode characters', async () => {
51
- if (!backend) {
52
- console.log('Skipping test: Web Crypto API not available');
53
- return;
54
- }
55
-
56
- const result = await backend.hash('Привет мир');
57
- expect(result).toBe('5abca3326cf0cefc00efe7065b5e0cf6');
58
- });
59
-
60
- it('should hash long string', async () => {
61
- if (!backend) {
62
- console.log('Skipping test: Web Crypto API not available');
63
- return;
64
- }
65
-
66
- const longString = 'a'.repeat(10000);
67
- const result = await backend.hash(longString);
68
- expect(result.length).toBe(32);
69
- });
70
- });
71
-
72
- describe('Binary data', () => {
73
- it('should hash Uint8Array', async () => {
74
- if (!backend) {
75
- console.log('Skipping test: Web Crypto API not available');
76
- return;
77
- }
78
-
79
- const data = new Uint8Array([104, 101, 108, 108, 111]);
80
- const result = await backend.hashBinary(data);
81
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
82
- });
83
-
84
- it('should hash ArrayBuffer', async () => {
85
- if (!backend) {
86
- console.log('Skipping test: Web Crypto API not available');
87
- return;
88
- }
89
-
90
- const data = new TextEncoder().encode('hello').buffer;
91
- const result = await backend.hashBinary(data);
92
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
93
- });
94
-
95
- it('should hash empty Uint8Array', async () => {
96
- if (!backend) {
97
- console.log('Skipping test: Web Crypto API not available');
98
- return;
99
- }
100
-
101
- const data = new Uint8Array(0);
102
- const result = await backend.hashBinary(data);
103
- expect(result).toBe('d41d8cd98f00b204e9800998ecf8427e');
104
- });
105
- });
106
-
107
- describe('Availability', () => {
108
- it('should check Web Crypto API availability', async () => {
109
- const available = WebCryptoBackend.isAvailable();
110
- expect(typeof available).toBe('boolean');
111
- });
112
- });
113
-
114
- describe('Performance', () => {
115
- it('should hash 1MB data efficiently', async () => {
116
- if (!backend) {
117
- console.log('Skipping test: Web Crypto API not available');
118
- return;
119
- }
120
-
121
- const data = 'a'.repeat(1024 * 1024);
122
-
123
- const start = performance.now();
124
- const result = await backend.hash(data);
125
- const duration = performance.now() - start;
126
-
127
- expect(result.length).toBe(32);
128
- expect(duration).toBeLessThan(1000);
129
- });
130
- });
131
-
132
- describe('Consistency', () => {
133
- it('should produce same hash for same input', async () => {
134
- if (!backend) {
135
- console.log('Skipping test: Web Crypto API not available');
136
- return;
137
- }
138
-
139
- const input = 'test input';
140
- const result1 = await backend.hash(input);
141
- const result2 = await backend.hash(input);
142
- expect(result1).toBe(result2);
143
- });
144
-
145
- it('should produce different hash for different inputs', async () => {
146
- if (!backend) {
147
- console.log('Skipping test: Web Crypto API not available');
148
- return;
149
- }
150
-
151
- const result1 = await backend.hash('hello');
152
- const result2 = await backend.hash('world');
153
- expect(result1).not.toBe(result2);
154
- });
155
- });
156
-
157
- describe('Interface compliance', () => {
158
- it('should have correct name and version', async () => {
159
- if (!backend) {
160
- console.log('Skipping test: Web Crypto API not available');
161
- return;
162
- }
163
-
164
- expect(backend.name).toBe('webcrypto');
165
- expect(backend.version).toBe('1.0.0');
166
- });
167
-
168
- it('should have reset method', async () => {
169
- if (!backend) {
170
- console.log('Skipping test: Web Crypto API not available');
171
- return;
172
- }
173
-
174
- expect(typeof backend.reset).toBe('function');
175
- });
176
-
177
- it('should throw error on update (no streaming)', async () => {
178
- if (!backend) {
179
- console.log('Skipping test: Web Crypto API not available');
180
- return;
181
- }
182
-
183
- expect(() => backend.update('test')).toThrow('Web Crypto API does not support streaming updates');
184
- });
185
-
186
- it('should throw error on digest (no streaming)', async () => {
187
- if (!backend) {
188
- console.log('Skipping test: Web Crypto API not available');
189
- return;
190
- }
191
-
192
- expect(() => backend.digest()).toThrow('Web Crypto API does not support streaming');
193
- });
194
- });
195
- });
@@ -1,33 +0,0 @@
1
- import add32 from '../src/add32';
2
-
3
- describe('add32', () => {
4
- test('should add two numbers and wrap around at 32 bits', () => {
5
- // Test basic addition
6
- expect(add32(1, 2)).toBe(3);
7
- expect(add32(10, 20)).toBe(30);
8
- expect(add32(100, 200)).toBe(300);
9
- });
10
-
11
- test('should handle large numbers correctly (32-bit wrap)', () => {
12
- // 2^32 - 1 = 4294967295
13
- expect(add32(4294967295, 1)).toBe(0); // Wrap around
14
- expect(add32(4294967295, 2)).toBe(1);
15
- expect(add32(4294967290, 10)).toBe(4); // Fixed: 4294967290 + 10 = 4294967300 mod 2^32 = 4
16
- });
17
-
18
- test("should handle negative numbers in two's complement", () => {
19
- // In two's complement 32-bit, -1 = 4294967295
20
- expect(add32(-1, 1)).toBe(0);
21
- expect(add32(-10, 10)).toBe(0);
22
- expect(add32(-100, 100)).toBe(0);
23
- });
24
-
25
- test('should maintain 32-bit integer behavior', () => {
26
- // Test overflow behavior
27
- const max32 = 4294967295;
28
- expect(add32(max32, max32)).toBe(-2); // Fixed: (2^32 - 1) + (2^32 - 1) = 2^33 - 2 = 0x1FFFFFFFE → 0xFFFFFFFE = -2 in two's complement
29
-
30
- // Test that results stay within 32-bit range
31
- expect(add32(0xffffffff, 0xffffffff)).toBe(-2); // Same as above
32
- });
33
- });
@@ -1,345 +0,0 @@
1
- import {
2
- FallbackManager,
3
- robustHash,
4
- metrics,
5
- detector
6
- } from '../src/utils/detect.js';
7
- import { WebCryptoBackend } from '../src/adapters/webcrypto.js';
8
- import { NodeCryptoBackend } from '../src/adapters/node.js';
9
- import { IE11Backend } from '../src/adapters/ie11.js';
10
- import { PureJSBackend } from '../src/adapters/pure-js.js';
11
-
12
- describe('FallbackManager', () => {
13
- let manager: FallbackManager;
14
-
15
- beforeEach(() => {
16
- manager = new FallbackManager();
17
- });
18
-
19
- describe('Constructor', () => {
20
- it('should create with default fallback order', () => {
21
- expect(manager).toBeDefined();
22
- });
23
-
24
- it('should create with custom fallback order', () => {
25
- const customManager = new FallbackManager(['purejs', 'webcrypto']);
26
- expect(customManager).toBeDefined();
27
- });
28
- });
29
-
30
- describe('getAvailableBackends', () => {
31
- it('should return available backends in priority order', async () => {
32
- const available = await manager.getAvailableBackends();
33
- expect(Array.isArray(available)).toBe(true);
34
- expect(available.length).toBeGreaterThan(0);
35
- });
36
-
37
- it('should include purejs as fallback', async () => {
38
- const available = await manager.getAvailableBackends();
39
- expect(available).toContain('purejs');
40
- });
41
-
42
- it('should check nodecrypto availability', async () => {
43
- const available = await manager.getAvailableBackends();
44
- const hasNodeCrypto = available.includes('nodecrypto');
45
- const nodeAvailable = NodeCryptoBackend.isAvailable();
46
- expect(hasNodeCrypto).toBe(nodeAvailable);
47
- });
48
-
49
- xit('should check webcrypto availability', async () => {
50
- const available = await manager.getAvailableBackends();
51
- const hasWebCrypto = available.includes('webcrypto');
52
- const webAvailable = WebCryptoBackend.isAvailable();
53
- // Check consistency between available backends and isAvailable
54
- expect(hasWebCrypto).toBe(webAvailable);
55
- });
56
- });
57
-
58
- describe('getBestBackend', () => {
59
- it('should return best available backend', async () => {
60
- const best = await manager.getBestBackend();
61
- expect(typeof best).toBe('string');
62
- expect(['nodecrypto', 'webcrypto', 'ie11', 'purejs']).toContain(best);
63
- });
64
-
65
- it('should prioritize nodecrypto if available', async () => {
66
- const available = await manager.getAvailableBackends();
67
- const best = await manager.getBestBackend();
68
-
69
- if (available.includes('nodecrypto')) {
70
- expect(best).toBe('nodecrypto');
71
- }
72
- });
73
- });
74
-
75
- describe('execute', () => {
76
- it('should execute operation with fallback and return success', async () => {
77
- const result = await manager.execute(async (backend) =>
78
- backend.hash('hello')
79
- );
80
- expect(result.success).toBe(true);
81
- expect(result.backend).toBeDefined();
82
- expect(result.data).toBe('5d41402abc4b2a76b9719d911017c592');
83
- });
84
-
85
- it('should fallback to available backend when first fails', async () => {
86
- // Test that fallback works when first backend throws error
87
- const failingManager = new FallbackManager(['nodecrypto', 'purejs']);
88
-
89
- // Mock NodeCryptoBackend to throw error
90
- const originalHash = NodeCryptoBackend.prototype.hash;
91
- NodeCryptoBackend.prototype.hash = function () {
92
- throw new Error('Node crypto not available');
93
- };
94
-
95
- try {
96
- const result = await failingManager.execute(async (backend) =>
97
- backend.hash('hello')
98
- );
99
-
100
- expect(result.success).toBe(true);
101
- expect(result.backend).toBe('purejs');
102
- } finally {
103
- // Restore original
104
- NodeCryptoBackend.prototype.hash = originalHash;
105
- }
106
- });
107
-
108
- it('should handle backend that throws error', async () => {
109
- const managerWithFailing = new FallbackManager(['purejs']);
110
-
111
- const result = await managerWithFailing.execute(async () => {
112
- throw new Error('Direct error');
113
- });
114
-
115
- expect(result.success).toBe(false);
116
- expect(result.errors).toBeDefined();
117
- });
118
- });
119
-
120
- describe('hash', () => {
121
- it('should hash string with fallback', async () => {
122
- const result = await manager.hash('hello');
123
- expect(result.success).toBe(true);
124
- expect(result.data).toBe('5d41402abc4b2a76b9719d911017c592');
125
- });
126
-
127
- it('should hash empty string', async () => {
128
- const result = await manager.hash('');
129
- expect(result.success).toBe(true);
130
- expect(result.data).toBe('d41d8cd98f00b204e9800998ecf8427e');
131
- });
132
-
133
- it('should return correct backend name', async () => {
134
- const result = await manager.hash('test');
135
- expect(result.backend).toBeDefined();
136
- expect(['nodecrypto', 'webcrypto', 'ie11', 'purejs']).toContain(
137
- result.backend
138
- );
139
- });
140
- });
141
-
142
- describe('hashBinary', () => {
143
- it('should hash binary data with fallback', async () => {
144
- const data = new Uint8Array([104, 101, 108, 108, 111]); // "hello"
145
- const result = await manager.hashBinary(data);
146
- expect(result.success).toBe(true);
147
- expect(result.data).toBe('5d41402abc4b2a76b9719d911017c592');
148
- });
149
-
150
- it('should hash ArrayBuffer', async () => {
151
- const data = new TextEncoder().encode('hello').buffer;
152
- const result = await manager.hashBinary(data);
153
- expect(result.success).toBe(true);
154
- });
155
- });
156
-
157
- describe('detector integration', () => {
158
- it('should use detector for backend creation', async () => {
159
- const backend = await detector.createBackendByName('purejs');
160
- expect(backend).toBeInstanceOf(PureJSBackend);
161
- });
162
-
163
- it('should create different backend types', async () => {
164
- const nodeBackend = await detector.createBackendByName('nodecrypto');
165
- expect(nodeBackend).toBeInstanceOf(NodeCryptoBackend);
166
-
167
- const webBackend = await detector.createBackendByName('webcrypto');
168
- expect(webBackend).toBeInstanceOf(WebCryptoBackend);
169
-
170
- const ie11Backend = await detector.createBackendByName('ie11');
171
- expect(ie11Backend).toBeInstanceOf(IE11Backend);
172
-
173
- const pureBackend = await detector.createBackendByName('purejs');
174
- expect(pureBackend).toBeInstanceOf(PureJSBackend);
175
- });
176
- });
177
- });
178
-
179
- describe('robustHash function', () => {
180
- beforeEach(() => {
181
- metrics.reset();
182
- });
183
-
184
- it('should hash with default fallback', async () => {
185
- const result = await robustHash('hello');
186
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
187
- });
188
-
189
- it('should hash empty string', async () => {
190
- const result = await robustHash('');
191
- expect(result).toBe('d41d8cd98f00b204e9800998ecf8427e');
192
- });
193
-
194
- it('should use specific backend when forceBackend is set', async () => {
195
- const result = await robustHash('hello', { forceBackend: 'purejs' });
196
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
197
- });
198
-
199
- it('should skip fallback when fallback: false', async () => {
200
- const result = await robustHash('hello', { fallback: false });
201
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
202
- });
203
-
204
- it('should support reportFallback option', async () => {
205
- const consoleSpy = jest.spyOn(console, 'info').mockImplementation();
206
-
207
- const result = await robustHash('hello', {
208
- fallback: true,
209
- reportFallback: true
210
- });
211
-
212
- expect(result).toBe('5d41402abc4b2a76b9719d911017c592');
213
- consoleSpy.mockRestore();
214
- });
215
-
216
- it('should handle multiple backends in fallback chain', async () => {
217
- // Test with various inputs
218
- const testCases = [
219
- 'hello',
220
- '',
221
- 'The quick brown fox jumps over the lazy dog',
222
- 'a'.repeat(1000)
223
- ];
224
-
225
- for (const input of testCases) {
226
- const result = await robustHash(input);
227
- expect(typeof result).toBe('string');
228
- expect(result.length).toBe(32);
229
- expect(result).toMatch(/^[0-9a-f]+$/);
230
- }
231
- });
232
- });
233
-
234
- describe('MetricsCollector', () => {
235
- beforeEach(() => {
236
- metrics.reset();
237
- });
238
-
239
- describe('recordSuccess', () => {
240
- it('should increment success count for nodecrypto', () => {
241
- metrics.recordSuccess('nodecrypto');
242
- expect(metrics.getMetrics().nodecrypto.success).toBe(1);
243
- });
244
-
245
- it('should increment success count for webcrypto', () => {
246
- metrics.recordSuccess('webcrypto');
247
- expect(metrics.getMetrics().webcrypto.success).toBe(1);
248
- });
249
-
250
- it('should increment success count for purejs', () => {
251
- metrics.recordSuccess('purejs');
252
- expect(metrics.getMetrics().purejs.success).toBe(1);
253
- });
254
-
255
- it('should not fail for unknown backend', () => {
256
- expect(() => metrics.recordSuccess('unknown')).not.toThrow();
257
- });
258
- });
259
-
260
- describe('recordFail', () => {
261
- it('should increment fail count for nodecrypto', () => {
262
- metrics.recordFail('nodecrypto');
263
- expect(metrics.getMetrics().nodecrypto.fail).toBe(1);
264
- });
265
-
266
- it('should increment fail count for webcrypto', () => {
267
- metrics.recordFail('webcrypto');
268
- expect(metrics.getMetrics().webcrypto.fail).toBe(1);
269
- });
270
-
271
- it('should not fail for unknown backend', () => {
272
- expect(() => metrics.recordFail('unknown')).not.toThrow();
273
- });
274
- });
275
-
276
- describe('getMetrics', () => {
277
- it('should return all backends metrics', () => {
278
- const allMetrics = metrics.getMetrics();
279
-
280
- expect(allMetrics.nodecrypto).toBeDefined();
281
- expect(allMetrics.webcrypto).toBeDefined();
282
- expect(allMetrics.ie11).toBeDefined();
283
- expect(allMetrics.purejs).toBeDefined();
284
- });
285
-
286
- it('should return correct structure', () => {
287
- const metricsObj = metrics.getMetrics();
288
-
289
- expect(metricsObj.nodecrypto).toEqual({ success: 0, fail: 0 });
290
- expect(metricsObj.webcrypto).toEqual({ success: 0, fail: 0 });
291
- expect(metricsObj.ie11).toEqual({ success: 0, fail: 0 });
292
- expect(metricsObj.purejs).toEqual({ success: 0, fail: 0 });
293
- });
294
- });
295
-
296
- describe('getSummary', () => {
297
- it('should return summary string', () => {
298
- metrics.recordSuccess('nodecrypto');
299
- metrics.recordFail('webcrypto');
300
-
301
- const summary = metrics.getSummary();
302
-
303
- expect(typeof summary).toBe('string');
304
- expect(summary).toContain('Total operations:');
305
- // Check that it contains some backend stats
306
- expect(summary).toContain('success');
307
- expect(summary).toContain('fail');
308
- });
309
-
310
- it('should show correct totals', () => {
311
- metrics.recordSuccess('nodecrypto');
312
- metrics.recordSuccess('nodecrypto');
313
- metrics.recordFail('webcrypto');
314
-
315
- const summary = metrics.getSummary();
316
-
317
- expect(summary).toContain('Total operations: 3');
318
- });
319
- });
320
-
321
- describe('reset', () => {
322
- it('should reset all metrics', () => {
323
- metrics.recordSuccess('nodecrypto');
324
- metrics.recordFail('webcrypto');
325
-
326
- metrics.reset();
327
-
328
- const afterReset = metrics.getMetrics();
329
- expect(afterReset.nodecrypto).toEqual({ success: 0, fail: 0 });
330
- expect(afterReset.webcrypto).toEqual({ success: 0, fail: 0 });
331
- });
332
- });
333
-
334
- describe('Integration with FallbackManager', () => {
335
- it('should track operations through fallback', () => {
336
- // Since FallbackManager doesn't automatically record metrics,
337
- // we test that metrics can be manually recorded
338
- metrics.reset();
339
- metrics.recordSuccess('purejs');
340
-
341
- const currentMetrics = metrics.getMetrics();
342
- expect(currentMetrics.purejs.success).toBe(1);
343
- });
344
- });
345
- });
@@ -1,38 +0,0 @@
1
- import hex from '../src/hex';
2
-
3
- describe('hex', () => {
4
- test('should convert number array to hex string', () => {
5
- const input = [0x12345678, 0x9abcdef0];
6
- const expected = '78563412f0debc9a';
7
- expect(hex(input)).toBe(expected);
8
- });
9
-
10
- test('should handle empty array', () => {
11
- expect(hex([])).toBe('');
12
- });
13
-
14
- test('should handle single number', () => {
15
- expect(hex([0x00000000])).toBe('00000000');
16
- expect(hex([0xffffffff])).toBe('ffffffff');
17
- expect(hex([0x01234567])).toBe('67452301');
18
- });
19
-
20
- test('should convert large numbers correctly', () => {
21
- const input = [0xdeadbeef, 0xcafebabe, 0xfaceb00c];
22
- const expected = 'efbeaddebebafeca0cb0cefa';
23
- expect(hex(input)).toBe(expected);
24
- });
25
-
26
- test('should handle boundary values', () => {
27
- // Minimum
28
- expect(hex([0])).toBe('00000000');
29
-
30
- // Maximum 32-bit
31
- expect(hex([4294967295])).toBe('ffffffff');
32
-
33
- // Test with 4 numbers (typical MD5 output)
34
- expect(hex([1732584193, -271733879, -1732584194, 271733878])).toBe(
35
- '0123456789abcdeffedcba9876543210'
36
- );
37
- });
38
- });
@@ -1,20 +0,0 @@
1
- import hex_chr from '../src/hex_chr';
2
-
3
- describe('hex_chr', () => {
4
- test('should contain all hex digits', () => {
5
- expect(hex_chr).toBeInstanceOf(Array);
6
- expect(hex_chr.length).toBe(16);
7
-
8
- // Check all hex digits
9
- const expected = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
10
- expect(hex_chr).toEqual(expected);
11
- });
12
-
13
- test('should have correct character at each position', () => {
14
- // Spot check some positions
15
- expect(hex_chr[0]).toBe('0');
16
- expect(hex_chr[9]).toBe('9');
17
- expect(hex_chr[10]).toBe('a');
18
- expect(hex_chr[15]).toBe('f');
19
- });
20
- });