use verit::{codegen, Dt, SchemaBuilder};
fn schema() -> verit::Schema {
SchemaBuilder::new()
.add_enum("Level", vec![(0, "Debug"), (1, "Info"), (2, "Error")])
.add_dense_struct("Point", vec![(1, "x", Dt::F64), (2, "y", Dt::F64)])
.add_struct(
"Order",
vec![
(1, "id", Dt::U64),
(2, "item", Dt::Str),
(3, "qty", Dt::U32),
(4, "tags", Dt::list(Dt::Str)),
(5, "origin", Dt::named("Point")),
(6, "level", Dt::named("Level")),
(7, "blob", Dt::Bytes),
(8, "grid", Dt::list(Dt::list(Dt::U16))),
],
)
.build("Order")
.unwrap()
}
fn canonical_decimals(schema: &verit::Schema) -> String {
schema
.canonical_bytes()
.iter()
.map(|b| b.to_string())
.collect::<Vec<_>>()
.join(", ")
}
#[test]
fn every_emitter_embeds_the_schema_id_and_canonical_bytes() {
let s = schema();
let id = format!("{:032x}", s.id());
let decimals = canonical_decimals(&s);
for (lang, code) in [
("ts", codegen::generate_ts(&s).unwrap()),
("go", codegen::generate_go(&s).unwrap()),
("cpp", codegen::generate_cpp(&s).unwrap()),
("python", codegen::generate_python(&s).unwrap()),
] {
assert!(code.contains(&id), "{lang}: missing schema id {id}");
assert!(
code.contains(&decimals),
"{lang}: missing canonical schema bytes"
);
assert!(code.contains("Point"), "{lang}: missing Point");
assert!(code.contains("Order"), "{lang}: missing Order");
let lower = code.to_lowercase();
for f in [
"id", "item", "qty", "tags", "origin", "level", "blob", "grid",
] {
assert!(lower.contains(f), "{lang}: missing field {f}");
}
}
}
#[test]
fn emitters_are_deterministic() {
let s = schema();
assert_eq!(
codegen::generate_ts(&s).unwrap(),
codegen::generate_ts(&s).unwrap()
);
assert_eq!(
codegen::generate_go(&s).unwrap(),
codegen::generate_go(&s).unwrap()
);
assert_eq!(
codegen::generate_cpp(&s).unwrap(),
codegen::generate_cpp(&s).unwrap()
);
}
#[test]
fn cpp_defines_nested_structs_before_they_are_used_by_value() {
let code = codegen::generate_cpp(&schema()).unwrap();
let point_def = code.find("struct Point {").expect("Point defined");
let order_def = code.find("struct Order {").expect("Order defined");
assert!(point_def < order_def, "Point must be defined before Order");
}
#[test]
fn emitters_reject_non_identifier_names() {
let bad = SchemaBuilder::new()
.add_struct("S", vec![(1, "has space", Dt::U8)])
.build("S")
.unwrap();
assert!(codegen::generate_ts(&bad).is_err());
assert!(codegen::generate_go(&bad).is_err());
assert!(codegen::generate_cpp(&bad).is_err());
}