This is an automated email from the ASF dual-hosted git repository. Kriskras99 pushed a commit to branch feat/derived_schema_test in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit bb9dcde939cbf59585d59de1e8e9b12ee3474924 Author: Kriskras99 <[email protected]> AuthorDate: Tue Jun 30 09:33:55 2026 +0200 feat: Derive tests for derived schemas --- avro/src/serde/derive.rs | 5 ++ avro/tests/avro-rs-226.rs | 4 ++ avro/tests/get_record_fields.rs | 2 + avro/tests/serde_human_readable_false.rs | 3 + avro/tests/serde_human_readable_true.rs | 3 + avro_derive/src/attributes/avro.rs | 3 + avro_derive/src/attributes/mod.rs | 2 + avro_derive/src/enums/bare_union.rs | 1 + avro_derive/src/enums/plain.rs | 1 + avro_derive/src/enums/record_internally_tagged.rs | 1 + avro_derive/src/enums/record_tag_content.rs | 1 + avro_derive/src/enums/union_of_records.rs | 1 + avro_derive/src/implementation.rs | 87 ++++++++++++++++++++++- avro_derive/src/structs.rs | 5 +- avro_derive/tests/derive.rs | 52 ++++++++++++-- avro_derive/tests/enum.rs | 42 +++++------ avro_derive/tests/serde.rs | 21 ++++++ 17 files changed, 207 insertions(+), 27 deletions(-) diff --git a/avro/src/serde/derive.rs b/avro/src/serde/derive.rs index 6d66fce..f588abc 100644 --- a/avro/src/serde/derive.rs +++ b/avro/src/serde/derive.rs @@ -102,6 +102,11 @@ use crate::{ /// /// Use the schema of the inner field directly. Is only allowed on structs with only one unskipped field. /// +/// - `#[avro(test = false)]` +/// +/// To disable generating tests for derived schemas. This is useful if you use a different [validator](crate::validator) +/// or the `unnameable_test_items` lint is triggered because the type your deriving is inside a function. +/// /// /// #### Variant attributes /// diff --git a/avro/tests/avro-rs-226.rs b/avro/tests/avro-rs-226.rs index b98b9d2..ee0aea3 100644 --- a/avro/tests/avro-rs-226.rs +++ b/avro/tests/avro-rs-226.rs @@ -46,6 +46,7 @@ where #[test] fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_middle_field() -> TestResult { #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)] + #[avro(tests = false)] struct T { x: Option<i8>, #[serde(skip_serializing_if = "Option::is_none")] @@ -67,6 +68,7 @@ fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_middle_field #[test] fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_first_field() -> TestResult { #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)] + #[avro(tests = false)] struct T { #[serde(skip_serializing_if = "Option::is_none")] #[avro(default = "null")] @@ -88,6 +90,7 @@ fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_first_field( #[test] fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_last_field() -> TestResult { #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)] + #[avro(tests = false)] struct T { x: Option<i8>, y: Option<String>, @@ -109,6 +112,7 @@ fn avro_rs_226_index_out_of_bounds_with_serde_skip_serializing_skip_last_field() #[test] fn avro_rs_226_index_out_of_bounds_with_serde_skip_multiple_fields() -> TestResult { #[derive(AvroSchema, Clone, Debug, Deserialize, PartialEq, Serialize)] + #[avro(tests = false)] struct T { no_skip1: Option<i8>, #[serde(skip_serializing)] diff --git a/avro/tests/get_record_fields.rs b/avro/tests/get_record_fields.rs index 5bab721..8e6519f 100644 --- a/avro/tests/get_record_fields.rs +++ b/avro/tests/get_record_fields.rs @@ -26,6 +26,7 @@ use apache_avro_test_helper::TestResult; #[test] fn avro_rs_448_default_get_record_fields_no_recursion() -> TestResult { #[derive(apache_avro_derive::AvroSchema)] + #[avro(tests = false)] struct Foo { _a: i32, _b: String, @@ -67,6 +68,7 @@ fn avro_rs_448_default_get_record_fields_no_recursion() -> TestResult { #[test] fn avro_rs_448_default_get_record_fields_recursion() -> TestResult { #[derive(apache_avro_derive::AvroSchema)] + #[avro(tests = false)] struct Foo { _a: i32, _b: Option<Box<Foo>>, diff --git a/avro/tests/serde_human_readable_false.rs b/avro/tests/serde_human_readable_false.rs index e4e6013..f9656c7 100644 --- a/avro/tests/serde_human_readable_false.rs +++ b/avro/tests/serde_human_readable_false.rs @@ -65,6 +65,7 @@ fn avro_rs_53_uuid_with_fixed() -> TestResult { #[test] fn avro_rs_440_uuid_string() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { #[avro(with = || Schema::Uuid(UuidSchema::String))] @@ -88,6 +89,7 @@ fn avro_rs_440_uuid_string() -> TestResult { #[test] fn avro_rs_440_uuid_bytes() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { #[avro(with = || Schema::Uuid(UuidSchema::Bytes))] @@ -116,6 +118,7 @@ fn avro_rs_440_uuid_bytes() -> TestResult { #[test] fn avro_rs_440_uuid_fixed() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { inner: Uuid, diff --git a/avro/tests/serde_human_readable_true.rs b/avro/tests/serde_human_readable_true.rs index f23570c..2873edb 100644 --- a/avro/tests/serde_human_readable_true.rs +++ b/avro/tests/serde_human_readable_true.rs @@ -64,6 +64,7 @@ fn avro_rs_53_uuid_with_string_true() -> TestResult { #[test] fn avro_rs_440_uuid_string() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { #[avro(with = || Schema::Uuid(UuidSchema::String))] @@ -89,6 +90,7 @@ fn avro_rs_440_uuid_string() -> TestResult { #[test] fn avro_rs_440_uuid_bytes() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { #[avro(with = || Schema::Uuid(UuidSchema::Bytes))] @@ -112,6 +114,7 @@ fn avro_rs_440_uuid_bytes() -> TestResult { #[test] fn avro_rs_440_uuid_fixed() -> TestResult { #[derive(apache_avro_derive::AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct CustomUuid { inner: Uuid, diff --git a/avro_derive/src/attributes/avro.rs b/avro_derive/src/attributes/avro.rs index bc8b5ef..e790f84 100644 --- a/avro_derive/src/attributes/avro.rs +++ b/avro_derive/src/attributes/avro.rs @@ -85,6 +85,9 @@ pub struct ContainerAttributes { /// Force the generator to use a certain schema representation #[darling(default)] pub repr: Option<Repr>, + /// Force the generator to use a certain schema representation + #[darling(default = || true)] + pub tests: bool, } impl ContainerAttributes { diff --git a/avro_derive/src/attributes/mod.rs b/avro_derive/src/attributes/mod.rs index 19e8a89..e316db4 100644 --- a/avro_derive/src/attributes/mod.rs +++ b/avro_derive/src/attributes/mod.rs @@ -135,6 +135,7 @@ pub struct NamedTypeOptions { pub transparent: bool, pub default: Option<Value>, pub repr: Option<Repr>, + pub tests: bool, } impl NamedTypeOptions { @@ -261,6 +262,7 @@ impl NamedTypeOptions { transparent: serde.transparent, default, repr, + tests: avro.tests, }) } } diff --git a/avro_derive/src/enums/bare_union.rs b/avro_derive/src/enums/bare_union.rs index 3fdf117..4babd3b 100644 --- a/avro_derive/src/enums/bare_union.rs +++ b/avro_derive/src/enums/bare_union.rs @@ -109,5 +109,6 @@ pub fn to_implementation( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } diff --git a/avro_derive/src/enums/plain.rs b/avro_derive/src/enums/plain.rs index 7d9562b..da6e18f 100644 --- a/avro_derive/src/enums/plain.rs +++ b/avro_derive/src/enums/plain.rs @@ -137,6 +137,7 @@ pub fn to_implementation( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } diff --git a/avro_derive/src/enums/record_internally_tagged.rs b/avro_derive/src/enums/record_internally_tagged.rs index ec8208a..4eefc0f 100644 --- a/avro_derive/src/enums/record_internally_tagged.rs +++ b/avro_derive/src/enums/record_internally_tagged.rs @@ -212,5 +212,6 @@ pub fn to_implementation( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } diff --git a/avro_derive/src/enums/record_tag_content.rs b/avro_derive/src/enums/record_tag_content.rs index ab922e9..f1170cf 100644 --- a/avro_derive/src/enums/record_tag_content.rs +++ b/avro_derive/src/enums/record_tag_content.rs @@ -168,5 +168,6 @@ pub fn to_implementation( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } diff --git a/avro_derive/src/enums/union_of_records.rs b/avro_derive/src/enums/union_of_records.rs index 49db73b..9c68590 100644 --- a/avro_derive/src/enums/union_of_records.rs +++ b/avro_derive/src/enums/union_of_records.rs @@ -94,5 +94,6 @@ pub fn to_implementation( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } diff --git a/avro_derive/src/implementation.rs b/avro_derive/src/implementation.rs index 54f5a8b..4ec84d0 100644 --- a/avro_derive/src/implementation.rs +++ b/avro_derive/src/implementation.rs @@ -17,7 +17,7 @@ use crate::utils::name_expr; use proc_macro2::{Ident, TokenStream}; -use quote::quote; +use quote::{format_ident, quote}; use syn::Generics; pub struct Implementation { @@ -35,6 +35,8 @@ pub struct Implementation { record_fields_expr: TokenStream, /// An expression that resolves to a `Option<serde_json::Value>` field_default_expr: TokenStream, + /// Tests that will be run if the type has no generics and they haven't been disabled via an attribute. + tests: Option<Vec<Test>>, } impl Implementation { @@ -49,6 +51,7 @@ impl Implementation { schema_expr: TokenStream, record_fields_expr: Option<TokenStream>, field_default_expr: Option<TokenStream>, + tests: bool, ) -> Implementation { let name_expr = name_expr(name); let schema_expr = quote! { @@ -68,6 +71,7 @@ impl Implementation { schema_expr, record_fields_expr, field_default_expr, + tests, ) } @@ -77,8 +81,9 @@ impl Implementation { schema_expr: TokenStream, record_fields_expr: Option<TokenStream>, field_default_expr: Option<TokenStream>, + tests: bool, ) -> Implementation { - Self { + let mut this = Self { ident, generics, schema_expr, @@ -86,6 +91,36 @@ impl Implementation { .unwrap_or_else(|| quote! { ::std::option::Option::None }), field_default_expr: field_default_expr .unwrap_or_else(|| quote! { ::std::option::Option::None }), + tests: tests.then(Vec::new), + }; + + this.add_schema_test(); + + this + } + + pub fn add_test(&mut self, test: Test) { + if let Some(tests) = &mut self.tests { + tests.push(test); + } + } + + fn add_schema_test(&mut self) { + // Only add the schema test if there are no generics to deal with. I think it should be possible + // to be able to generate the test if there are only lifetimes, but that needs more experimentation. + if self.generics.lifetimes().count() == 0 + && self.generics.type_params().count() == 0 + && self.generics.const_params().count() == 0 + { + let ident = &self.ident; + self.add_test(Test { + name: "schema".to_string(), + body: quote! { + eprintln!("Invalid schema, if this is because a different validator is used at runtime you can disable generating tests with `#[avro(tests = false)]`"); + <#ident as ::apache_avro::serde::AvroSchema>::get_schema(); + }, + should_panic: None, + }); } } @@ -96,6 +131,24 @@ impl Implementation { let record_fields_expr = self.record_fields_expr; let field_default_expr = self.field_default_expr; + let tests = if let Some(tests) = self.tests { + let test_module_name = format!( + "_apache_avro_derive_tests_for_{}", + ident.to_string().to_lowercase() + ); + let tests = tests + .into_iter() + .map(|t| t.into_token_stream(&test_module_name)); + quote! { + #( + #[cfg(test)] + #tests + )* + } + } else { + TokenStream::new() + }; + quote! { #[automatically_derived] impl #impl_generics ::apache_avro::AvroSchemaComponent for #ident #ty_generics #where_clause { @@ -111,6 +164,36 @@ impl Implementation { #field_default_expr } } + + #tests + } + } +} + +pub struct Test { + /// The name of the test. + pub name: String, + /// The body of the test function, so without `fn some_name() {`. + pub body: TokenStream, + /// If this test should panic, this should be the message. + pub should_panic: Option<String>, +} + +impl Test { + pub fn into_token_stream(self, prefix: &str) -> TokenStream { + let name = format_ident!("{prefix}_{}", &self.name); + let body = &self.body; + let should_panic = if let Some(expected) = &self.should_panic { + quote! { #[should_panic(expected = #expected)] } + } else { + TokenStream::new() + }; + quote! { + #[test] + #should_panic + fn #name() { + #body + } } } } diff --git a/avro_derive/src/structs.rs b/avro_derive/src/structs.rs index 9e242b5..891c43f 100644 --- a/avro_derive/src/structs.rs +++ b/avro_derive/src/structs.rs @@ -35,7 +35,7 @@ pub fn to_implementation( data: DataStruct, ) -> Result<Implementation, Vec<syn::Error>> { if container_attrs.transparent { - transparent(input_span, ident, generics, data) + transparent(input_span, ident, generics, &container_attrs, data) } else { normal(ident, generics, container_attrs, data) } @@ -85,6 +85,7 @@ fn normal( .default .map(json_value_expr) .map(|t| quote! { ::std::option::Option::Some(#t)}), + container_attrs.tests, )) } @@ -92,6 +93,7 @@ fn transparent( input_span: Span, ident: Ident, generics: Generics, + container_attrs: &NamedTypeOptions, data: DataStruct, ) -> Result<Implementation, Vec<syn::Error>> { match data.fields { @@ -119,6 +121,7 @@ fn transparent( field_to_schema_expr(&field, &attrs.with)?, Some(field_to_record_fields_expr(&field, &attrs.with)?), Some(field_default_expr), + container_attrs.tests, )) } else { Err(vec![syn::Error::new( diff --git a/avro_derive/tests/derive.rs b/avro_derive/tests/derive.rs index c4c7d21..df48539 100644 --- a/avro_derive/tests/derive.rs +++ b/avro_derive/tests/derive.rs @@ -209,7 +209,7 @@ fn test_complex_namespace() { #[test] fn avro_rs_239_test_named_record() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)] - #[avro(namespace = "com.testing.namespace")] + #[avro(namespace = "com.testing.namespace", tests = false)] #[serde(rename = "Other")] struct TestNamedRecord { a: i32, @@ -658,6 +658,7 @@ fn test_enum() { fn avro_rs_239_test_enum_named() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)] #[serde(rename = "Other", rename_all = "snake_case")] + #[avro(tests = false)] enum TestNamedEnum { A, B, @@ -667,6 +668,7 @@ fn avro_rs_239_test_enum_named() { } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq, Eq)] + #[avro(tests = false)] struct TestNamedEnumNested { a: TestNamedEnum, b: String, @@ -1361,6 +1363,7 @@ fn test_basic_enum_with_aliases2() { #[test] fn test_basic_struct_with_defaults() { #[derive(Debug, Deserialize, Serialize, AvroSchema, Clone, PartialEq, Eq)] + #[avro(tests = false)] enum MyEnum { Foo, Bar, @@ -1368,6 +1371,7 @@ fn test_basic_struct_with_defaults() { } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct TestBasicStructWithDefaultValues { #[avro(default = "123")] a: i32, @@ -1502,15 +1506,13 @@ fn test_basic_struct_with_defaults() { #[test] fn avro_3633_test_basic_struct_with_skip_attribute() { - // Note: If using the skip attribute together with serialization, - // the serde's skip attribute needs also to be added - #[derive(Debug, Default, Serialize, Deserialize, Clone, PartialEq, Eq)] struct TestBasicStructNoSchema { field: bool, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct TestBasicStructWithSkipAttribute { #[serde(skip)] condition: bool, @@ -1583,6 +1585,7 @@ fn avro_3633_test_basic_struct_with_skip_attribute() { #[test] fn avro_3633_test_basic_struct_with_rename_attribute() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct TestBasicStructWithRenameAttribute { #[serde(rename = "a1")] a: bool, @@ -1640,6 +1643,7 @@ fn avro_3633_test_basic_struct_with_rename_attribute() { #[test] fn test_avro_3663_raw_identifier_field_name() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct TestRawIdent { r#type: bool, } @@ -1657,6 +1661,7 @@ fn test_avro_3663_raw_identifier_field_name() { fn avro_3962_fields_documentation() { /// Foo docs #[derive(AvroSchema)] + #[avro(tests = false)] #[allow(dead_code)] struct Foo { /// a's Rustdoc @@ -1680,11 +1685,13 @@ fn avro_3962_fields_documentation() { #[test] fn avro_rs_247_serde_flatten_support() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Nested { a: bool, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(flatten)] nested: Nested, @@ -1723,17 +1730,20 @@ fn avro_rs_247_serde_nested_flatten_support() { use serde::{Deserialize, Serialize}; #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)] + #[avro(tests = false)] pub struct NestedFoo { one: u32, } #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)] + #[avro(tests = false)] pub struct Foo { #[serde(flatten)] nested_foo: NestedFoo, } #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)] + #[avro(tests = false)] struct Bar { foo: Foo, two: u32, @@ -1780,11 +1790,13 @@ fn avro_rs_247_serde_nested_flatten_support() { #[should_panic(expected = "Duplicate field names found")] fn avro_rs_247_serde_flatten_support_duplicate_field_name() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Nested { a: i32, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(flatten)] nested: Nested, @@ -1797,6 +1809,7 @@ fn avro_rs_247_serde_flatten_support_duplicate_field_name() { #[test] fn avro_rs_247_serde_flatten_support_with_skip() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Nested { a: bool, #[serde(skip)] @@ -1804,6 +1817,7 @@ fn avro_rs_247_serde_flatten_support_with_skip() { } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(flatten)] nested: Nested, @@ -1883,6 +1897,7 @@ fn avro_rs_397_with() { #[allow(dead_code)] #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { #[avro(with)] #[serde(with = "module")] @@ -1933,6 +1948,7 @@ fn avro_rs_397_with_generic() { #[allow(dead_code)] #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { #[avro(with = generic::<15>)] a: [u8; 15], @@ -1967,6 +1983,7 @@ fn avro_rs_397_uuid() { .unwrap(); #[derive(AvroSchema, Debug, Clone, PartialEq, Serialize, Deserialize)] + #[avro(tests = false)] struct Foo { #[serde(rename = "baz")] bar: uuid::Uuid, @@ -1999,6 +2016,7 @@ fn avro_rs_397_derive_with_expr_lambda() { let expected_schema = Schema::parse_str(schema).unwrap(); #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { #[avro(with = || Schema::Bytes)] _a: String, @@ -2022,6 +2040,7 @@ fn avro_rs_398_transparent_with_skip() { #[allow(dead_code)] #[derive(AvroSchema)] #[serde(transparent)] + #[avro(tests = false)] struct Foo { #[serde(skip)] a: String, @@ -2041,6 +2060,7 @@ fn avro_rs_401_do_not_match_typename() { #[expect(dead_code, reason = "We only check the schema")] #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { field: f32, } @@ -2066,6 +2086,7 @@ fn avro_rs_401_do_not_match_typename() { fn avro_rs_401_supported_type_variants() { #[expect(dead_code, reason = "We only check the schema")] #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo<'a> { one: f32, two: std::string::String, @@ -2170,6 +2191,7 @@ fn avro_rs_414_round_trip_char_u64_u128_i128() { .unwrap(); #[derive(AvroSchema, Serialize, Deserialize, PartialEq, Debug, Clone)] + #[avro(tests = false)] struct Foo { a: char, b: u64, @@ -2189,23 +2211,27 @@ fn avro_rs_414_round_trip_char_u64_u128_i128() { #[test] fn avro_rs_448_flatten_recurring_type() { #[derive(AvroSchema)] + #[avro(tests = false)] #[expect(dead_code, reason = "Only testing derived schema")] pub enum Color { G, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct A { pub _color: Color, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct C { #[serde(flatten)] pub _a: A, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct TestStruct { pub _a: Color, pub _c: C, @@ -2248,29 +2274,34 @@ fn avro_rs_448_flatten_recurring_type() { #[test] fn avro_rs_448_flatten_transparent_sandwich() { #[derive(AvroSchema)] + #[avro(tests = false)] #[expect(dead_code, reason = "Only testing derived schema")] pub enum Color { G, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct A { pub _color: Color, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct C { #[serde(flatten)] pub _a: A, } #[derive(AvroSchema)] + #[avro(tests = false)] #[serde(transparent)] pub struct B { pub _c: C, } #[derive(AvroSchema)] + #[avro(tests = false)] pub struct TestStruct { pub _a: Color, pub _b: B, @@ -2318,6 +2349,7 @@ fn avro_rs_448_flatten_transparent_sandwich() { #[test] fn avro_rs_448_transparent_with() { #[derive(AvroSchema)] + #[avro(tests = false)] #[serde(transparent)] pub struct TestStruct { #[avro(with = || Schema::Long)] @@ -2338,12 +2370,14 @@ fn avro_rs_448_transparent_with() { #[test] fn avro_rs_448_transparent_with_2() { #[derive(AvroSchema)] + #[avro(tests = false)] pub struct Foo { _field: i32, _a: String, } #[derive(AvroSchema)] + #[avro(tests = false)] #[serde(transparent)] pub struct TestStruct { #[avro(with = Foo::get_schema_in_ctxt)] @@ -2377,17 +2411,20 @@ fn avro_rs_448_transparent_with_2() { #[test] fn avro_rs_476_field_default() { #[derive(AvroSchema)] + #[avro(tests = false)] struct Bar { _field: Box<Bar>, } #[derive(AvroSchema)] + #[avro(tests = false)] #[avro(default = r#"{"_field": true}"#)] struct Spam { _field: bool, } #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { _a: bool, _b: i8, @@ -2431,12 +2468,14 @@ fn avro_rs_476_field_default() { #[test] fn avro_rs_476_field_default_false() { #[derive(AvroSchema)] + #[avro(tests = false)] #[avro(default = r#"{"_field": true}"#)] struct Spam { _field: bool, } #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { #[avro(default = false)] _a: bool, @@ -2460,12 +2499,14 @@ fn avro_rs_476_field_default_false() { #[test] fn avro_rs_476_field_default_provided() { #[derive(AvroSchema)] + #[avro(tests = false)] #[avro(default = r#"{"_field": true}"#)] struct Spam { _field: bool, } #[derive(AvroSchema)] + #[avro(tests = false)] struct Foo { #[avro(default = "true")] _a: bool, @@ -2542,6 +2583,7 @@ fn avro_rs_476_field_default_provided() { #[test] fn avro_rs_476_skip_serializing_fielddefault_trait_none() { #[derive(AvroSchema, Debug, Deserialize, Serialize)] + #[avro(tests = false)] struct T { x: Option<i8>, #[serde(skip_serializing)] @@ -2574,6 +2616,7 @@ fn avro_rs_476_skip_serializing_fielddefault_trait_none() { #[test] fn avro_rs_561_transparent_struct_with_default_override() { #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)] + #[avro(tests = false)] #[serde(transparent)] struct T { #[avro(default = "42")] @@ -2590,6 +2633,7 @@ fn avro_rs_561_transparent_struct_with_default_override() { #[test] fn avro_rs_569_tuple_struct() { #[derive(AvroSchema, Debug, PartialEq, Eq, Deserialize, Serialize)] + #[avro(tests = false)] struct T(i32, String); let schema = T::get_schema(); diff --git a/avro_derive/tests/enum.rs b/avro_derive/tests/enum.rs index 6ef6c25..11abb57 100644 --- a/avro_derive/tests/enum.rs +++ b/avro_derive/tests/enum.rs @@ -72,7 +72,7 @@ where #[test] fn avro_rs_561_bare_union_untagged_empty_tuple_variant() { #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] #[serde(untagged)] enum C { A(), @@ -84,7 +84,7 @@ fn avro_rs_561_bare_union_untagged_empty_tuple_variant() { #[test] fn avro_rs_561_bare_union_empty_tuple_variant() { #[derive(Debug, Eq, PartialEq, AvroSchema, Serialize, Deserialize)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] enum C { A(), B {}, @@ -97,6 +97,7 @@ fn avro_rs_561_bare_union_empty_tuple_variant() { #[test] fn avro_rs_569_enum_repr_default() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] + #[avro(tests = false)] enum Foo { A, B, @@ -122,7 +123,7 @@ fn avro_rs_569_enum_repr_default() { #[test] fn avro_rs_569_enum_repr_enum() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "enum")] + #[avro(repr = "enum", tests = false)] enum Foo { A, B, @@ -148,7 +149,7 @@ fn avro_rs_569_enum_repr_enum() { #[test] fn avro_rs_569_enum_repr_record_tag_content_plain() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_tag_content")] + #[avro(repr = "record_tag_content", tests = false)] #[serde(tag = "type", content = "value")] enum Foo { A, @@ -190,7 +191,7 @@ fn avro_rs_569_enum_repr_record_tag_content_plain() { #[test] fn avro_rs_569_enum_repr_record_tag_content_tuple() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_tag_content")] + #[avro(repr = "record_tag_content", tests = false)] #[serde(tag = "type", content = "value")] enum Foo { A, @@ -253,7 +254,7 @@ fn avro_rs_569_enum_repr_record_tag_content_tuple() { #[test] fn avro_rs_569_enum_repr_record_tag_content_struct() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_tag_content")] + #[avro(repr = "record_tag_content", tests = false)] #[serde(tag = "type", content = "value")] enum Foo { A {}, @@ -316,7 +317,7 @@ fn avro_rs_569_enum_repr_record_tag_content_struct() { #[test] fn avro_rs_569_enum_repr_bare_union_plain() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] #[serde(untagged)] enum Foo { A, @@ -331,7 +332,7 @@ fn avro_rs_569_enum_repr_bare_union_plain() { #[test] fn avro_rs_569_enum_repr_bare_union_tuple() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] #[serde(untagged)] enum Foo { B(String), @@ -367,7 +368,7 @@ fn avro_rs_569_enum_repr_bare_union_tuple() { #[test] fn avro_rs_569_enum_repr_record_internally_tagged_plain() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_internally_tagged")] + #[avro(repr = "record_internally_tagged", tests = false)] #[serde(tag = "type")] enum Foo { A, @@ -402,7 +403,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_plain() { )] fn avro_rs_569_enum_repr_record_internally_tagged_tuple_no_get_record_fields() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_internally_tagged")] + #[avro(repr = "record_internally_tagged", tests = false)] #[serde(tag = "type")] enum Foo { B(String), @@ -414,13 +415,14 @@ fn avro_rs_569_enum_repr_record_internally_tagged_tuple_no_get_record_fields() { #[test] fn avro_rs_569_enum_repr_record_internally_tagged_tuple() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_internally_tagged")] + #[avro(repr = "record_internally_tagged", tests = false)] #[serde(tag = "type")] enum Foo { B(Bar), } #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] + #[avro(tests = false)] struct Bar { spam: String, } @@ -452,7 +454,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_tuple() { #[test] fn avro_rs_569_enum_repr_record_internally_tagged_struct() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_internally_tagged")] + #[avro(repr = "record_internally_tagged", tests = false)] #[serde(tag = "type")] enum Foo { A {}, @@ -512,7 +514,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_struct() { #[should_panic(expected = "Missing default for skipped field 'spam' of schema")] fn avro_rs_569_enum_repr_record_internally_tagged_struct_no_defaults() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "record_internally_tagged")] + #[avro(repr = "record_internally_tagged", tests = false)] #[serde(tag = "type")] enum Foo { A {}, @@ -533,7 +535,7 @@ fn avro_rs_569_enum_repr_record_internally_tagged_struct_no_defaults() { #[test] fn avro_rs_569_enum_repr_union_of_records_plain() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "union_of_records")] + #[avro(repr = "union_of_records", tests = false)] enum Foo { A, B, @@ -559,7 +561,7 @@ fn avro_rs_569_enum_repr_union_of_records_plain() { #[test] fn avro_rs_569_enum_repr_union_of_records_tuple() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "union_of_records")] + #[avro(repr = "union_of_records", tests = false)] enum Foo { A(), B(String), @@ -593,7 +595,7 @@ fn avro_rs_569_enum_repr_union_of_records_tuple() { #[test] fn avro_rs_569_enum_repr_union_of_records_struct() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "union_of_records")] + #[avro(repr = "union_of_records", tests = false)] enum Foo { A {}, B { @@ -635,7 +637,7 @@ fn avro_rs_569_enum_repr_union_of_records_struct() { #[test] fn avro_rs_569_enum_repr_bare_union_without_untagged_plain() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] enum Foo { A, } @@ -649,7 +651,7 @@ fn avro_rs_569_enum_repr_bare_union_without_untagged_plain() { #[test] fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] enum Foo { B(String), #[serde(rename = "D")] @@ -684,7 +686,7 @@ fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple() { #[test] fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple_same_len() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] enum Foo { A(String, String), B(i32, i32), @@ -724,7 +726,7 @@ fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple_same_len() { #[test] fn avro_rs_569_enum_repr_bare_union_without_untagged_tuple_and_struct_same_len() { #[derive(AvroSchema, Debug, Serialize, Deserialize, Clone, PartialEq)] - #[avro(repr = "bare_union")] + #[avro(repr = "bare_union", tests = false)] enum Foo { A { a: String, b: String }, B(i32, i32), diff --git a/avro_derive/tests/serde.rs b/avro_derive/tests/serde.rs index 3b51074..9d612fc 100644 --- a/avro_derive/tests/serde.rs +++ b/avro_derive/tests/serde.rs @@ -68,6 +68,7 @@ mod container_attributes { #[test] fn avro_rs_373_rename() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(rename = "Bar")] struct Foo { a: String, @@ -103,6 +104,7 @@ mod container_attributes { #[test] fn avro_rs_373_nested_rename() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(rename = "Bar")] struct Foo { a: String, @@ -110,6 +112,7 @@ mod container_attributes { } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Outer { bar: Foo, } @@ -154,6 +157,7 @@ mod container_attributes { #[test] fn avro_rs_373_rename_all() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(rename_all = "UPPERCASE")] struct Foo { a: String, @@ -191,12 +195,14 @@ mod container_attributes { #[should_panic(expected = "Expected Schema::Record(name: FooFromInto)")] fn avro_rs_373_from_into() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(from = "FooFromInto", into = "FooFromInto")] struct Foo { a: String, b: i32, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct FooFromInto { a: String, b: i32, @@ -251,12 +257,14 @@ mod container_attributes { #[should_panic(expected = r#"Missing field in record: "c""#)] fn avro_rs_373_from_into_different() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(from = "FooFromInto", into = "FooFromInto")] struct Foo { a: String, b: i32, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct FooFromInto { a: String, b: i32, @@ -311,6 +319,7 @@ mod container_attributes { #[test] fn avro_rs_398_transparent() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(transparent)] struct Foo { a: String, @@ -333,6 +342,7 @@ mod container_attributes { #[test] fn avro_rs_398_transparent_ref() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(transparent)] struct Foo<'a> { a: &'a str, @@ -351,6 +361,7 @@ mod container_attributes { #[test] fn avro_rs_398_transparent_array() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] #[serde(transparent)] struct Foo { a: Vec<String>, @@ -409,6 +420,7 @@ mod container_attributes { // Provide getters for every private field of the remote struct. The getter must // return either `T` or `&T` where `T` is the type of the field. #[derive(Serialize, Deserialize, AvroSchema)] + #[avro(tests = false)] #[serde(remote = "Duration")] struct DurationDef { #[serde(getter = "Duration::seconds")] @@ -425,6 +437,7 @@ mod container_attributes { } #[derive(Serialize, Deserialize, AvroSchema, Debug, PartialEq, Eq)] + #[avro(tests = false)] struct Process { command_line: String, @@ -446,6 +459,7 @@ mod variant_attributes { #[test] fn avro_rs_373_rename() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] enum Foo { #[serde(rename = "Three")] One, @@ -471,6 +485,7 @@ mod variant_attributes { #[test] fn avro_rs_373_alias() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] enum Foo { #[serde(rename = "Three", alias = "One")] One, @@ -496,6 +511,7 @@ mod variant_attributes { #[test] fn avro_rs_373_skip() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] enum Foo { #[allow(dead_code)] #[serde(skip)] @@ -526,6 +542,7 @@ mod field_attributes { #[test] fn avro_rs_373_rename() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(rename = "c")] a: String, @@ -561,11 +578,13 @@ mod field_attributes { #[test] fn avro_rs_373_flatten() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Nested { a: bool, } #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(flatten)] nested: Nested, @@ -601,6 +620,7 @@ mod field_attributes { #[test] fn avro_rs_373_skip() { #[derive(Debug, Serialize, Deserialize, AvroSchema, Clone, PartialEq)] + #[avro(tests = false)] struct Foo { #[serde(skip)] a: String, @@ -633,6 +653,7 @@ mod field_attributes { fn avro_rs_397_avroschema_with_bytes() { #[expect(dead_code, reason = "We only care about the schema")] #[derive(AvroSchema)] + #[avro(tests = false)] struct TestStructWithBytes<'a> { #[avro(with)] #[serde(with = "apache_avro::serde::bytes")]
