pure-md5 0.2.0 → 0.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 (158) hide show
  1. package/dist/adapters/ie11.cjs +1 -2
  2. package/dist/adapters/ie11.js +1 -2
  3. package/dist/adapters/node.cjs +1 -2
  4. package/dist/adapters/node.js +1 -2
  5. package/dist/adapters/webcrypto.cjs +1 -2
  6. package/dist/adapters/webcrypto.js +1 -2
  7. package/dist/core/index.cjs +1 -2
  8. package/dist/core/index.js +1 -2
  9. package/dist/index.cjs +1 -2
  10. package/dist/index.js +1 -2
  11. package/dist/stream/adapter.cjs +1 -2
  12. package/dist/stream/adapter.js +1 -2
  13. package/dist/stream/fs-utils.cjs +1 -2
  14. package/dist/stream/fs-utils.js +1 -2
  15. package/dist/stream/index.cjs +1 -2
  16. package/dist/stream/index.js +1 -2
  17. package/dist/stream/light/index.cjs +1 -2
  18. package/dist/stream/light/index.js +1 -2
  19. package/dist/stream/md5-stream.cjs +1 -2
  20. package/dist/stream/md5-stream.js +1 -2
  21. package/dist/stream/whatwg-stream.cjs +1 -2
  22. package/dist/stream/whatwg-stream.js +1 -2
  23. package/dist/utils/detect.cjs +1 -2
  24. package/dist/utils/detect.js +1 -2
  25. package/package.json +1 -1
  26. package/pure-md5-0.2.0.tgz +0 -0
  27. package/.aliases +0 -19
  28. package/.bash_profile +0 -12
  29. package/.bash_prompt +0 -56
  30. package/.changeset/README.md +0 -32
  31. package/.changeset/config.json +0 -16
  32. package/.continue/mcpServers/new-mcp-server.yaml +0 -10
  33. package/.continue/rules +0 -29
  34. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
  35. package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
  36. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  37. package/.github/PULL_REQUEST_TEMPLATE.md +0 -35
  38. package/.github/workflows/npm-publish.yml +0 -33
  39. package/.github/workflows/release.yml +0 -42
  40. package/CHANGELOG.md +0 -9
  41. package/CONTRIBUTING.md +0 -203
  42. package/MIGRATION_GUIDE_STREAMS.md +0 -374
  43. package/STREAM_API.md +0 -582
  44. package/STREAM_BENCHMARKS.md +0 -232
  45. package/STREAM_EXAMPLES.md +0 -669
  46. package/STREAM_OPTIMIZATION_REPORT.md +0 -136
  47. package/STREAM_TROUBLESHOOTING.md +0 -537
  48. package/WEB_CRYPTO_TESTS_SUMMARY.md +0 -140
  49. package/WHATWG_STREAMS.md +0 -191
  50. package/__tests__/adapters/node-crypto.test.ts +0 -167
  51. package/__tests__/adapters/web-crypto-node.test.ts +0 -73
  52. package/__tests__/adapters/web-crypto.test.ts +0 -195
  53. package/__tests__/add32.test.ts +0 -33
  54. package/__tests__/fallback.test.ts +0 -345
  55. package/__tests__/hex.test.ts +0 -38
  56. package/__tests__/hex_chr.test.ts +0 -20
  57. package/__tests__/index.test.ts +0 -87
  58. package/__tests__/integration/fixtures/test-file.txt +0 -1
  59. package/__tests__/integration/md5-stream-file.test.ts +0 -293
  60. package/__tests__/integration/node-crypto-file.test.ts +0 -86
  61. package/__tests__/integration/web-crypto.test.ts +0 -38
  62. package/__tests__/md51.test.ts +0 -73
  63. package/__tests__/md5block.test.ts +0 -61
  64. package/__tests__/md5cycle.test.ts +0 -48
  65. package/__tests__/round-functions.test.ts +0 -87
  66. package/__tests__/stream/fs-utils.test.ts +0 -209
  67. package/__tests__/stream/md5-stream-edge-cases.test.ts +0 -461
  68. package/__tests__/stream/md5-stream.test.ts +0 -418
  69. package/__tests__/stream/whatwg-stream.test.ts +0 -355
  70. package/__tests__/stream/whatwg-stream.test.ts.bak2 +0 -335
  71. package/benchmarks/md5-stream.bench.ts +0 -212
  72. package/benchmarks/whatwg-stream.bench.ts +0 -180
  73. package/dist/adapters/ie11.cjs.map +0 -1
  74. package/dist/adapters/ie11.js.map +0 -1
  75. package/dist/adapters/node.cjs.map +0 -1
  76. package/dist/adapters/node.js.map +0 -1
  77. package/dist/adapters/webcrypto.cjs.map +0 -1
  78. package/dist/adapters/webcrypto.js.map +0 -1
  79. package/dist/chunk-2YXXFGBV.js +0 -2
  80. package/dist/chunk-2YXXFGBV.js.map +0 -1
  81. package/dist/chunk-4KSCMS4Q.js +0 -2
  82. package/dist/chunk-4KSCMS4Q.js.map +0 -1
  83. package/dist/chunk-6P2QV5SR.js +0 -4
  84. package/dist/chunk-6P2QV5SR.js.map +0 -1
  85. package/dist/chunk-G5WHEAIQ.js +0 -2
  86. package/dist/chunk-G5WHEAIQ.js.map +0 -1
  87. package/dist/chunk-H2K353LR.js +0 -2
  88. package/dist/chunk-H2K353LR.js.map +0 -1
  89. package/dist/chunk-JKVD5LHZ.js +0 -2
  90. package/dist/chunk-JKVD5LHZ.js.map +0 -1
  91. package/dist/chunk-NWQ4N5RX.js +0 -2
  92. package/dist/chunk-NWQ4N5RX.js.map +0 -1
  93. package/dist/chunk-PHZ7FTYF.js +0 -2
  94. package/dist/chunk-PHZ7FTYF.js.map +0 -1
  95. package/dist/chunk-PNZTVQA7.js +0 -2
  96. package/dist/chunk-PNZTVQA7.js.map +0 -1
  97. package/dist/chunk-R4JB5MBR.js +0 -2
  98. package/dist/chunk-R4JB5MBR.js.map +0 -1
  99. package/dist/chunk-VFOAY6XI.js +0 -2
  100. package/dist/chunk-VFOAY6XI.js.map +0 -1
  101. package/dist/chunk-XB5BQIEX.js +0 -2
  102. package/dist/chunk-XB5BQIEX.js.map +0 -1
  103. package/dist/core/index.cjs.map +0 -1
  104. package/dist/core/index.js.map +0 -1
  105. package/dist/index.cjs.map +0 -1
  106. package/dist/index.js.map +0 -1
  107. package/dist/stream/adapter.cjs.map +0 -1
  108. package/dist/stream/adapter.js.map +0 -1
  109. package/dist/stream/fs-utils.cjs.map +0 -1
  110. package/dist/stream/fs-utils.js.map +0 -1
  111. package/dist/stream/index.cjs.map +0 -1
  112. package/dist/stream/index.js.map +0 -1
  113. package/dist/stream/light/index.cjs.map +0 -1
  114. package/dist/stream/light/index.js.map +0 -1
  115. package/dist/stream/md5-stream.cjs.map +0 -1
  116. package/dist/stream/md5-stream.js.map +0 -1
  117. package/dist/stream/whatwg-stream.cjs.map +0 -1
  118. package/dist/stream/whatwg-stream.js.map +0 -1
  119. package/dist/utils/detect.cjs.map +0 -1
  120. package/dist/utils/detect.js.map +0 -1
  121. package/planning/03-optimization-size-tree-shaking/01-es-modules-tree-shaking.md +0 -152
  122. package/planning/03-optimization-size-tree-shaking/02-consolidate-modules.md +0 -65
  123. package/planning/03-optimization-size-tree-shaking/03-remove-duplicate-add32.md +0 -93
  124. package/planning/03-optimization-size-tree-shaking/04-remove-runtime-check.md +0 -102
  125. package/planning/03-optimization-size-tree-shaking/05-optimize-loops-performance.md +0 -107
  126. package/planning/03-optimization-size-tree-shaking/06-tsup-formats-configuration.md +0 -227
  127. package/planning/03-optimization-size-tree-shaking/07-multiple-build-formats.md +0 -228
  128. package/planning/03-optimization-size-tree-shaking/08-benchmarks-metrics.md +0 -34
  129. package/planning/03-optimization-size-tree-shaking/MIGRATION_GUIDE.md +0 -260
  130. package/planning/03-optimization-size-tree-shaking/README.md +0 -173
  131. package/planning/03-optimization-size-tree-shaking/SUMMARY.md +0 -168
  132. package/planning/04-adapter-backend/03-backend-web-crypto.md +0 -149
  133. package/planning/04-adapter-backend/04-backend-node-crypto.md +0 -181
  134. package/planning/04-adapter-backend/05-backend-pure-js.md +0 -174
  135. package/planning/04-adapter-backend/06-backend-ie11.md +0 -158
  136. package/planning/04-adapter-backend/07-detection-environment.md +0 -232
  137. package/planning/04-adapter-backend/08-detection-backend.md +0 -210
  138. package/planning/04-adapter-backend/09-adapter-unified.md +0 -255
  139. package/planning/04-adapter-backend/10-fallback-mechanism.md +0 -333
  140. package/planning/04-adapter-backend/11-tests-backend-web-crypto.md +0 -191
  141. package/planning/04-adapter-backend/12-tests-backend-node-crypto.md +0 -222
  142. package/planning/04-adapter-backend/README.md +0 -45
  143. package/planning/05-documentation-publishing/01-README-optimization.md +0 -105
  144. package/planning/05-documentation-publishing/02-VitePress-site-evaluation.md +0 -136
  145. package/planning/05-documentation-publishing/03-Changeset-setup.md +0 -192
  146. package/planning/05-documentation-publishing/04-GitHub-templates.md +0 -252
  147. package/planning/05-documentation-publishing/README.md +0 -22
  148. package/planning/05-documentation-publishing/STATUS.md +0 -222
  149. package/planning/prd.md +0 -405
  150. package/planning/streams/01-create-md5stream-class.md +0 -69
  151. package/planning/streams/02-create-factory-api.md +0 -65
  152. package/planning/streams/03-fs-integration.md +0 -37
  153. package/planning/streams/04-whatwg-streams-support.md +0 -37
  154. package/planning/streams/05-audit-optimization.md +0 -121
  155. package/planning/streams/06-comprehensive-tests-docs.md +0 -137
  156. package/planning/streams/07-architecture-integration.md +0 -38
  157. package/planning/streams/README.md +0 -98
  158. 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
- });