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
BIN
View File
Binary file not shown.
+39
View File
@@ -0,0 +1,39 @@
d_val: 3.1415926535
f_val: 2.71828
i32_val: 42
i64_val: 123456789012345
u32_val: 1000
u64_val: 18446744073709551615
si32_val: -42
si64_val: -123456789012345
fx32_val: 123456
fx64_val: 1234567890123456789
sfx32_val: -123456
sfx64_val: -1234567890123456789
b_val: true
s_val: "Hello Roto!"
bytes_val: "SGVsbG8gUm90byE="
status: ACTIVE
repeated_i32: 1
repeated_i32: 2
repeated_i32: 3
repeated_i32: 4
repeated_i32: 5
repeated_string: "one"
repeated_string: "two"
repeated_string: "three"
repeated_nested {
id: 101
name: "Nested 1"
active: true
}
repeated_nested {
id: 102
name: "Nested 2"
active: false
}
single_nested {
id: 200
name: "Single Nested"
active: true
}
+53
View File
@@ -0,0 +1,53 @@
syntax = "proto3";
package roto.test;
// A comprehensive message containing all primitive types and complex structures
// to test the proto-to-rust codegen and runtime accessors.
message ComplexMessage {
// --- Floating Point ---
double d_val = 1;
float f_val = 2;
// --- Integers (Variable Length) ---
int32 i32_val = 3;
int64 i64_val = 4;
uint32 u32_val = 5;
uint64 u64_val = 6;
sint32 si32_val = 7;
sint64 si64_val = 8;
// --- Integers (Fixed Length) ---
fixed32 fx32_val = 9;
fixed64 fx64_val = 10;
sfixed32 sfx32_val = 11;
sfixed64 sfx64_val = 12;
// --- Other Primitives ---
bool b_val = 13;
string s_val = 14;
bytes bytes_val = 15;
// --- Enumerations ---
enum Status {
UNKNOWN = 0;
ACTIVE = 1;
INACTIVE = 2;
DELETED = 3;
}
Status status = 16;
// --- Repeated Fields ---
// Testing packed primitives and non-packed types
repeated int32 repeated_i32 = 17;
repeated string repeated_string = 18;
repeated NestedMessage repeated_nested = 19;
// --- Nested Messages ---
message NestedMessage {
int32 id = 1;
string name = 2;
bool active = 3;
}
NestedMessage single_nested = 20;
}
+91
View File
@@ -394,6 +394,97 @@ mod tests {
let result = builder.write_string(1, "too long"); let result = builder.write_string(1, "too long");
assert_eq!(result, Err(RotoError::BufferOverflow)); 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> { pub struct ProtoBuilder<'a> {