use super::*;
use crate::{
test_utils::{
check_formatting_equivalence,
},
nonexhaustive_enum::{
GetEnumInfo,
examples::{
command_a,
command_b,
command_c,
command_h_mismatched_discriminant,
command_serde,
generic_a,
many_ranges_a,
many_ranges_b,
},
},
};
use core_extensions::SelfOps;
use std::{
cmp::{Ord, Ordering, PartialEq, PartialOrd},
collections::hash_map::DefaultHasher,
hash::{Hash,Hasher},
sync::Arc,
};
#[test]
fn construct_deconstruct(){
{
use self::command_a::{Foo as FooA};
let mut variant_a=NonExhaustive::new(FooA::A);
let mut variant_b=NonExhaustive::new(FooA::B(11));
assert_eq!(variant_a.as_enum(), Ok(&FooA::A));
assert_eq!(variant_b.as_enum(), Ok(&FooA::B(11)));
assert_eq!(variant_a.as_enum_mut(), Ok(&mut FooA::A));
assert_eq!(variant_b.as_enum_mut(), Ok(&mut FooA::B(11)));
assert_eq!(variant_a.into_enum(), Ok(FooA::A));
assert_eq!(variant_b.into_enum(), Ok(FooA::B(11)));
}
{
use self::command_b::{Foo as FooB};
let mut variant_a=NonExhaustive::new(FooB::A);
let mut variant_b=NonExhaustive::new(FooB::B(11));
let mut variant_c=NonExhaustive::new(FooB::C);
assert_eq!(variant_a.as_enum(), Ok(&FooB::A));
assert_eq!(variant_b.as_enum(), Ok(&FooB::B(11)));
assert_eq!(variant_c.as_enum(), Ok(&FooB::C));
assert_eq!(variant_a.as_enum_mut(), Ok(&mut FooB::A));
assert_eq!(variant_b.as_enum_mut(), Ok(&mut FooB::B(11)));
assert_eq!(variant_c.as_enum_mut(), Ok(&mut FooB::C));
assert_eq!(variant_a.into_enum(), Ok(FooB::A));
assert_eq!(variant_b.into_enum(), Ok(FooB::B(11)));
assert_eq!(variant_c.into_enum(), Ok(FooB::C));
}
}
#[test]
fn get_discriminant(){
{
use self::command_c::Foo as FooC;
let wrapped_a=NonExhaustive::new(FooC::A);
let wrapped_b=NonExhaustive::new(FooC::B(11));
let wrapped_c=NonExhaustive::new(FooC::C);
let wrapped_d=NonExhaustive::new(FooC::D{name:"what".into()});
assert_eq!(wrapped_a.get_discriminant(),0);
assert_eq!(wrapped_b.get_discriminant(),1);
assert_eq!(wrapped_c.get_discriminant(),2);
assert_eq!(wrapped_d.get_discriminant(),3);
}
{
use self::command_h_mismatched_discriminant::Foo;
let wrapped_a=NonExhaustive::new(Foo::A);
let wrapped_b=NonExhaustive::new(Foo::B);
let wrapped_c=NonExhaustive::new(Foo::C);
assert_eq!(wrapped_a.get_discriminant(),40);
assert_eq!(wrapped_b.get_discriminant(),41);
assert_eq!(wrapped_c.get_discriminant(),42);
}
}
#[test]
fn is_valid_discriminant(){
{
use self::command_c::Foo as FooC;
assert_eq!(FooC::is_valid_discriminant(0),true);
assert_eq!(FooC::is_valid_discriminant(1),true);
assert_eq!(FooC::is_valid_discriminant(2),true);
assert_eq!(FooC::is_valid_discriminant(3),true);
assert_eq!(FooC::is_valid_discriminant(4),false);
assert_eq!(FooC::is_valid_discriminant(5),false);
}
{
use self::command_h_mismatched_discriminant::Foo;
assert_eq!(Foo::is_valid_discriminant(0),false);
assert_eq!(Foo::is_valid_discriminant(39),false);
assert_eq!(Foo::is_valid_discriminant(40),true);
assert_eq!(Foo::is_valid_discriminant(41),true);
assert_eq!(Foo::is_valid_discriminant(42),true);
assert_eq!(Foo::is_valid_discriminant(43),false);
assert_eq!(Foo::is_valid_discriminant(44),false);
}
{
use self::many_ranges_a::Foo;
assert_eq!(Foo::is_valid_discriminant(0),true);
assert_eq!(Foo::is_valid_discriminant(1),false);
assert_eq!(Foo::is_valid_discriminant(2),false);
assert_eq!(Foo::is_valid_discriminant(39),false);
assert_eq!(Foo::is_valid_discriminant(40),true);
assert_eq!(Foo::is_valid_discriminant(41),true);
assert_eq!(Foo::is_valid_discriminant(42),true);
assert_eq!(Foo::is_valid_discriminant(43),false);
assert_eq!(Foo::is_valid_discriminant(44),false);
assert_eq!(Foo::is_valid_discriminant(58),false);
assert_eq!(Foo::is_valid_discriminant(59),false);
assert_eq!(Foo::is_valid_discriminant(60),true);
assert_eq!(Foo::is_valid_discriminant(61),true);
assert_eq!(Foo::is_valid_discriminant(62),false);
assert_eq!(Foo::is_valid_discriminant(63),false);
}
{
use self::many_ranges_b::Foo;
assert_eq!(Foo::is_valid_discriminant(0),true);
assert_eq!(Foo::is_valid_discriminant(1),false);
assert_eq!(Foo::is_valid_discriminant(2),false);
assert_eq!(Foo::is_valid_discriminant(39),false);
assert_eq!(Foo::is_valid_discriminant(40),true);
assert_eq!(Foo::is_valid_discriminant(41),true);
assert_eq!(Foo::is_valid_discriminant(42),false);
assert_eq!(Foo::is_valid_discriminant(43),false);
assert_eq!(Foo::is_valid_discriminant(58),false);
assert_eq!(Foo::is_valid_discriminant(59),false);
assert_eq!(Foo::is_valid_discriminant(60),true);
assert_eq!(Foo::is_valid_discriminant(62),false);
assert_eq!(Foo::is_valid_discriminant(63),false);
}
}
#[test]
fn transmuting_enums(){
unsafe{
use self::command_a::{Foo as FooA};
use self::command_c::{Foo as FooC};
let mut variant_a=NonExhaustive::new(FooC::A).transmute_enum::<FooA>();
let mut variant_b=NonExhaustive::new(FooC::B(11)).transmute_enum::<FooA>();
let mut variant_c=NonExhaustive::new(FooC::C).transmute_enum::<FooA>();
let mut variant_d=FooC::D{name:"what".into()}
.piped(NonExhaustive::new)
.transmute_enum::<FooA>();
assert_eq!(variant_c.is_valid_discriminant(), false);
assert_eq!(variant_d.is_valid_discriminant(), false);
assert_eq!(variant_a.as_enum(), Ok(&FooA::A));
assert_eq!(variant_b.as_enum(), Ok(&FooA::B(11)));
assert_eq!(variant_c.as_enum().ok(), None);
assert_eq!(variant_d.as_enum().ok(), None);
assert_eq!(variant_a.as_enum_mut(), Ok(&mut FooA::A));
assert_eq!(variant_b.as_enum_mut(), Ok(&mut FooA::B(11)));
assert_eq!(variant_c.as_enum_mut().ok(), None);
assert_eq!(variant_d.as_enum_mut().ok(), None);
assert_eq!(variant_a.into_enum(), Ok(FooA::A));
assert_eq!(variant_b.into_enum(), Ok(FooA::B(11)));
assert_eq!(variant_c.into_enum().ok(), None);
assert_eq!(variant_d.into_enum().ok(), None);
}
}
#[test]
fn clone_test(){
use self::generic_a::Foo;
let arc=Arc::new(100);
assert_eq!(Arc::strong_count(&arc), 1);
let variant_a=NonExhaustive::new(Foo::<Arc<i32>>::A);
let variant_b=NonExhaustive::new(Foo::<Arc<i32>>::B);
let variant_c=NonExhaustive::new(Foo::<Arc<i32>>::C(arc.clone()));
assert_eq!(Arc::strong_count(&arc), 2);
assert_eq!(variant_a.clone(), variant_a);
assert_eq!(variant_b.clone(), variant_b);
{
let clone_c=variant_c.clone();
assert_eq!(Arc::strong_count(&arc), 3);
assert_eq!(clone_c, variant_c);
}
assert_eq!(Arc::strong_count(&arc), 2);
assert_eq!(variant_a.clone(), Foo::A);
assert_eq!(variant_b.clone(), Foo::B);
{
let clone_c=variant_c.clone();
assert_eq!(Arc::strong_count(&arc), 3);
assert_eq!(clone_c.clone(), Foo::C(arc.clone()));
}
assert_eq!(Arc::strong_count(&arc), 2);
drop(variant_c);
assert_eq!(Arc::strong_count(&arc), 1);
}
#[test]
fn fmt_test(){
use self::command_serde::{Foo as FooC};
let variant_a=FooC::A;
let wrapped_a=NonExhaustive::new(variant_a.clone());
let variant_b=FooC::B(11);
let wrapped_b=NonExhaustive::new(variant_b.clone());
let variant_c=FooC::C;
let wrapped_c=NonExhaustive::new(variant_c.clone());
let variant_d=FooC::D{name:"what".into()};
let wrapped_d=NonExhaustive::new(variant_d.clone());
check_formatting_equivalence(&variant_a,&wrapped_a);
check_formatting_equivalence(&variant_b,&wrapped_b);
check_formatting_equivalence(&variant_c,&wrapped_c);
check_formatting_equivalence(&variant_d,&wrapped_d);
}
#[test]
fn cmp_test(){
use self::generic_a::Foo;
let variant_a=Foo::<String>::A;
let wrapped_a=NonExhaustive::new(variant_a.clone());
let variant_b=Foo::<String>::B;
let wrapped_b=NonExhaustive::new(variant_b.clone());
let variant_c=Foo::<String>::C("what".into());
let wrapped_c=NonExhaustive::new(variant_c.clone());
for wrapped in vec![&wrapped_a,&wrapped_b,&wrapped_c] {
assert_eq!(wrapped.cmp(&wrapped), Ordering::Equal);
}
assert_eq!(wrapped_a.cmp(&wrapped_b), Ordering::Less);
assert_eq!(wrapped_b.cmp(&wrapped_c), Ordering::Less);
macro_rules! cmp_tests {
(
loop_variables=$variant:ident,$wrapped:ident,$which_one:ident;
var_b=$var_b:ident;
var_c=$var_c:ident;
) => (
#[allow(unused_variables)]
for ($variant,$wrapped) in
vec![(&variant_a,&wrapped_a),(&variant_b,&wrapped_b),(&variant_c,&wrapped_c)]
{
assert_eq!($wrapped == $which_one, true);
assert_eq!($wrapped <= $which_one, true);
assert_eq!($wrapped >= $which_one, true );
assert_eq!($wrapped < $which_one, false);
assert_eq!($wrapped > $which_one, false);
assert_eq!($wrapped != $which_one, false);
assert_eq!($wrapped.partial_cmp($which_one), Some(Ordering::Equal));
assert_eq!($wrapped.eq($which_one), true);
assert_eq!($wrapped.ne($which_one), false);
}
assert_eq!(wrapped_a == $var_b, false);
assert_eq!(wrapped_a <= $var_b, true);
assert_eq!(wrapped_a >= $var_b, false);
assert_eq!(wrapped_a < $var_b, true);
assert_eq!(wrapped_a > $var_b, false);
assert_eq!(wrapped_a != $var_b, true);
assert_eq!(wrapped_a.partial_cmp(&$var_b), Some(Ordering::Less));
assert_eq!(wrapped_a.eq(&$var_b), false);
assert_eq!(wrapped_a.ne(&$var_b), true);
assert_eq!(wrapped_b == $var_c, false);
assert_eq!(wrapped_b <= $var_c, true);
assert_eq!(wrapped_b >= $var_c, false);
assert_eq!(wrapped_b < $var_c, true);
assert_eq!(wrapped_b > $var_c, false);
assert_eq!(wrapped_b != $var_c, true);
assert_eq!(wrapped_b.partial_cmp(&$var_c), Some(Ordering::Less));
assert_eq!(wrapped_b.eq(&$var_c), false);
assert_eq!(wrapped_b.ne(&$var_c), true);
)
}
cmp_tests!{
loop_variables=variant,wrapped,variant;
var_b=variant_b;
var_c=variant_c;
}
cmp_tests!{
loop_variables=variant,wrapped,wrapped;
var_b=wrapped_b;
var_c=wrapped_c;
}
}
#[test]
fn hash_test(){
use self::generic_a::Foo;
fn hash_value<H:Hash>(v:&H)->u64{
let mut hasher=DefaultHasher::new();
v.hash(&mut hasher);
hasher.finish()
}
let variant_a=Foo::<String>::A;
let wrapped_a=NonExhaustive::new(variant_a.clone());
let variant_b=Foo::<String>::B;
let wrapped_b=NonExhaustive::new(variant_b.clone());
let variant_c=Foo::<String>::C("what".into());
let wrapped_c=NonExhaustive::new(variant_c.clone());
for (variant,wrapped) in
vec![(&variant_a,&wrapped_a),(&variant_b,&wrapped_b),(&variant_c,&wrapped_c)]
{
assert_eq!(hash_value(variant),hash_value(wrapped));
}
}
#[test]
fn serde_test() {
use self::command_serde::{Foo as FooC};
let variant_a=FooC::A;
let variant_b=FooC::B(10);
let variant_c=FooC::C;
let variant_d=FooC::D{name:"what".into()};
let expected_a=NonExhaustive::new(variant_a.clone());
let expected_b=NonExhaustive::new(variant_b.clone());
let expected_c=NonExhaustive::new(variant_c.clone());
let expected_d=NonExhaustive::new(variant_d.clone());
let json_a=r#""A""#;
let json_dd_a=serde_json::to_string(&json_a).unwrap();
let json_b=r#"{"B":10}"#;
let json_dd_b=serde_json::to_string(&json_b).unwrap();
let json_c=r#""C""#;
let json_dd_c=serde_json::to_string(&json_c).unwrap();
let json_d=r#"{"D":{"name":"what"}}"#;
let json_dd_d=serde_json::to_string(&json_d).unwrap();
assert_eq!(
serde_json::from_str::<NonExhaustiveFor<FooC>>(r#" "oinoiasnd" "#).map_err(drop),
Err(()),
);
assert_eq!(
NonExhaustiveFor::<FooC>::deserialize_from_proxy(
r#"oinoiasnd"#.into()
).map_err(drop),
Err(()),
);
for (json_dd,json,expected,variant) in
vec![
(&*json_dd_a,json_a,&expected_a,&variant_a),
(&*json_dd_b,json_b,&expected_b,&variant_b),
(&*json_dd_c,json_c,&expected_c,&variant_c),
(&*json_dd_d,json_d,&expected_d,&variant_d),
]
{
{
let deserialized=serde_json::from_str::<NonExhaustiveFor<FooC>>(json_dd).unwrap();
assert_eq!(deserialized,*expected);
assert_eq!(deserialized,*variant);
}
{
let deserialized=
NonExhaustiveFor::<FooC>::deserialize_from_proxy(json.into()).unwrap();
assert_eq!(deserialized,*expected);
assert_eq!(deserialized,*variant);
}
assert_eq!(&*serde_json::to_string(&expected).unwrap(), json_dd);
assert_eq!(&*expected.serialize_into_proxy().unwrap(), json);
assert_eq!(&*serde_json::to_string(&variant).unwrap(), json);
}
}