// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. //! Tests for DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound, //! RuntimeDebugNoBound, PartialOrdNoBound and OrdNoBound use frame_support::{ CloneNoBound, DebugNoBound, DefaultNoBound, EqNoBound, OrdNoBound, PartialEqNoBound, PartialOrdNoBound, RuntimeDebugNoBound, }; #[derive(RuntimeDebugNoBound)] struct Unnamed(u64); #[test] fn runtime_debug_no_bound_display_correctly() { // This test is not executed without std assert_eq!(format!("{:?}", Unnamed(1)), "Unnamed(1)"); } trait Config { type C: std::fmt::Debug + Clone + Eq + PartialEq + Default + PartialOrd + Ord; } struct Runtime; struct ImplNone; impl Config for Runtime { type C = u32; } #[derive( DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound, PartialOrdNoBound, OrdNoBound, )] struct StructNamed { a: u32, b: u64, c: T::C, phantom: core::marker::PhantomData<(U, V)>, } #[rustversion::attr(not(stable), ignore)] #[cfg(not(feature = "disable-ui-tests"))] #[test] fn test_struct_named_debug_print() { let a_1 = StructNamed:: { a: 1, b: 2, c: 3, phantom: Default::default(), }; assert_eq!( format!("{:?}", a_1), String::from("StructNamed { a: 1, b: 2, c: 3, phantom: PhantomData<(derive_no_bound::ImplNone, derive_no_bound::ImplNone)> }") ); } #[test] fn test_struct_named() { let a_1 = StructNamed:: { a: 1, b: 2, c: 3, phantom: Default::default(), }; let a_default: StructNamed = Default::default(); assert_eq!(a_default.a, 0); assert_eq!(a_default.b, 0); assert_eq!(a_default.c, 0); assert_eq!(a_default.phantom, Default::default()); let a_2 = a_1.clone(); assert_eq!(a_2.a, 1); assert_eq!(a_2.b, 2); assert_eq!(a_2.c, 3); assert_eq!(a_2, a_1); let b = StructNamed:: { a: 1, b: 2, c: 4, phantom: Default::default(), }; assert!(b != a_1); assert!(b > a_1); } #[derive( DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound, PartialOrdNoBound, OrdNoBound, )] struct StructUnnamed(u32, u64, T::C, core::marker::PhantomData<(U, V)>); #[rustversion::attr(not(stable), ignore)] #[cfg(not(feature = "disable-ui-tests"))] #[test] fn test_struct_unnamed_debug_print() { let a_1 = StructUnnamed::(1, 2, 3, Default::default()); assert_eq!(format!("{:?}", a_1), String::from("StructUnnamed(1, 2, 3, PhantomData<(derive_no_bound::ImplNone, derive_no_bound::ImplNone)>)")); } #[test] fn test_struct_unnamed() { let a_1 = StructUnnamed::(1, 2, 3, Default::default()); let a_default: StructUnnamed = Default::default(); assert_eq!(a_default.0, 0); assert_eq!(a_default.1, 0); assert_eq!(a_default.2, 0); assert_eq!(a_default.3, Default::default()); let a_2 = a_1.clone(); assert_eq!(a_2.0, 1); assert_eq!(a_2.1, 2); assert_eq!(a_2.2, 3); assert_eq!(a_2, a_1); let b = StructUnnamed::(1, 2, 4, Default::default()); assert!(b != a_1); assert!(b > a_1); } #[derive( DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound, PartialOrdNoBound, OrdNoBound, )] struct StructNoGenerics { field1: u32, field2: u64, } #[allow(dead_code)] #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound)] enum EnumNoGenerics { #[default] VariantUnnamed(u32, u64), VariantNamed { a: u32, b: u64, }, VariantUnit, } #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound)] enum Enum { #[default] VariantUnnamed(u32, u64, T::C, core::marker::PhantomData<(U, V)>), VariantNamed { a: u32, b: u64, c: T::C, phantom: core::marker::PhantomData<(U, V)>, }, VariantUnit, VariantUnit2, } // enum that will have a named default. #[allow(dead_code)] #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound)] enum Enum2 { #[default] VariantNamed { a: u32, b: u64, c: T::C, }, VariantUnnamed(u32, u64, T::C), VariantUnit, VariantUnit2, } #[allow(dead_code)] // enum that will have a unit default. #[derive(DebugNoBound, CloneNoBound, EqNoBound, PartialEqNoBound, DefaultNoBound)] enum Enum3 { #[default] VariantUnit, VariantNamed { a: u32, b: u64, c: T::C, }, VariantUnnamed(u32, u64, T::C), VariantUnit2, } #[rustversion::attr(not(stable), ignore)] #[cfg(not(feature = "disable-ui-tests"))] #[test] fn test_enum_debug_print() { type TestEnum = Enum; let variant_0 = TestEnum::VariantUnnamed(1, 2, 3, Default::default()); let variant_1 = TestEnum::VariantNamed { a: 1, b: 2, c: 3, phantom: Default::default() }; let variant_2 = TestEnum::VariantUnit; let variant_3 = TestEnum::VariantUnit2; assert_eq!( format!("{:?}", variant_0), String::from("Enum::VariantUnnamed(1, 2, 3, PhantomData<(derive_no_bound::ImplNone, derive_no_bound::ImplNone)>)"), ); assert_eq!( format!("{:?}", variant_1), String::from("Enum::VariantNamed { a: 1, b: 2, c: 3, phantom: PhantomData<(derive_no_bound::ImplNone, derive_no_bound::ImplNone)> }"), ); assert_eq!(format!("{:?}", variant_2), String::from("Enum::VariantUnit")); assert_eq!(format!("{:?}", variant_3), String::from("Enum::VariantUnit2")); } #[test] fn test_enum() { type TestEnum = Enum; let variant_0 = TestEnum::VariantUnnamed(1, 2, 3, Default::default()); let variant_0_bis = TestEnum::VariantUnnamed(1, 2, 4, Default::default()); let variant_1 = TestEnum::VariantNamed { a: 1, b: 2, c: 3, phantom: Default::default() }; let variant_1_bis = TestEnum::VariantNamed { a: 1, b: 2, c: 4, phantom: Default::default() }; let variant_2 = TestEnum::VariantUnit; let variant_3 = TestEnum::VariantUnit2; let default: TestEnum = Default::default(); assert_eq!( default, // first variant is default. TestEnum::VariantUnnamed(0, 0, 0, Default::default()) ); assert_eq!(Enum2::::default(), Enum2::::VariantNamed { a: 0, b: 0, c: 0 }); assert_eq!(Enum3::::default(), Enum3::::VariantUnit); assert!(variant_0 != variant_0_bis); assert!(variant_1 != variant_1_bis); assert!(variant_0 != variant_1); assert!(variant_0 != variant_2); assert!(variant_0 != variant_3); assert!(variant_1 != variant_0); assert!(variant_1 != variant_2); assert!(variant_1 != variant_3); assert!(variant_2 != variant_0); assert!(variant_2 != variant_1); assert!(variant_2 != variant_3); assert!(variant_3 != variant_0); assert!(variant_3 != variant_1); assert!(variant_3 != variant_2); assert!(variant_0.clone() == variant_0); assert!(variant_1.clone() == variant_1); assert!(variant_2.clone() == variant_2); assert!(variant_3.clone() == variant_3); } // Return all the combinations of (0, 0, 0), (0, 0, 1), (0, 1, 0), ... // Used to test all the possible struct orderings fn combinations() -> Vec<(u32, u64, u32)> { let mut v = vec![]; for a in 0..=1 { for b in 0..=1 { for c in 0..=1 { v.push((a, b, c)); } } } v } // Ensure that the PartialOrdNoBound follows the same rules as the native PartialOrd #[derive(Debug, Clone, Eq, PartialEq, Default, PartialOrd, Ord)] struct StructNamedRust { a: u32, b: u64, c: u32, phantom: core::marker::PhantomData<(ImplNone, ImplNone)>, } #[derive(Debug, Clone, Eq, PartialEq, Default, PartialOrd, Ord)] struct StructUnnamedRust(u32, u64, u32, core::marker::PhantomData<(ImplNone, ImplNone)>); #[test] fn struct_named_same_as_native_rust() { for (a, b, c) in combinations() { let a_1 = StructNamed:: { a, b, c, phantom: Default::default() }; let b_1 = StructNamedRust { a, b, c, phantom: Default::default() }; for (a, b, c) in combinations() { let a_2 = StructNamed:: { a, b, c, phantom: Default::default() }; let b_2 = StructNamedRust { a, b, c, phantom: Default::default() }; assert_eq!(a_1.partial_cmp(&a_2), b_1.partial_cmp(&b_2)); assert_eq!(a_1.cmp(&a_2), b_1.cmp(&b_2)); assert_eq!(a_1.eq(&a_2), b_1.eq(&b_2)); } } } #[test] fn struct_unnamed_same_as_native_rust() { for (a, b, c) in combinations() { let a_1 = StructUnnamed::(a, b, c, Default::default()); let b_1 = StructUnnamedRust(a, b, c, Default::default()); for (a, b, c) in combinations() { let a_2 = StructUnnamed::(a, b, c, Default::default()); let b_2 = StructUnnamedRust(a, b, c, Default::default()); assert_eq!(a_1.partial_cmp(&a_2), b_1.partial_cmp(&b_2)); assert_eq!(a_1.cmp(&a_2), b_1.cmp(&b_2)); assert_eq!(a_1.eq(&a_2), b_1.eq(&b_2)); } } }