@layerzerolabs/common-utils-stellar-contracts 0.2.122

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.
@@ -0,0 +1,689 @@
1
+ use crate::{
2
+ buffer_reader::BufferReader, buffer_writer::BufferWriter, bytes_ext::BytesExt,
3
+ tests::test_helper::assert_address_payload_matches,
4
+ };
5
+ use soroban_sdk::{address_payload::AddressPayload, testutils::Address as _, Address, Bytes, BytesN, Env, I256, U256};
6
+
7
+ /// Helper to test U256 write/read roundtrip
8
+ fn test_u256_roundtrip(env: &Env, value: &soroban_sdk::U256) {
9
+ let mut writer = BufferWriter::new(env);
10
+ writer.write_u256(value.clone());
11
+ let bytes = writer.to_bytes();
12
+ assert_eq!(bytes.len(), 32);
13
+
14
+ let mut reader = BufferReader::new(&bytes);
15
+ assert_eq!(reader.read_u256(), *value);
16
+ assert_eq!(reader.remaining_len(), 0);
17
+ }
18
+
19
+ /// Helper to test address write/read roundtrip
20
+ fn test_address_write_roundtrip(env: &Env, address: &Address) {
21
+ let mut writer = BufferWriter::new(env);
22
+ writer.write_address(address);
23
+
24
+ // Address is 33 bytes (1 type + 32 payload)
25
+ let bytes = writer.to_bytes();
26
+ assert_eq!(bytes.len(), 33);
27
+
28
+ let mut reader = BufferReader::new(&bytes);
29
+ assert_eq!(reader.read_address(), *address);
30
+ assert_eq!(reader.remaining_len(), 0);
31
+ }
32
+
33
+ // ============================================
34
+ // constructor tests (new, from_bytes)
35
+ // ============================================
36
+
37
+ #[test]
38
+ fn test_new_buffer_writer() {
39
+ let env = Env::default();
40
+ let writer = BufferWriter::new(&env);
41
+
42
+ assert_eq!(writer.len(), 0);
43
+ assert!(writer.is_empty());
44
+ }
45
+
46
+ #[test]
47
+ fn test_from_bytes() {
48
+ let env = Env::default();
49
+ let initial = Bytes::from_array(&env, &[0x01, 0x02]);
50
+ let mut writer = BufferWriter::from_bytes(initial);
51
+
52
+ writer.write_u8(0x03).write_u16(0x0405);
53
+
54
+ let bytes = writer.to_bytes();
55
+ assert_eq!(bytes.len(), 5);
56
+ assert_eq!(bytes.get(0).unwrap(), 0x01);
57
+ assert_eq!(bytes.get(1).unwrap(), 0x02);
58
+ assert_eq!(bytes.get(2).unwrap(), 0x03);
59
+ assert_eq!(bytes.get(3).unwrap(), 0x04);
60
+ assert_eq!(bytes.get(4).unwrap(), 0x05);
61
+ }
62
+
63
+ #[test]
64
+ fn test_from_bytes_with_large_buffer() {
65
+ let env = Env::default();
66
+ let initial_data: [u8; 100] = core::array::from_fn(|i| i as u8);
67
+ let initial = Bytes::from_array(&env, &initial_data);
68
+ let mut writer = BufferWriter::from_bytes(initial);
69
+
70
+ writer.write_u32(0xDEADBEEF);
71
+
72
+ let bytes = writer.to_bytes();
73
+ assert_eq!(bytes.len(), 104);
74
+ assert_eq!(bytes.get(0).unwrap(), 0);
75
+ assert_eq!(bytes.get(99).unwrap(), 99);
76
+ // Verify appended data
77
+ let mut reader = BufferReader::new(&bytes);
78
+ reader.skip(100);
79
+ assert_eq!(reader.read_u32(), 0xDEADBEEF);
80
+ }
81
+
82
+ #[test]
83
+ fn test_from_bytes_empty() {
84
+ let env = Env::default();
85
+ let empty = Bytes::new(&env);
86
+ let mut writer = BufferWriter::from_bytes(empty);
87
+
88
+ writer.write_u8(0x42);
89
+
90
+ let bytes = writer.to_bytes();
91
+ assert_eq!(bytes.len(), 1);
92
+ assert_eq!(bytes.get(0).unwrap(), 0x42);
93
+ }
94
+
95
+ // ============================================
96
+ // write_primitives tests (u8, u16, u32, u64, u128, i128, u256, bool)
97
+ // ============================================
98
+
99
+ #[test]
100
+ fn test_write_primitives_big_endian_golden_bytes() {
101
+ let env = Env::default();
102
+ let mut writer = BufferWriter::new(&env);
103
+ writer
104
+ .write_u8(0x12)
105
+ .write_u16(0x3456)
106
+ .write_u32(0x789ABCDE)
107
+ .write_u64(0x0102030405060708)
108
+ .write_u128(0x0102030405060708090a0b0c0d0e0f10);
109
+
110
+ let bytes = writer.to_bytes();
111
+ let got: [u8; 31] = bytes.to_array();
112
+
113
+ let expected: [u8; 31] = [
114
+ 0x12, // u8
115
+ 0x34, 0x56, // u16
116
+ 0x78, 0x9A, 0xBC, 0xDE, // u32
117
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // u64
118
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, // u128
119
+ ];
120
+ assert_eq!(got, expected);
121
+ }
122
+
123
+ #[test]
124
+ fn test_write_signed_integers_big_endian_golden_bytes() {
125
+ let env = Env::default();
126
+ let mut writer = BufferWriter::new(&env);
127
+
128
+ writer
129
+ .write_i8(-1)
130
+ .write_i8(i8::MIN)
131
+ .write_i8(i8::MAX)
132
+ .write_i16(-1)
133
+ .write_i16(i16::MIN)
134
+ .write_i16(i16::MAX)
135
+ .write_i32(-1)
136
+ .write_i32(i32::MIN)
137
+ .write_i32(i32::MAX)
138
+ .write_i64(-1)
139
+ .write_i64(i64::MIN)
140
+ .write_i64(i64::MAX)
141
+ .write_i128(-1)
142
+ .write_i128(i128::MIN)
143
+ .write_i128(i128::MAX);
144
+
145
+ let bytes = writer.to_bytes();
146
+ assert_eq!(bytes.len(), 93);
147
+ let got: [u8; 93] = bytes.to_array();
148
+
149
+ // Layout:
150
+ // - i8: -1, MIN, MAX (3 bytes)
151
+ // - i16: -1, MIN, MAX (6 bytes)
152
+ // - i32: -1, MIN, MAX (12 bytes)
153
+ // - i64: -1, MIN, MAX (24 bytes)
154
+ // - i128: -1, MIN, MAX (48 bytes)
155
+ // Total = 93 bytes
156
+ let mut expected = [0u8; 93];
157
+ let mut pos = 0usize;
158
+
159
+ expected[pos] = (-1i8) as u8;
160
+ pos += 1;
161
+ expected[pos] = i8::MIN as u8;
162
+ pos += 1;
163
+ expected[pos] = i8::MAX as u8;
164
+ pos += 1;
165
+
166
+ expected[pos..pos + 2].copy_from_slice(&(-1i16).to_be_bytes());
167
+ pos += 2;
168
+ expected[pos..pos + 2].copy_from_slice(&i16::MIN.to_be_bytes());
169
+ pos += 2;
170
+ expected[pos..pos + 2].copy_from_slice(&i16::MAX.to_be_bytes());
171
+ pos += 2;
172
+
173
+ expected[pos..pos + 4].copy_from_slice(&(-1i32).to_be_bytes());
174
+ pos += 4;
175
+ expected[pos..pos + 4].copy_from_slice(&i32::MIN.to_be_bytes());
176
+ pos += 4;
177
+ expected[pos..pos + 4].copy_from_slice(&i32::MAX.to_be_bytes());
178
+ pos += 4;
179
+
180
+ expected[pos..pos + 8].copy_from_slice(&(-1i64).to_be_bytes());
181
+ pos += 8;
182
+ expected[pos..pos + 8].copy_from_slice(&i64::MIN.to_be_bytes());
183
+ pos += 8;
184
+ expected[pos..pos + 8].copy_from_slice(&i64::MAX.to_be_bytes());
185
+ pos += 8;
186
+
187
+ expected[pos..pos + 16].copy_from_slice(&(-1i128).to_be_bytes());
188
+ pos += 16;
189
+ expected[pos..pos + 16].copy_from_slice(&i128::MIN.to_be_bytes());
190
+ pos += 16;
191
+ expected[pos..pos + 16].copy_from_slice(&i128::MAX.to_be_bytes());
192
+ pos += 16;
193
+
194
+ assert_eq!(pos, expected.len());
195
+ assert_eq!(got, expected);
196
+ }
197
+
198
+ #[test]
199
+ fn test_write_signed_integers_roundtrip() {
200
+ let env = Env::default();
201
+ let mut writer = BufferWriter::new(&env);
202
+
203
+ writer
204
+ .write_i8(0)
205
+ .write_i8(-1)
206
+ .write_i8(i8::MIN)
207
+ .write_i8(i8::MAX)
208
+ .write_i16(0)
209
+ .write_i16(-42)
210
+ .write_i16(i16::MIN)
211
+ .write_i16(i16::MAX)
212
+ .write_i32(0)
213
+ .write_i32(-42)
214
+ .write_i32(i32::MIN)
215
+ .write_i32(i32::MAX)
216
+ .write_i64(0)
217
+ .write_i64(-42)
218
+ .write_i64(i64::MIN)
219
+ .write_i64(i64::MAX)
220
+ .write_i128(0)
221
+ .write_i128(-42)
222
+ .write_i128(123_456_789)
223
+ .write_i128(i128::MIN)
224
+ .write_i128(i128::MAX);
225
+
226
+ let bytes = writer.to_bytes();
227
+ let mut reader = BufferReader::new(&bytes);
228
+
229
+ assert_eq!(reader.read_i8(), 0);
230
+ assert_eq!(reader.read_i8(), -1);
231
+ assert_eq!(reader.read_i8(), i8::MIN);
232
+ assert_eq!(reader.read_i8(), i8::MAX);
233
+
234
+ assert_eq!(reader.read_i16(), 0);
235
+ assert_eq!(reader.read_i16(), -42);
236
+ assert_eq!(reader.read_i16(), i16::MIN);
237
+ assert_eq!(reader.read_i16(), i16::MAX);
238
+
239
+ assert_eq!(reader.read_i32(), 0);
240
+ assert_eq!(reader.read_i32(), -42);
241
+ assert_eq!(reader.read_i32(), i32::MIN);
242
+ assert_eq!(reader.read_i32(), i32::MAX);
243
+
244
+ assert_eq!(reader.read_i64(), 0);
245
+ assert_eq!(reader.read_i64(), -42);
246
+ assert_eq!(reader.read_i64(), i64::MIN);
247
+ assert_eq!(reader.read_i64(), i64::MAX);
248
+
249
+ assert_eq!(reader.read_i128(), 0);
250
+ assert_eq!(reader.read_i128(), -42);
251
+ assert_eq!(reader.read_i128(), 123_456_789);
252
+ assert_eq!(reader.read_i128(), i128::MIN);
253
+ assert_eq!(reader.read_i128(), i128::MAX);
254
+ assert_eq!(reader.remaining_len(), 0);
255
+ }
256
+
257
+ #[test]
258
+ fn test_write_i256_big_endian_golden_bytes_and_roundtrip() {
259
+ let env = Env::default();
260
+
261
+ // Golden layouts: -1, MIN, MAX, +1
262
+ let mut raw = [0u8; 32 * 4];
263
+ raw[0..32].copy_from_slice(&[0xFF; 32]); // -1
264
+ raw[32] = 0x80; // MIN (0x80 followed by 31x 0x00)
265
+ raw[64] = 0x7F; // MAX (0x7F followed by 31x 0xFF)
266
+ raw[65..96].copy_from_slice(&[0xFF; 31]);
267
+ raw[127] = 0x01; // +1
268
+
269
+ let expected_neg1 = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[0..32]));
270
+ let expected_min = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[32..64]));
271
+ let expected_max = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[64..96]));
272
+ let expected_one = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[96..128]));
273
+
274
+ let mut writer = BufferWriter::new(&env);
275
+ writer.write_i256(expected_neg1).write_i256(expected_min).write_i256(expected_max).write_i256(expected_one);
276
+
277
+ let bytes = writer.to_bytes();
278
+ assert_eq!(bytes.len(), 128);
279
+ let got: [u8; 128] = bytes.to_array();
280
+ assert_eq!(got, raw);
281
+
282
+ // Roundtrip through BufferReader.
283
+ let mut reader = BufferReader::new(&bytes);
284
+ let roundtrip_neg1 = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[0..32]));
285
+ let roundtrip_min = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[32..64]));
286
+ let roundtrip_max = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[64..96]));
287
+ let roundtrip_one = I256::from_be_bytes(&env, &Bytes::from_slice(&env, &raw[96..128]));
288
+
289
+ assert_eq!(reader.read_i256(), roundtrip_neg1);
290
+ assert_eq!(reader.read_i256(), roundtrip_min);
291
+ assert_eq!(reader.read_i256(), roundtrip_max);
292
+ assert_eq!(reader.read_i256(), roundtrip_one);
293
+ assert_eq!(reader.remaining_len(), 0);
294
+ }
295
+
296
+ #[test]
297
+ fn test_write_primitives_roundtrip() {
298
+ let env = Env::default();
299
+ let mut writer = BufferWriter::new(&env);
300
+
301
+ writer
302
+ .write_u8(0x12)
303
+ .write_u16(0x3456)
304
+ .write_u32(0x789ABCDE)
305
+ .write_u64(0x0102030405060708)
306
+ .write_u128(0x10111213141516171819_1a1b1c1d1e1f);
307
+
308
+ let bytes = writer.to_bytes();
309
+ // 1 + 2 + 4 + 8 + 16 = 31
310
+ assert_eq!(bytes.len(), 31);
311
+
312
+ // Verify with reader
313
+ let mut reader = BufferReader::new(&bytes);
314
+ assert_eq!(reader.read_u8(), 0x12);
315
+ assert_eq!(reader.read_u16(), 0x3456);
316
+ assert_eq!(reader.read_u32(), 0x789ABCDE);
317
+ assert_eq!(reader.read_u64(), 0x0102030405060708);
318
+ assert_eq!(reader.read_u128(), 0x10111213141516171819_1a1b1c1d1e1f);
319
+ }
320
+
321
+ #[test]
322
+ fn test_write_boundary_values() {
323
+ let env = Env::default();
324
+ let mut writer = BufferWriter::new(&env);
325
+
326
+ writer
327
+ .write_u8(0)
328
+ .write_u8(u8::MAX)
329
+ .write_u16(0)
330
+ .write_u16(u16::MAX)
331
+ .write_u32(0)
332
+ .write_u32(u32::MAX)
333
+ .write_u64(0)
334
+ .write_u64(u64::MAX)
335
+ .write_u128(0)
336
+ .write_u128(u128::MAX);
337
+
338
+ let bytes = writer.to_bytes();
339
+ let mut reader = BufferReader::new(&bytes);
340
+
341
+ assert_eq!(reader.read_u8(), 0);
342
+ assert_eq!(reader.read_u8(), u8::MAX);
343
+ assert_eq!(reader.read_u16(), 0);
344
+ assert_eq!(reader.read_u16(), u16::MAX);
345
+ assert_eq!(reader.read_u32(), 0);
346
+ assert_eq!(reader.read_u32(), u32::MAX);
347
+ assert_eq!(reader.read_u64(), 0);
348
+ assert_eq!(reader.read_u64(), u64::MAX);
349
+ assert_eq!(reader.read_u128(), 0);
350
+ assert_eq!(reader.read_u128(), u128::MAX);
351
+ }
352
+
353
+ #[test]
354
+ fn test_write_bool() {
355
+ let env = Env::default();
356
+ let mut writer = BufferWriter::new(&env);
357
+
358
+ writer.write_bool(true).write_bool(false).write_bool(true);
359
+
360
+ let bytes = writer.to_bytes();
361
+ assert_eq!(bytes.len(), 3);
362
+
363
+ let mut reader = BufferReader::new(&bytes);
364
+ assert!(reader.read_bool());
365
+ assert!(!reader.read_bool());
366
+ assert!(reader.read_bool());
367
+ }
368
+
369
+ #[test]
370
+ fn test_write_u256_boundary_values() {
371
+ use soroban_sdk::U256;
372
+ let env = Env::default();
373
+
374
+ // Zero
375
+ let zero = U256::from_u32(&env, 0);
376
+ test_u256_roundtrip(&env, &zero);
377
+
378
+ // From u128::MAX
379
+ let from_u128_max = U256::from_u128(&env, u128::MAX);
380
+ test_u256_roundtrip(&env, &from_u128_max);
381
+
382
+ // Max (all 0xFF bytes)
383
+ let max_bytes = Bytes::from_array(&env, &[0xFF; 32]);
384
+ let max_u256 = U256::from_be_bytes(&env, &max_bytes);
385
+ test_u256_roundtrip(&env, &max_u256);
386
+ }
387
+
388
+ #[test]
389
+ fn test_write_mixed_sizes_no_alignment_issues() {
390
+ let env = Env::default();
391
+ let mut writer = BufferWriter::new(&env);
392
+
393
+ // Test that byte-packed writes work correctly regardless of "alignment"
394
+ // (Soroban Bytes has no alignment requirements, but this documents the behavior)
395
+ writer
396
+ .write_u8(0x01)
397
+ .write_u64(0x0203040506070809)
398
+ .write_u8(0x0A)
399
+ .write_u128(0x0B0C0D0E0F101112131415161718191A)
400
+ .write_u8(0x1B);
401
+
402
+ assert_eq!(writer.len(), 1 + 8 + 1 + 16 + 1); // 27 bytes
403
+
404
+ let bytes = writer.to_bytes();
405
+ let mut reader = BufferReader::new(&bytes);
406
+ assert_eq!(reader.read_u8(), 0x01);
407
+ assert_eq!(reader.read_u64(), 0x0203040506070809);
408
+ assert_eq!(reader.read_u8(), 0x0A);
409
+ assert_eq!(reader.read_u128(), 0x0B0C0D0E0F101112131415161718191A);
410
+ assert_eq!(reader.read_u8(), 0x1B);
411
+ assert_eq!(reader.remaining_len(), 0);
412
+ }
413
+
414
+ // ============================================
415
+ // write_bytes tests (write_bytes, write_bytes_n)
416
+ // ============================================
417
+
418
+ #[test]
419
+ fn test_write_bytes() {
420
+ let env = Env::default();
421
+ let mut writer = BufferWriter::new(&env);
422
+
423
+ let data = Bytes::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
424
+ writer.write_bytes(&data);
425
+
426
+ let bytes = writer.to_bytes();
427
+ assert_eq!(bytes.len(), 4);
428
+ assert_eq!(bytes.get(0).unwrap(), 0x01);
429
+ assert_eq!(bytes.get(3).unwrap(), 0x04);
430
+ }
431
+
432
+ #[test]
433
+ fn test_write_bytes_empty() {
434
+ let env = Env::default();
435
+ let mut writer = BufferWriter::new(&env);
436
+
437
+ let empty = Bytes::new(&env);
438
+ writer.write_bytes(&empty);
439
+
440
+ let bytes = writer.to_bytes();
441
+ assert_eq!(bytes.len(), 0);
442
+ }
443
+
444
+ #[test]
445
+ fn test_write_bytes_n() {
446
+ let env = Env::default();
447
+ let mut writer = BufferWriter::new(&env);
448
+
449
+ let bytes4 = BytesN::<4>::from_array(&env, &[0x01, 0x02, 0x03, 0x04]);
450
+ let bytes8 = BytesN::<8>::from_array(&env, &[0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c]);
451
+ let bytes32 = BytesN::<32>::from_array(&env, &[0x42; 32]);
452
+
453
+ writer.write_bytes_n(&bytes4).write_bytes_n(&bytes8).write_bytes_n(&bytes32);
454
+
455
+ let bytes = writer.to_bytes();
456
+ assert_eq!(bytes.len(), 4 + 8 + 32);
457
+
458
+ let mut reader = BufferReader::new(&bytes);
459
+ assert_eq!(reader.read_bytes_n::<4>(), bytes4);
460
+ assert_eq!(reader.read_bytes_n::<8>(), bytes8);
461
+ assert_eq!(reader.read_bytes_n::<32>(), bytes32);
462
+ }
463
+
464
+ #[test]
465
+ fn test_write_bytes_n_array() {
466
+ let env = Env::default();
467
+ let mut writer = BufferWriter::new(&env);
468
+ let bytes = writer.write_array(&[0x01, 0x02, 0x03, 0x04]).to_bytes();
469
+ assert_eq!(bytes.len(), 4);
470
+ assert_eq!(bytes.get(0).unwrap(), 0x01);
471
+ assert_eq!(bytes.get(3).unwrap(), 0x04);
472
+ }
473
+
474
+ // ============================================
475
+ // write_address tests
476
+ // ============================================
477
+
478
+ #[test]
479
+ fn test_write_address_contract() {
480
+ let env = Env::default();
481
+ let address = Address::generate(&env);
482
+ let payload = address.to_payload().unwrap();
483
+ assert!(matches!(payload, AddressPayload::ContractIdHash(_)));
484
+ test_address_write_roundtrip(&env, &address);
485
+ }
486
+
487
+ #[test]
488
+ fn test_write_address_account() {
489
+ let env = Env::default();
490
+ let account_payload = BytesN::<32>::from_array(&env, &[0x42; 32]);
491
+ let address = Address::from_payload(&env, AddressPayload::AccountIdPublicKeyEd25519(account_payload));
492
+ let payload = address.to_payload().unwrap();
493
+ assert!(matches!(payload, AddressPayload::AccountIdPublicKeyEd25519(_)));
494
+ test_address_write_roundtrip(&env, &address);
495
+ }
496
+
497
+ #[test]
498
+ fn test_write_multiple_addresses() {
499
+ let env = Env::default();
500
+ let mut writer = BufferWriter::new(&env);
501
+
502
+ let addr1 = Address::generate(&env);
503
+ let addr2 = Address::generate(&env);
504
+ let addr3 = Address::generate(&env);
505
+
506
+ writer.write_address(&addr1).write_address(&addr2).write_address(&addr3);
507
+
508
+ let bytes = writer.to_bytes();
509
+ assert_eq!(bytes.len(), 99); // 33 * 3
510
+
511
+ let mut reader = BufferReader::new(&bytes);
512
+ assert_eq!(reader.read_address(), addr1);
513
+ assert_eq!(reader.read_address(), addr2);
514
+ assert_eq!(reader.read_address(), addr3);
515
+ }
516
+
517
+ // ============================================
518
+ // write_address_payload tests
519
+ // ============================================
520
+
521
+ #[test]
522
+ fn test_write_address_payload() {
523
+ let env = Env::default();
524
+ let address = Address::generate(&env);
525
+ let expected_payload = address.to_payload().unwrap();
526
+
527
+ let mut writer = BufferWriter::new(&env);
528
+ writer.write_address_payload(&address);
529
+ let bytes = writer.to_bytes();
530
+
531
+ // Verify it's exactly 32 bytes (no type byte)
532
+ assert_eq!(bytes.len(), 32);
533
+
534
+ // Verify the payload matches
535
+ let mut reader = BufferReader::new(&bytes);
536
+ let payload = reader.read_address_payload();
537
+ assert_address_payload_matches(payload, expected_payload);
538
+ assert_eq!(reader.remaining_len(), 0);
539
+ }
540
+
541
+ #[test]
542
+ fn test_write_address_payload_with_other_data() {
543
+ let env = Env::default();
544
+ let address = Address::generate(&env);
545
+
546
+ let mut writer = BufferWriter::new(&env);
547
+ writer.write_u32(0x12345678).write_address_payload(&address).write_u64(0xAABBCCDDEEFF0011);
548
+ let bytes = writer.to_bytes();
549
+
550
+ assert_eq!(bytes.len(), 4 + 32 + 8); // u32 + payload (32) + u64
551
+
552
+ let mut reader = BufferReader::new(&bytes);
553
+ assert_eq!(reader.read_u32(), 0x12345678);
554
+ let payload = reader.read_address_payload();
555
+ assert_address_payload_matches(payload, address.to_payload().unwrap());
556
+ assert_eq!(reader.read_u64(), 0xAABBCCDDEEFF0011);
557
+ assert_eq!(reader.remaining_len(), 0);
558
+ }
559
+
560
+ // ============================================
561
+ // chaining tests
562
+ // ============================================
563
+
564
+ #[test]
565
+ fn test_chaining_empty_bytes() {
566
+ let env = Env::default();
567
+ let mut writer = BufferWriter::new(&env);
568
+
569
+ let empty = Bytes::new(&env);
570
+ writer.write_bytes(&empty).write_u8(0x42).write_bytes(&empty);
571
+
572
+ let bytes = writer.to_bytes();
573
+ assert_eq!(bytes.len(), 1); // Only the u8
574
+ assert_eq!(bytes.get(0).unwrap(), 0x42);
575
+ }
576
+
577
+ // ============================================
578
+ // buffer_access tests (len, is_empty, env)
579
+ // ============================================
580
+
581
+ #[test]
582
+ fn test_len_after_writes() {
583
+ let env = Env::default();
584
+ let mut writer = BufferWriter::new(&env);
585
+
586
+ assert_eq!(writer.len(), 0);
587
+ assert!(writer.is_empty());
588
+
589
+ writer.write_u8(0x01);
590
+ assert_eq!(writer.len(), 1);
591
+ assert!(!writer.is_empty());
592
+
593
+ writer.write_u16(0x0203);
594
+ assert_eq!(writer.len(), 3);
595
+
596
+ writer.write_u32(0x04050607);
597
+ assert_eq!(writer.len(), 7);
598
+ }
599
+
600
+ #[test]
601
+ fn test_env_from_writer() {
602
+ let env = Env::default();
603
+ let writer = BufferWriter::new(&env);
604
+
605
+ // Verify we can use the env reference from the writer
606
+ let _new_bytes = Bytes::from_array(writer.env(), &[0x01, 0x02]);
607
+ }
608
+
609
+ // ============================================
610
+ // complex_roundtrip tests
611
+ // ============================================
612
+
613
+ #[test]
614
+ fn test_complex_message_roundtrip() {
615
+ let env = Env::default();
616
+ let mut writer = BufferWriter::new(&env);
617
+
618
+ // Simulate a complex message structure
619
+ let version: u8 = 1;
620
+ let msg_type: u16 = 0x0102;
621
+ let sender = Address::generate(&env);
622
+ let nonce: u64 = 12345678;
623
+ let amount = U256::from_u128(&env, 1000000000000000000u128);
624
+ let payload = Bytes::from_array(&env, &[0xDE, 0xAD, 0xBE, 0xEF]);
625
+
626
+ writer
627
+ .write_u8(version)
628
+ .write_u16(msg_type)
629
+ .write_address(&sender)
630
+ .write_u64(nonce)
631
+ .write_u256(amount.clone())
632
+ .write_bytes(&payload);
633
+
634
+ let bytes = writer.to_bytes();
635
+
636
+ // Read back and verify
637
+ let mut reader = BufferReader::new(&bytes);
638
+ assert_eq!(reader.read_u8(), version);
639
+ assert_eq!(reader.read_u16(), msg_type);
640
+ assert_eq!(reader.read_address(), sender);
641
+ assert_eq!(reader.read_u64(), nonce);
642
+ assert_eq!(reader.read_u256(), amount);
643
+
644
+ let read_payload = reader.read_bytes(4);
645
+ assert_eq!(read_payload.len(), 4);
646
+ assert_eq!(read_payload.get(0).unwrap(), 0xDE);
647
+ assert_eq!(read_payload.get(3).unwrap(), 0xEF);
648
+ }
649
+
650
+ // ============================================
651
+ // stress_and_edge_case tests
652
+ // ============================================
653
+
654
+ #[test]
655
+ fn test_write_large_buffer() {
656
+ let env = Env::default();
657
+ let mut writer = BufferWriter::new(&env);
658
+
659
+ // Write many items to test buffer growth
660
+ for i in 0..1000u32 {
661
+ writer.write_u32(i);
662
+ }
663
+
664
+ assert_eq!(writer.len(), 4000);
665
+
666
+ // Verify via reader
667
+ let bytes = writer.to_bytes();
668
+ let mut reader = BufferReader::new(&bytes);
669
+ for i in 0..1000u32 {
670
+ assert_eq!(reader.read_u32(), i);
671
+ }
672
+ }
673
+
674
+ #[test]
675
+ fn test_write_repeated_values() {
676
+ let env = Env::default();
677
+ let mut writer = BufferWriter::new(&env);
678
+
679
+ for _ in 0..100 {
680
+ writer.write_u8(0xFF);
681
+ }
682
+
683
+ let bytes = writer.to_bytes();
684
+ assert_eq!(bytes.len(), 100);
685
+
686
+ for i in 0..100 {
687
+ assert_eq!(bytes.get(i).unwrap(), 0xFF);
688
+ }
689
+ }