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.
- package/README.md +38 -24
- package/dist/adapters/ie11.cjs +1 -2
- package/dist/adapters/ie11.js +1 -2
- package/dist/adapters/node.cjs +1 -2
- package/dist/adapters/node.js +1 -2
- package/dist/adapters/webcrypto.cjs +1 -2
- package/dist/adapters/webcrypto.js +1 -2
- package/dist/index.cjs +1 -2
- package/dist/index.d.ts +149 -5
- package/dist/index.js +3 -2
- package/dist/md5.cjs +1 -0
- package/dist/md5.d.ts +20 -0
- package/dist/md5.js +1 -0
- package/dist/stream/md5-stream.cjs +1 -2
- package/dist/stream/md5-stream.js +1 -2
- package/dist/stream/whatwg-stream.cjs +1 -2
- package/dist/stream/whatwg-stream.js +1 -2
- package/dist/utils/detect.cjs +1 -2
- package/dist/utils/detect.js +3 -2
- package/package.json +10 -15
- package/pure-md5-0.2.1.tgz +0 -0
- package/test-tree-shake.mjs +12 -0
- package/.aliases +0 -19
- package/.bash_profile +0 -12
- package/.bash_prompt +0 -56
- package/.changeset/README.md +0 -32
- package/.changeset/config.json +0 -16
- package/.continue/mcpServers/new-mcp-server.yaml +0 -10
- package/.continue/rules +0 -29
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -35
- package/.github/ISSUE_TEMPLATE/documentation.md +0 -20
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -35
- package/.github/workflows/npm-publish.yml +0 -33
- package/.github/workflows/release.yml +0 -42
- package/CHANGELOG.md +0 -9
- package/CONTRIBUTING.md +0 -203
- package/MIGRATION_GUIDE_STREAMS.md +0 -374
- package/STREAM_API.md +0 -582
- package/STREAM_BENCHMARKS.md +0 -232
- package/STREAM_EXAMPLES.md +0 -669
- package/STREAM_OPTIMIZATION_REPORT.md +0 -136
- package/STREAM_TROUBLESHOOTING.md +0 -537
- package/WEB_CRYPTO_TESTS_SUMMARY.md +0 -140
- package/WHATWG_STREAMS.md +0 -191
- package/__tests__/adapters/node-crypto.test.ts +0 -167
- package/__tests__/adapters/web-crypto-node.test.ts +0 -73
- package/__tests__/adapters/web-crypto.test.ts +0 -195
- package/__tests__/add32.test.ts +0 -33
- package/__tests__/fallback.test.ts +0 -345
- package/__tests__/hex.test.ts +0 -38
- package/__tests__/hex_chr.test.ts +0 -20
- package/__tests__/index.test.ts +0 -87
- package/__tests__/integration/fixtures/test-file.txt +0 -1
- package/__tests__/integration/md5-stream-file.test.ts +0 -293
- package/__tests__/integration/node-crypto-file.test.ts +0 -86
- package/__tests__/integration/web-crypto.test.ts +0 -38
- package/__tests__/md51.test.ts +0 -73
- package/__tests__/md5block.test.ts +0 -61
- package/__tests__/md5cycle.test.ts +0 -48
- package/__tests__/round-functions.test.ts +0 -87
- package/__tests__/stream/fs-utils.test.ts +0 -209
- package/__tests__/stream/md5-stream-edge-cases.test.ts +0 -461
- package/__tests__/stream/md5-stream.test.ts +0 -418
- package/__tests__/stream/whatwg-stream.test.ts +0 -355
- package/__tests__/stream/whatwg-stream.test.ts.bak2 +0 -335
- package/benchmarks/md5-stream.bench.ts +0 -212
- package/benchmarks/whatwg-stream.bench.ts +0 -180
- package/dist/adapters/ie11.cjs.map +0 -1
- package/dist/adapters/ie11.js.map +0 -1
- package/dist/adapters/node.cjs.map +0 -1
- package/dist/adapters/node.js.map +0 -1
- package/dist/adapters/webcrypto.cjs.map +0 -1
- package/dist/adapters/webcrypto.js.map +0 -1
- package/dist/chunk-2YXXFGBV.js +0 -2
- package/dist/chunk-2YXXFGBV.js.map +0 -1
- package/dist/chunk-4KSCMS4Q.js +0 -2
- package/dist/chunk-4KSCMS4Q.js.map +0 -1
- package/dist/chunk-6P2QV5SR.js +0 -4
- package/dist/chunk-6P2QV5SR.js.map +0 -1
- package/dist/chunk-G5WHEAIQ.js +0 -2
- package/dist/chunk-G5WHEAIQ.js.map +0 -1
- package/dist/chunk-H2K353LR.js +0 -2
- package/dist/chunk-H2K353LR.js.map +0 -1
- package/dist/chunk-JKVD5LHZ.js +0 -2
- package/dist/chunk-JKVD5LHZ.js.map +0 -1
- package/dist/chunk-NWQ4N5RX.js +0 -2
- package/dist/chunk-NWQ4N5RX.js.map +0 -1
- package/dist/chunk-PHZ7FTYF.js +0 -2
- package/dist/chunk-PHZ7FTYF.js.map +0 -1
- package/dist/chunk-PNZTVQA7.js +0 -2
- package/dist/chunk-PNZTVQA7.js.map +0 -1
- package/dist/chunk-R4JB5MBR.js +0 -2
- package/dist/chunk-R4JB5MBR.js.map +0 -1
- package/dist/chunk-VFOAY6XI.js +0 -2
- package/dist/chunk-VFOAY6XI.js.map +0 -1
- package/dist/chunk-XB5BQIEX.js +0 -2
- package/dist/chunk-XB5BQIEX.js.map +0 -1
- package/dist/core/index.cjs +0 -2
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -19
- package/dist/core/index.d.ts +0 -19
- package/dist/core/index.js +0 -2
- package/dist/core/index.js.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -84
- package/dist/index.js.map +0 -1
- package/dist/stream/adapter.cjs +0 -2
- package/dist/stream/adapter.cjs.map +0 -1
- package/dist/stream/adapter.d.cts +0 -63
- package/dist/stream/adapter.d.ts +0 -63
- package/dist/stream/adapter.js +0 -2
- package/dist/stream/adapter.js.map +0 -1
- package/dist/stream/fs-utils.cjs +0 -2
- package/dist/stream/fs-utils.cjs.map +0 -1
- package/dist/stream/fs-utils.d.cts +0 -137
- package/dist/stream/fs-utils.d.ts +0 -137
- package/dist/stream/fs-utils.js +0 -2
- package/dist/stream/fs-utils.js.map +0 -1
- package/dist/stream/index.cjs +0 -2
- package/dist/stream/index.cjs.map +0 -1
- package/dist/stream/index.d.cts +0 -4
- package/dist/stream/index.d.ts +0 -4
- package/dist/stream/index.js +0 -2
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/light/index.cjs +0 -2
- package/dist/stream/light/index.cjs.map +0 -1
- package/dist/stream/light/index.d.cts +0 -4
- package/dist/stream/light/index.d.ts +0 -4
- package/dist/stream/light/index.js +0 -2
- package/dist/stream/light/index.js.map +0 -1
- package/dist/stream/md5-stream.cjs.map +0 -1
- package/dist/stream/md5-stream.js.map +0 -1
- package/dist/stream/whatwg-stream.cjs.map +0 -1
- package/dist/stream/whatwg-stream.js.map +0 -1
- package/dist/types-edGoGJ5V.d.cts +0 -42
- package/dist/types-edGoGJ5V.d.ts +0 -42
- package/dist/utils/detect.cjs.map +0 -1
- package/dist/utils/detect.js.map +0 -1
- package/planning/03-optimization-size-tree-shaking/01-es-modules-tree-shaking.md +0 -152
- package/planning/03-optimization-size-tree-shaking/02-consolidate-modules.md +0 -65
- package/planning/03-optimization-size-tree-shaking/03-remove-duplicate-add32.md +0 -93
- package/planning/03-optimization-size-tree-shaking/04-remove-runtime-check.md +0 -102
- package/planning/03-optimization-size-tree-shaking/05-optimize-loops-performance.md +0 -107
- package/planning/03-optimization-size-tree-shaking/06-tsup-formats-configuration.md +0 -227
- package/planning/03-optimization-size-tree-shaking/07-multiple-build-formats.md +0 -228
- package/planning/03-optimization-size-tree-shaking/08-benchmarks-metrics.md +0 -34
- package/planning/03-optimization-size-tree-shaking/MIGRATION_GUIDE.md +0 -260
- package/planning/03-optimization-size-tree-shaking/README.md +0 -173
- package/planning/03-optimization-size-tree-shaking/SUMMARY.md +0 -168
- package/planning/04-adapter-backend/03-backend-web-crypto.md +0 -149
- package/planning/04-adapter-backend/04-backend-node-crypto.md +0 -181
- package/planning/04-adapter-backend/05-backend-pure-js.md +0 -174
- package/planning/04-adapter-backend/06-backend-ie11.md +0 -158
- package/planning/04-adapter-backend/07-detection-environment.md +0 -232
- package/planning/04-adapter-backend/08-detection-backend.md +0 -210
- package/planning/04-adapter-backend/09-adapter-unified.md +0 -255
- package/planning/04-adapter-backend/10-fallback-mechanism.md +0 -333
- package/planning/04-adapter-backend/11-tests-backend-web-crypto.md +0 -191
- package/planning/04-adapter-backend/12-tests-backend-node-crypto.md +0 -222
- package/planning/04-adapter-backend/README.md +0 -45
- package/planning/05-documentation-publishing/01-README-optimization.md +0 -105
- package/planning/05-documentation-publishing/02-VitePress-site-evaluation.md +0 -136
- package/planning/05-documentation-publishing/03-Changeset-setup.md +0 -192
- package/planning/05-documentation-publishing/04-GitHub-templates.md +0 -252
- package/planning/05-documentation-publishing/README.md +0 -22
- package/planning/05-documentation-publishing/STATUS.md +0 -222
- package/planning/prd.md +0 -405
- package/planning/streams/01-create-md5stream-class.md +0 -69
- package/planning/streams/02-create-factory-api.md +0 -65
- package/planning/streams/03-fs-integration.md +0 -37
- package/planning/streams/04-whatwg-streams-support.md +0 -37
- package/planning/streams/05-audit-optimization.md +0 -121
- package/planning/streams/06-comprehensive-tests-docs.md +0 -137
- package/planning/streams/07-architecture-integration.md +0 -38
- package/planning/streams/README.md +0 -98
- 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
|
-
});
|