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,461 +0,0 @@
1
- /**
2
- * Comprehensive edge case tests for MD5Stream
3
- * Tests public methods, edge cases, and advanced functionality
4
- */
5
-
6
- import { MD5Stream, createMD5Stream } from '../../src/stream/md5-stream.js';
7
- import { md5Core } from '../../src/core/index.js';
8
-
9
- describe('MD5Stream - Public Methods', () => {
10
- describe('getCurrentState()', () => {
11
- test('should return initial state on new instance', () => {
12
- const stream = new MD5Stream();
13
- const state = stream.getCurrentState();
14
-
15
- expect(state.state).toHaveLength(4);
16
- expect(state.state[0]).toBe(1732584193);
17
- expect(state.state[1]).toBe(-271733879);
18
- expect(state.state[2]).toBe(-1732584194);
19
- expect(state.state[3]).toBe(271733878);
20
- expect(state.bytesProcessed).toBe(0);
21
- });
22
-
23
- test('should update state after processing data', () => {
24
- const stream = new MD5Stream();
25
- // Use data larger than 64 bytes to trigger actual processing
26
- stream.write('a'.repeat(70));
27
- const state = stream.getCurrentState();
28
-
29
- expect(state.bytesProcessed).toBeGreaterThan(0);
30
- expect(state.state).not.toEqual([1732584193, -271733879, -1732584194, 271733878]);
31
- });
32
-
33
- test('should not modify internal state on multiple calls', () => {
34
- const stream = new MD5Stream();
35
- stream.write('test');
36
-
37
- const state1 = stream.getCurrentState();
38
- const state2 = stream.getCurrentState();
39
- const state3 = stream.getCurrentState();
40
-
41
- expect(state1).toEqual(state2);
42
- expect(state2).toEqual(state3);
43
- });
44
-
45
- test('should return deep copy of state', () => {
46
- const stream = new MD5Stream();
47
- const state1 = stream.getCurrentState();
48
-
49
- // Modify returned state
50
- state1.state[0] = 0;
51
- state1.bytesProcessed = 999;
52
-
53
- // Original should be unchanged
54
- const state2 = stream.getCurrentState();
55
- expect(state2.state[0]).not.toBe(0);
56
- expect(state2.bytesProcessed).not.toBe(999);
57
- });
58
- });
59
-
60
- describe('getBytesProcessed()', () => {
61
- test('should return 0 for new instance', () => {
62
- const stream = new MD5Stream();
63
- expect(stream.getBytesProcessed()).toBe(0);
64
- });
65
-
66
- test('should increment with data chunks', () => {
67
- const stream = new MD5Stream();
68
-
69
- expect(stream.getBytesProcessed()).toBe(0);
70
- stream.write('ab');
71
- expect(stream.getBytesProcessed()).toBe(2);
72
- stream.write('cd');
73
- expect(stream.getBytesProcessed()).toBe(4);
74
- });
75
-
76
- test('should not include pending buffer bytes', () => {
77
- const stream = new MD5Stream();
78
-
79
- // Write partial block (less than 64 bytes)
80
- const partial = 'a'.repeat(32);
81
- stream.write(partial);
82
-
83
- // Should count exact bytes written
84
- expect(stream.getBytesProcessed()).toBe(32);
85
- });
86
- });
87
-
88
- describe('reset()', () => {
89
- test('should reset state to initial values', () => {
90
- const stream = new MD5Stream();
91
- stream.write('test data that will be reset');
92
-
93
- stream.reset();
94
-
95
- const state = stream.getCurrentState();
96
- expect(state.state[0]).toBe(1732584193);
97
- expect(state.bytesProcessed).toBe(0);
98
- });
99
-
100
- test('should allow reusing stream after reset', (done) => {
101
- const stream = new MD5Stream();
102
- let firstDone = false;
103
- let secondDone = false;
104
-
105
- stream.on('md5', (result) => {
106
- if (!firstDone) {
107
- // First computation complete
108
- expect(result.digest).toBe(md5Core('first'));
109
- expect(result.bytesProcessed).toBe(5);
110
- firstDone = true;
111
-
112
- // Reset the stream state
113
- stream.reset();
114
-
115
- // Now we need to write new data
116
- // But stream is already ended, so we can't use it
117
- // This test verifies that reset() clears the internal state
118
- // For full reuse, you need to create a new stream
119
- } else if (!secondDone) {
120
- // Second computation would be on a fresh stream
121
- secondDone = true;
122
- }
123
- });
124
-
125
- stream.write('first');
126
- stream.end();
127
-
128
- // Verify reset worked by checking state is cleared
129
- setTimeout(() => {
130
- const state = stream.getCurrentState();
131
- expect(state.bytesProcessed).toBe(0);
132
- done();
133
- }, 100);
134
- });
135
- });
136
- });
137
-
138
- describe('MD5Stream - Edge Cases', () => {
139
- describe('Empty and Zero-length Data', () => {
140
- test('should handle completely empty stream', (done) => {
141
- const stream = new MD5Stream();
142
-
143
- stream.on('md5', (result) => {
144
- expect(result.digest).toBe(md5Core(''));
145
- expect(result.bytesProcessed).toBe(0);
146
- done();
147
- });
148
-
149
- stream.end();
150
- });
151
-
152
- test('should handle stream with only empty writes', (done) => {
153
- const stream = new MD5Stream();
154
-
155
- stream.on('md5', (result) => {
156
- expect(result.digest).toBe(md5Core(''));
157
- expect(result.bytesProcessed).toBe(0);
158
- done();
159
- });
160
-
161
- stream.write('');
162
- stream.write('');
163
- stream.end();
164
- });
165
-
166
- test('should handle mix of empty and non-empty writes', (done) => {
167
- const stream = new MD5Stream();
168
- const input = 'test';
169
-
170
- stream.on('md5', (result) => {
171
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
172
- expect(result.bytesProcessed).toBe(4);
173
- done();
174
- });
175
-
176
- stream.write('');
177
- stream.write('te');
178
- stream.write('');
179
- stream.write('st');
180
- stream.write('');
181
- stream.end();
182
- });
183
- });
184
-
185
- describe('Single Byte Processing', () => {
186
- test('should handle single byte string', (done) => {
187
- const stream = new MD5Stream();
188
-
189
- stream.on('md5', (result) => {
190
- expect(result.digest).toBe(md5Core('a'));
191
- expect(result.bytesProcessed).toBe(1);
192
- done();
193
- });
194
-
195
- stream.write('a');
196
- stream.end();
197
- });
198
-
199
- test('should handle single byte buffer', (done) => {
200
- const stream = new MD5Stream();
201
-
202
- stream.on('md5', (result) => {
203
- expect(result.digest).toBe(md5Core('x'));
204
- expect(result.bytesProcessed).toBe(1);
205
- done();
206
- });
207
-
208
- stream.write(Buffer.from('x'));
209
- stream.end();
210
- });
211
-
212
- test('should process 64 single-byte chunks correctly', (done) => {
213
- const stream = new MD5Stream();
214
- const input = Array(64).fill('a').join('');
215
-
216
- stream.on('md5', (result) => {
217
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
218
- expect(result.bytesProcessed).toBe(64);
219
- done();
220
- });
221
-
222
- for (let i = 0; i < 64; i++) {
223
- stream.write('a');
224
- }
225
- stream.end();
226
- });
227
- });
228
-
229
- describe('Boundary Conditions', () => {
230
- test('should handle exactly 64 bytes (one block)', (done) => {
231
- const stream = new MD5Stream();
232
- const input = 'a'.repeat(64);
233
-
234
- stream.on('md5', (result) => {
235
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
236
- expect(result.bytesProcessed).toBe(64);
237
- done();
238
- });
239
-
240
- stream.end(input);
241
- });
242
-
243
- test('should handle exactly 128 bytes (two blocks)', (done) => {
244
- const stream = new MD5Stream();
245
- const input = 'a'.repeat(128);
246
-
247
- stream.on('md5', (result) => {
248
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
249
- expect(result.bytesProcessed).toBe(128);
250
- done();
251
- });
252
-
253
- stream.end(input);
254
- });
255
-
256
- test('should handle 63 bytes (one byte short of block)', (done) => {
257
- const stream = new MD5Stream();
258
- const input = 'a'.repeat(63);
259
-
260
- stream.on('md5', (result) => {
261
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
262
- expect(result.bytesProcessed).toBe(63);
263
- done();
264
- });
265
-
266
- stream.end(input);
267
- });
268
-
269
- test('should handle 65 bytes (one byte over block)', (done) => {
270
- const stream = new MD5Stream();
271
- const input = 'a'.repeat(65);
272
-
273
- stream.on('md5', (result) => {
274
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
275
- expect(result.bytesProcessed).toBe(65);
276
- done();
277
- });
278
-
279
- stream.end(input);
280
- });
281
-
282
- test('should handle 127 bytes (one byte short of 2 blocks)', (done) => {
283
- const stream = new MD5Stream();
284
- const input = 'a'.repeat(127);
285
-
286
- stream.on('md5', (result) => {
287
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
288
- expect(result.bytesProcessed).toBe(127);
289
- done();
290
- });
291
-
292
- stream.end(input);
293
- });
294
-
295
- test('should handle 129 bytes (one byte over 2 blocks)', (done) => {
296
- const stream = new MD5Stream();
297
- const input = 'a'.repeat(129);
298
-
299
- stream.on('md5', (result) => {
300
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
301
- expect(result.bytesProcessed).toBe(129);
302
- done();
303
- });
304
-
305
- stream.end(input);
306
- });
307
- });
308
-
309
- describe('Very Large Data', () => {
310
- test('should handle 1MB of data', (done) => {
311
- const stream = new MD5Stream();
312
- const size = 1024 * 1024; // 1MB
313
- const input = 'a'.repeat(size);
314
-
315
- stream.on('md5', (result) => {
316
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
317
- expect(result.bytesProcessed).toBe(size);
318
- done();
319
- });
320
-
321
- stream.end(input);
322
- }, 10000);
323
-
324
- test('should handle 10MB of data', (done) => {
325
- const stream = new MD5Stream();
326
- const size = 10 * 1024 * 1024; // 10MB
327
- const input = 'a'.repeat(size);
328
-
329
- stream.on('md5', (result) => {
330
- expect(result.bytesProcessed).toBe(size);
331
- expect(result.digest.length).toBe(32);
332
- done();
333
- });
334
-
335
- stream.end(input);
336
- }, 30000);
337
- });
338
- });
339
-
340
- describe('MD5Stream - State Management', () => {
341
- test('should maintain state across multiple chunks', (done) => {
342
- const stream = new MD5Stream();
343
- const input = 'The quick brown fox jumps over the lazy dog';
344
- const chunks = [
345
- 'The qu',
346
- 'ick bro',
347
- 'wn fox ju',
348
- 'mps over ',
349
- 'the lazy d',
350
- 'og'
351
- ];
352
-
353
- stream.on('md5', (result) => {
354
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
355
- expect(result.bytesProcessed).toBe(input.length);
356
- done();
357
- });
358
-
359
- chunks.forEach(chunk => stream.write(chunk));
360
- stream.end();
361
- });
362
-
363
- test('should maintain state with alternating chunk sizes', (done) => {
364
- const stream = new MD5Stream();
365
- const input = 'abcdefghijklmnopqrstuvwxyz';
366
-
367
- stream.on('md5', (result) => {
368
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
369
- expect(result.bytesProcessed).toBe(26);
370
- done();
371
- });
372
-
373
- // Alternating very small and larger chunks
374
- stream.write('ab');
375
- stream.write('cdefghijklmnop');
376
- stream.write('qr');
377
- stream.write('stuvwxyz');
378
- stream.end();
379
- });
380
- });
381
-
382
- describe('MD5Stream - Custom Options', () => {
383
- test('should work with custom add32 function', (done) => {
384
- const customAdd32 = (x: number, y: number): number => {
385
- // Custom implementation that matches standard behavior
386
- return ((x + y) & 0xffffffff);
387
- };
388
-
389
- const stream = new MD5Stream({ add32: customAdd32 });
390
- const input = 'custom add32 test string';
391
-
392
- stream.on('md5', (result) => {
393
- // Should produce same result as default add32
394
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
395
- expect(result.bytesProcessed).toBe(input.length);
396
- done();
397
- });
398
-
399
- stream.end(input);
400
- });
401
- });
402
-
403
- describe('MD5Stream - Factory Functions', () => {
404
- test('createMD5Stream should return valid instance', () => {
405
- const stream = createMD5Stream();
406
- expect(stream).toBeInstanceOf(MD5Stream);
407
- expect(stream.getCurrentState().bytesProcessed).toBe(0);
408
- });
409
-
410
- test('createMD5Stream should support options', () => {
411
- const customAdd32 = (x: number, y: number): number => (x + y) & 0xffffffff;
412
- const stream = createMD5Stream({ add32: customAdd32 });
413
-
414
- expect(stream).toBeInstanceOf(MD5Stream);
415
- expect(stream.getCurrentState().bytesProcessed).toBe(0);
416
- });
417
- });
418
-
419
- describe('MD5Stream - Special Characters', () => {
420
- test('should handle null bytes', (done) => {
421
- const stream = new MD5Stream();
422
- const input = 'a\0b\0c\0d';
423
-
424
- stream.on('md5', (result) => {
425
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
426
- expect(result.bytesProcessed).toBe(input.length);
427
- done();
428
- });
429
-
430
- stream.end(input);
431
- });
432
-
433
- test('should handle unicode characters', (done) => {
434
- const stream = new MD5Stream();
435
- const input = 'Привет мир 🌍'; // "Hello world" in Russian + emoji
436
-
437
- stream.on('md5', (result) => {
438
- // Stream uses UTF-8 encoding for strings (via Node.js Buffer)
439
- // Expected hash is MD5 of UTF-8 bytes
440
- expect(result.digest).toBe('c3f46b3563baa69fc33b2830242e11b1'); // MD5 of UTF-8 bytes
441
- // bytesProcessed is UTF-8 byte length (24 bytes for this string)
442
- expect(result.bytesProcessed).toBe(24); // UTF-8 byte length
443
- done();
444
- });
445
-
446
- stream.end(input);
447
- });
448
-
449
- test('should handle control characters', (done) => {
450
- const stream = new MD5Stream();
451
- const input = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f';
452
-
453
- stream.on('md5', (result) => {
454
- expect(result.digest).toBe(md5Core(input)); // MD5 of string using charCodeAt (matches Node.js string encoding)
455
- expect(result.bytesProcessed).toBe(16);
456
- done();
457
- });
458
-
459
- stream.end(input);
460
- });
461
- });