Add more thorough test cases
This commit is contained in:
+91
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user