//! These tests are common between different deserialization methods use serde::Deserialize; use serde_teamspeak_querystring::{from_str, ErrorKind}; /// It is a helper struct we use to test primitive types /// as we don't support anything beside maps/structs at the root level #[derive(Debug, PartialEq, Deserialize)] struct Primitive { value: T, } impl Primitive { pub fn new(value: T) -> Self { Self { value } } } macro_rules! p { ($value:expr, $type: ty) => { Primitive::<$type>::new($value) }; ($value:expr) => { Primitive::new($value) }; } #[test] fn deserialize_integer_valid() { // u8 assert_eq!(from_str("value=255"), Ok(p!(255_u8))); assert_eq!(from_str("value=0"), Ok(p!(0_u8))); // i8 assert_eq!(from_str("value=127"), Ok(p!(127_i8))); assert_eq!(from_str("value=-128"), Ok(p!(-128_i8))); // u16 assert_eq!(from_str("value=65535"), Ok(p!(65535_u16))); assert_eq!(from_str("value=0"), Ok(p!(0_u16))); // i16 assert_eq!(from_str("value=32767"), Ok(p!(32767_i16))); assert_eq!(from_str("value=-32768"), Ok(p!(-32768_i16))); // u32 assert_eq!(from_str("value=4294967295"), Ok(p!(4294967295_u32))); assert_eq!(from_str("value=0"), Ok(p!(0_u32))); // i32 assert_eq!(from_str("value=2147483647"), Ok(p!(2147483647_i32))); assert_eq!(from_str("value=-2147483648"), Ok(p!(-2147483648_i32))); // u64 assert_eq!( from_str("value=18446744073709551615"), Ok(p!(18446744073709551615_u64)) ); assert_eq!(from_str("value=0"), Ok(p!(0_u64))); // i64 assert_eq!( from_str("value=9223372036854775807"), Ok(p!(9223372036854775807_i64)) ); assert_eq!( from_str("value=-9223372036854775808"), Ok(p!(-9223372036854775808_i64)) ); } #[test] fn deserialize_float_valid() { assert_eq!(from_str("value=1.2"), Ok(p!(1.2_f64))); assert_eq!(from_str("value=-1.2"), Ok(p!(-1.2_f64))); assert_eq!(from_str("value=1.2E5"), Ok(p!(1.2E5_f64))); assert_eq!(from_str("value=-1.2E5"), Ok(p!(-1.2E5_f64))); assert_eq!(from_str("value=1.2E-5"), Ok(p!(1.2E-5_f64))); assert_eq!(from_str("value=-1.2E-5"), Ok(p!(-1.2E-5_f64))); assert_eq!( from_str("value=18446744073709551616"), Ok(p!(18446744073709551616_f64)) ); assert_eq!( from_str("value=-18446744073709551616"), Ok(p!(-18446744073709551616_f64)) ); } /// Check if different boolean idents work #[test] fn deserialize_bool() { // true assert_eq!(from_str("value=1"), Ok(p!(true))); assert_eq!(from_str("value=on"), Ok(p!(true))); assert_eq!(from_str("value=true"), Ok(p!(true))); // false assert_eq!(from_str("value=0"), Ok(p!(false))); assert_eq!(from_str("value=off"), Ok(p!(false))); assert_eq!(from_str("value=false"), Ok(p!(false))); } /// Check if we can directly deserialize non percent encoded values to str #[test] fn deserialize_str() { assert_eq!(from_str("value=test"), Ok(p!("test"))); // We don't make assumptions about numbers assert_eq!(from_str("value=250"), Ok(p!("250"))); assert_eq!(from_str("value=-25"), Ok(p!("-25"))); } #[test] fn deserialize_strings() { assert_eq!(from_str("value=foo"), Ok(p!("foo".to_string()))); // percent decoded /*assert_eq!( from_str("value=%D8%A8%D8%A7%D8%A8%D8%A7%D8%A8%D8%B2%D8%B1%DA%AF"), Ok(p!("بابابزرگ".to_string())) );*/ assert_eq!( from_str(r#"value=بابابزرگr+-*%1\s\s\s\s143\s\/\\"#), Ok(p!(r#"بابابزرگr+-*%1 143 /\"#.to_string())) ); // Plus in strings should be replaced with space assert_eq!(from_str("value=rum+rum"), Ok(p!("rum+rum".to_string()))); } #[test] fn deserialize_option() { assert_eq!(from_str("value=1337"), Ok(p!(Some(1337), Option))); assert_eq!(from_str("value="), Ok(p!(None, Option))); assert_eq!(from_str("value=1337 value="), Ok(p!(None, Option))); } #[test] fn deserialize_new_type() { #[derive(Debug, Deserialize, Eq, PartialEq)] struct NewType(i32); assert_eq!(from_str("value=-2500000"), Ok(p!(NewType(-2_500_000)))); } #[test] fn deserialize_extra_ampersands() { assert_eq!(from_str(" value=bar"), Ok(p!("bar"))); assert_eq!(from_str("value=bar "), Ok(p!("bar"))); assert_eq!(from_str("value=bar value=baz"), Ok(p!("baz"))); } #[test] fn deserialize_no_value() { assert_eq!(from_str("value"), Ok(p!(""))); assert_eq!(from_str("value"), Ok(p!(true))); assert_eq!(from_str("value"), Ok(p!(()))); assert_eq!(from_str("value="), Ok(p!(""))); assert_eq!(from_str("value="), Ok(p!(true))); assert_eq!(from_str("value="), Ok(p!(()))); assert_eq!(from_str("value"), Ok(p!(None, Option))); assert_eq!(from_str("value="), Ok(p!(None, Option))); // We could see this as an empty string too, but to keep it the same as // other types, we go with None assert_eq!(from_str("value="), Ok(p!(None, Option<&str>))); } #[test] fn deserialize_integer_overflow() { // u8 assert!(from_str::>("value=-10").is_err()); assert!(from_str::>("value=260").is_err()); // i8 assert!(from_str::>("value=255").is_err()); assert!(from_str::>("value=-200").is_err()); // // u16 assert!(from_str::>("value=65537").is_err()); assert!(from_str::>("value=-200").is_err()); // // i16 assert!(from_str::>("value=32768").is_err()); assert!(from_str::>("value=-32769").is_err()); // // u32 assert!(from_str::>("value=4294967296").is_err()); assert!(from_str::>("value=-200").is_err()); // // i32 assert!(from_str::>("value=2147483648").is_err()); assert!(from_str::>("value=-2147483649").is_err()); // // u64 assert!(from_str::>("value=18446744073709551616").is_err()); assert!(from_str::>("value=-200").is_err()); // // i64 assert!(from_str::>("value=9223372036854775808").is_err()); assert!(from_str::>("value=-9223372036854775809").is_err()); // // invalid for integer assert!(from_str::>("value=1.5").is_err()); assert!(from_str::>("value=-1.5").is_err()); assert!(from_str::>("value=1.2E3").is_err()); assert!(from_str::>("value=1.2E-3").is_err()); } #[test] fn deserialize_invalid_number() { assert!(from_str::>("value=number").is_err()); assert!(from_str::>("value=123n").is_err()); assert!(from_str::>("value=number").is_err()); assert!(from_str::>("value=-1.5num").is_err()); assert!(from_str::>("value= ").is_err()); assert!(from_str::>("value=1.0a1.0").is_err()); } /// Check if different boolean idents work #[test] fn deserialize_invalid_bool() { assert!(from_str::>("value=bla").is_err()); assert!(from_str::>("value=0off").is_err()); assert!(from_str::>("value=of").is_err()); assert!(from_str::>("value=onoff").is_err()); } #[test] fn deserialize_invalid_type() { // Percent encoded values should fail to deserialize for &str /*assert!( from_str::>("value=%D8%A8%D8%A7%D8%A8%D8%A7%D8%A8%D8%B2%D8%B1%DA%AF") .is_err() ); assert!(from_str::>("value=rum+rum").is_err());*/ // Invalid type for option assert!(from_str::>>("value=foo").is_err()); assert!(from_str::>>("value=foo").is_err()); // Only struct/map accepted as start point assert!(from_str::("value").is_err()); } /*#[test] fn deserialize_invalid_precent_decoding() { assert!(from_str::>("value=Test%88").is_err()); }*/ #[test] fn deserialize_error_test() { assert_eq!( from_str::>("value=12 value=13 value=14") .unwrap_err() .kind, ErrorKind::InvalidLength ); // Changed i32 to () according by rustc #[derive(Debug, Deserialize)] struct Tuple((), ()); assert_eq!( from_str::>("value=12 value=13 value=14") .unwrap_err() .kind, ErrorKind::InvalidLength ); /*assert_eq!( from_str::>("value=Test%88%88") .unwrap_err() .kind, ErrorKind::InvalidEncoding );*/ assert_eq!( from_str::>("value=12foo").unwrap_err().kind, ErrorKind::InvalidNumber ); assert_eq!( from_str::>("value=foo").unwrap_err().kind, ErrorKind::InvalidBoolean ); #[derive(Debug, Deserialize)] enum ValueEnum { A((), ()), B(()), C {}, } assert_eq!( from_str::>("value=A") .unwrap_err() .kind, ErrorKind::UnexpectedType ); assert_eq!( from_str::>("value=B") .unwrap_err() .kind, ErrorKind::UnexpectedType ); assert_eq!( from_str::>("value=C") .unwrap_err() .kind, ErrorKind::UnexpectedType ); }