From 24f5979a4d00f9574a1c8d4b9ad1bc09e81363fc Mon Sep 17 00:00:00 2001 From: Sergei Zharinov Date: Tue, 6 Jan 2026 16:54:18 -0300 Subject: [PATCH] refactor: Use neutral wording in type verification panic messages --- crates/plotnik-lib/src/engine/verify.rs | 42 ++++----- crates/plotnik-lib/src/engine/verify_tests.rs | 88 +++++++++---------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/crates/plotnik-lib/src/engine/verify.rs b/crates/plotnik-lib/src/engine/verify.rs index 7328f61f..53d72045 100644 --- a/crates/plotnik-lib/src/engine/verify.rs +++ b/crates/plotnik-lib/src/engine/verify.rs @@ -12,26 +12,26 @@ use super::Value; /// Debug-only type verification. /// -/// Panics with a pretty diagnostic if the value doesn't match the expected type. +/// Panics with a pretty diagnostic if the value doesn't match the declared type. /// This is a no-op in release builds. /// -/// `expected_type` should be the `result_type` from the entrypoint that was executed. +/// `declared_type` should be the `result_type` from the entrypoint that was executed. #[cfg(debug_assertions)] -pub fn debug_verify_type(value: &Value, expected_type: TypeId, module: &Module, colors: Colors) { +pub fn debug_verify_type(value: &Value, declared_type: TypeId, module: &Module, colors: Colors) { let types = module.types(); let strings = module.strings(); let mut errors = Vec::new(); verify_type( value, - expected_type, + declared_type, &types, &strings, &mut String::new(), &mut errors, ); if !errors.is_empty() { - panic_with_mismatch(value, expected_type, &errors, module, colors); + panic_with_mismatch(value, declared_type, &errors, module, colors); } } @@ -40,7 +40,7 @@ pub fn debug_verify_type(value: &Value, expected_type: TypeId, module: &Module, #[inline(always)] pub fn debug_verify_type( _value: &Value, - _expected_type: TypeId, + _declared_type: TypeId, _module: &Module, _colors: Colors, ) { @@ -50,16 +50,16 @@ pub fn debug_verify_type( #[cfg(debug_assertions)] fn verify_type( value: &Value, - expected: TypeId, + declared: TypeId, types: &TypesView<'_>, strings: &StringsView<'_>, path: &mut String, errors: &mut Vec, ) { - let Some(type_def) = types.get(expected) else { + let Some(type_def) = types.get(declared) else { errors.push(format_error( path, - &format!("unknown type id {}", expected.0), + &format!("unknown type id {}", declared.0), )); return; }; @@ -74,7 +74,7 @@ fn verify_type( if !matches!(value, Value::Null) { errors.push(format_error( path, - &format!("expected void (null), found {}", value_kind_name(value)), + &format!("type: void, value: {}", value_kind_name(value)), )); } } @@ -83,7 +83,7 @@ fn verify_type( if !matches!(value, Value::Node(_)) { errors.push(format_error( path, - &format!("expected Node, found {}", value_kind_name(value)), + &format!("type: Node, value: {}", value_kind_name(value)), )); } } @@ -92,7 +92,7 @@ fn verify_type( if !matches!(value, Value::String(_)) { errors.push(format_error( path, - &format!("expected string, found {}", value_kind_name(value)), + &format!("type: string, value: {}", value_kind_name(value)), )); } } @@ -101,7 +101,7 @@ fn verify_type( if !matches!(value, Value::Node(_)) { errors.push(format_error( path, - &format!("expected Node (alias), found {}", value_kind_name(value)), + &format!("type: Node (alias), value: {}", value_kind_name(value)), )); } } @@ -127,7 +127,7 @@ fn verify_type( _ => { errors.push(format_error( path, - &format!("expected array, found {}", value_kind_name(value)), + &format!("type: array, value: {}", value_kind_name(value)), )); } } @@ -140,7 +140,7 @@ fn verify_type( if items.is_empty() { errors.push(format_error( path, - "expected non-empty array, found empty array", + "type: non-empty array, value: empty array", )); } for (i, item) in items.iter().enumerate() { @@ -153,7 +153,7 @@ fn verify_type( _ => { errors.push(format_error( path, - &format!("expected array, found {}", value_kind_name(value)), + &format!("type: array, value: {}", value_kind_name(value)), )); } } @@ -191,7 +191,7 @@ fn verify_type( _ => { errors.push(format_error( path, - &format!("expected object, found {}", value_kind_name(value)), + &format!("type: object, value: {}", value_kind_name(value)), )); } }, @@ -247,7 +247,7 @@ fn verify_type( _ => { errors.push(format_error( path, - &format!("expected tagged union, found {}", value_kind_name(value)), + &format!("type: tagged union, value: {}", value_kind_name(value)), )); } }, @@ -318,7 +318,7 @@ fn centered_header(label: &str, width: usize) -> String { #[cfg(debug_assertions)] fn panic_with_mismatch( value: &Value, - expected_type: TypeId, + declared_type: TypeId, errors: &[String], module: &Module, colors: Colors, @@ -333,7 +333,7 @@ fn panic_with_mismatch( let type_name = (0..entrypoints.len()) .find_map(|i| { let e = entrypoints.get(i); - if e.result_type == expected_type { + if e.result_type == declared_type { Some(strings.get(e.name)) } else { None @@ -357,7 +357,7 @@ fn panic_with_mismatch( panic!( "\n{separator}\n\ - TYPE MISMATCH: Query output does not match declared type\n\ + BUG: Type and value do not match\n\ {separator}\n\n\ {type_str}\n\ {output_header}\n\n\ diff --git a/crates/plotnik-lib/src/engine/verify_tests.rs b/crates/plotnik-lib/src/engine/verify_tests.rs index ea95703c..97567060 100644 --- a/crates/plotnik-lib/src/engine/verify_tests.rs +++ b/crates/plotnik-lib/src/engine/verify_tests.rs @@ -19,8 +19,8 @@ fn build_module(query: &str) -> (Module, TypeId) { assert!(query_obj.is_valid(), "query should be valid"); let bytecode = emit_linked(&query_obj).expect("emit failed"); let module = Module::from_bytes(bytecode).expect("decode failed"); - let expected_type = module.entrypoints().get(0).result_type; - (module, expected_type) + let declared_type = module.entrypoints().get(0).result_type; + (module, declared_type) } fn make_node() -> Value { @@ -33,51 +33,51 @@ fn make_node() -> Value { #[test] fn verify_valid_node() { - let (module, expected_type) = build_module("Q = (identifier) @id"); + let (module, declared_type) = build_module("Q = (identifier) @id"); let value = Value::Object(vec![("id".to_string(), make_node())]); // Should not panic - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_optional_present() { - let (module, expected_type) = build_module("Q = (identifier)? @id"); + let (module, declared_type) = build_module("Q = (identifier)? @id"); let value = Value::Object(vec![("id".to_string(), make_node())]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_optional_null() { - let (module, expected_type) = build_module("Q = (identifier)? @id"); + let (module, declared_type) = build_module("Q = (identifier)? @id"); let value = Value::Object(vec![("id".to_string(), Value::Null)]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_array() { - let (module, expected_type) = build_module("Q = (identifier)* @ids"); + let (module, declared_type) = build_module("Q = (identifier)* @ids"); let value = Value::Object(vec![( "ids".to_string(), Value::Array(vec![make_node(), make_node()]), )]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_empty_array() { - let (module, expected_type) = build_module("Q = (identifier)* @ids"); + let (module, declared_type) = build_module("Q = (identifier)* @ids"); let value = Value::Object(vec![("ids".to_string(), Value::Array(vec![]))]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_enum() { - let (module, expected_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); + let (module, declared_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); let value = Value::Tagged { tag: "A".to_string(), data: Some(Box::new(Value::Object(vec![( @@ -86,54 +86,54 @@ fn verify_valid_enum() { )]))), }; - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_enum_void_variant() { - let (module, expected_type) = build_module("Q = [A: (identifier) @x B: (number)]"); + let (module, declared_type) = build_module("Q = [A: (identifier) @x B: (number)]"); let value = Value::Tagged { tag: "B".to_string(), data: None, }; - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] fn verify_valid_string() { - let (module, expected_type) = build_module("Q = (identifier) @id :: string"); + let (module, declared_type) = build_module("Q = (identifier) @id :: string"); let value = Value::Object(vec![("id".to_string(), Value::String("foo".to_string()))]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_node_is_string() { - let (module, expected_type) = build_module("Q = (identifier) @id"); + let (module, declared_type) = build_module("Q = (identifier) @id"); // id should be Node, but we provide string let value = Value::Object(vec![("id".to_string(), Value::String("wrong".to_string()))]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_missing_required_field() { - let (module, expected_type) = build_module("Q = {(identifier) @a (number) @b}"); + let (module, declared_type) = build_module("Q = {(identifier) @a (number) @b}"); // Missing field 'b' let value = Value::Object(vec![("a".to_string(), make_node())]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_array_element_wrong_type() { - let (module, expected_type) = build_module("Q = (identifier)* @ids"); + let (module, declared_type) = build_module("Q = (identifier)* @ids"); // Array element is string instead of Node let value = Value::Object(vec![( @@ -141,37 +141,37 @@ fn verify_invalid_array_element_wrong_type() { Value::Array(vec![make_node(), Value::String("oops".to_string())]), )]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_non_empty_array_is_empty() { - let (module, expected_type) = build_module("Q = (identifier)+ @ids"); + let (module, declared_type) = build_module("Q = (identifier)+ @ids"); // Non-empty array but we provide empty let value = Value::Object(vec![("ids".to_string(), Value::Array(vec![]))]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_enum_unknown_variant() { - let (module, expected_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); + let (module, declared_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); let value = Value::Tagged { tag: "C".to_string(), // Unknown variant data: None, }; - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_enum_void_with_data() { - let (module, expected_type) = build_module("Q = [A: (identifier) @x B: (number)]"); + let (module, declared_type) = build_module("Q = [A: (identifier) @x B: (number)]"); // Void variant B has data when it shouldn't let value = Value::Tagged { @@ -179,13 +179,13 @@ fn verify_invalid_enum_void_with_data() { data: Some(Box::new(Value::Object(vec![]))), }; - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] +#[should_panic(expected = "BUG:")] fn verify_invalid_enum_non_void_missing_data() { - let (module, expected_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); + let (module, declared_type) = build_module("Q = [A: (identifier) @x B: (number) @y]"); // Non-void variant A missing data let value = Value::Tagged { @@ -193,16 +193,16 @@ fn verify_invalid_enum_non_void_missing_data() { data: None, }; - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); } #[test] -#[should_panic(expected = "TYPE MISMATCH")] -fn verify_invalid_expected_object_got_array() { - let (module, expected_type) = build_module("Q = (identifier) @id"); +#[should_panic(expected = "BUG:")] +fn verify_invalid_object_vs_array() { + let (module, declared_type) = build_module("Q = (identifier) @id"); - // Expected object, got array + // Type says object, value is array let value = Value::Array(vec![make_node()]); - debug_verify_type(&value, expected_type, &module, Colors::OFF); + debug_verify_type(&value, declared_type, &module, Colors::OFF); }