xrpl_common_stdlib/objects/test_utils.rs
1//! Shared mock-host-binding helpers used by the `#[cfg(test)]` blocks that
2//! `tools/generateLedgerObjects.js` emits at the bottom of every
3//! `objects::generated::<entry>` file.
4
5use crate::host::host_bindings_trait::MockHostBindings;
6
7/// Wires `le_field` and `home_le_field` to always succeed:
8/// the output buffer is filled and the call returns the requested buffer length as the
9/// result code. This satisfies both the fixed-size getters (which require the result code
10/// to exactly equal the expected size) and the variable-size getters (which only require a
11/// non-negative result code), so it works uniformly as a "field present" mock for every
12/// getter the generator emits, without a `.with(...)` predicate limiting which
13/// field/slot/call count it applies to.
14///
15/// The first byte is set to `0x80` rather than `0`: for an `Amount` field the decoder reads
16/// the leading bit to pick the wire variant, and only the IOU variant (bit 7 set) has an
17/// expected length equal to the full `AMOUNT_SIZE` buffer this mock reports. A zero lead byte
18/// would parse as XRP (expected length 8) and be rejected against the 48-byte report. Every
19/// other field type ignores the lead byte's value here (they only care about the length), so
20/// `0x80` is a safe uniform fill.
21fn write_present(out_buff_ptr: *mut u8, out_buff_len: usize) {
22 unsafe {
23 core::ptr::write_bytes(out_buff_ptr, 0, out_buff_len);
24 if out_buff_len > 0 {
25 *out_buff_ptr = 0x80;
26 }
27 }
28}
29
30pub fn mock_all_fields_present(mock: &mut MockHostBindings) {
31 mock.expect_le_field()
32 .returning(|_cache_num, _field, out_buff_ptr, out_buff_len| {
33 write_present(out_buff_ptr, out_buff_len);
34 out_buff_len as i32
35 });
36 mock.expect_home_le_field()
37 .returning(|_field, out_buff_ptr, out_buff_len| {
38 write_present(out_buff_ptr, out_buff_len);
39 out_buff_len as i32
40 });
41}
42
43/// Wires `le_field` and `home_le_field` to always report
44/// `FIELD_NOT_FOUND`, regardless of field/slot. Buffers are zero-filled defensively even
45/// though a not-found result usually means the caller doesn't read the buffer.
46pub fn mock_all_fields_not_found(mock: &mut MockHostBindings) {
47 use crate::host::error_codes::FIELD_NOT_FOUND;
48
49 mock.expect_le_field()
50 .returning(|_cache_num, _field, out_buff_ptr, out_buff_len| {
51 unsafe { core::ptr::write_bytes(out_buff_ptr, 0, out_buff_len) };
52 FIELD_NOT_FOUND
53 });
54 mock.expect_home_le_field()
55 .returning(|_field, out_buff_ptr, out_buff_len| {
56 unsafe { core::ptr::write_bytes(out_buff_ptr, 0, out_buff_len) };
57 FIELD_NOT_FOUND
58 });
59}