Add more thorough test cases

This commit is contained in:
2026-05-02 17:52:04 -07:00
parent 6912ff37d3
commit 4ee2dcb948
4 changed files with 183 additions and 0 deletions
+91
View File
@@ -394,6 +394,97 @@ mod tests {
let result = builder.write_string(1, "too long");
assert_eq!(result, Err(RotoError::BufferOverflow));
}
#[test]
fn test_protoc_binary_compatibility() {
let data = include_bytes!("../data/test_data.pb");
let acc = ProtoAccessor::new(data).unwrap();
// 1. Varints (Integers, Booleans, Enums)
let (val_i32, type_i32) = acc.get_value(3).expect("i32_val not found");
assert_eq!(type_i32, WireType::Varint);
let (v, _) = read_varint(val_i32).unwrap();
assert_eq!(v, 42);
let (val_b, type_b) = acc.get_value(13).expect("b_val not found");
assert_eq!(type_b, WireType::Varint);
let (v_b, _) = read_varint(val_b).unwrap();
assert_eq!(v_b, 1); // true
let (val_status, type_status) = acc.get_value(16).expect("status not found");
assert_eq!(type_status, WireType::Varint);
let (v_s, _) = read_varint(val_status).unwrap();
assert_eq!(v_s, 1); // ACTIVE
// 2. Length Delimited (Strings, Bytes)
let (val_s, type_s) = acc.get_value(14).expect("s_val not found");
assert_eq!(type_s, WireType::LengthDelimited);
assert_eq!(val_s, "Hello Roto!".as_bytes());
// 3. Fixed Width (Floats)
let (val_f, type_f) = acc.get_value(2).expect("f_val not found");
assert_eq!(type_f, WireType::Fixed32);
let f_val = f32::from_le_bytes(val_f.try_into().expect("Expected 4 bytes for f32"));
assert!((f_val - 2.71828).abs() < 1e-5);
// 4. Repeated Fields
// Note: primitive repeated fields are packed in proto3, so we iterate over the blob
let mut i32_vals = Vec::new();
for item in acc.iter_repeated(17) {
let (blob, _) = item.expect("Failed to decode repeated i32");
let mut cursor = 0;
while cursor < blob.len() {
let (v, len) = read_varint(&blob[cursor..]).unwrap();
i32_vals.push(v);
cursor += len;
}
}
assert_eq!(i32_vals, vec![1, 2, 3, 4, 5]);
let repeated_strings: Vec<_> = acc.iter_repeated(18)
.map(|r| {
let (val, _) = r.expect("Failed to decode repeated string");
std::str::from_utf8(val).expect("Invalid utf8")
})
.collect();
assert_eq!(repeated_strings, vec!["one", "two", "three"]);
let repeated_nested: Vec<_> = acc.iter_repeated(19)
.map(|r| {
let (val, _) = r.expect("Failed to decode repeated nested");
let nested_acc = ProtoAccessor::new(val).unwrap();
let (id_val, _) = nested_acc.get_value(1).expect("Nested id not found");
let (id, _) = read_varint(id_val).unwrap();
id
})
.collect();
assert_eq!(repeated_nested, vec![101, 102]);
// 5. Single Nested Message
let (val_nested, type_nested) = acc.get_value(20).expect("single_nested not found");
assert_eq!(type_nested, WireType::LengthDelimited);
let nested_acc = ProtoAccessor::new(val_nested).unwrap();
let (val_id, _) = nested_acc.get_value(1).expect("Nested id not found");
let (id, _) = read_varint(val_id).unwrap();
assert_eq!(id, 200);
// Validate that fields appear in the expected relative order
let field_numbers: Vec<u32> = acc.fields()
.map(|r| r.expect("Failed to decode field").0.field_number)
.collect();
let essential_fields = [1, 2, 3, 14, 16, 20];
let mut last_field = 0;
let mut found_count = 0;
for &f in &field_numbers {
if essential_fields.contains(&f) {
assert!(f >= last_field, "Fields appeared out of order: {} came after {}", f, last_field);
last_field = f;
found_count += 1;
}
}
assert_eq!(found_count, essential_fields.len());
}
}
pub struct ProtoBuilder<'a> {