diff options
Diffstat (limited to 'third_party/rust/serde_yaml/tests')
-rw-r--r-- | third_party/rust/serde_yaml/tests/test_de.rs | 396 | ||||
-rw-r--r-- | third_party/rust/serde_yaml/tests/test_error.rs | 287 | ||||
-rw-r--r-- | third_party/rust/serde_yaml/tests/test_serde.rs | 434 | ||||
-rw-r--r-- | third_party/rust/serde_yaml/tests/test_value.rs | 55 |
4 files changed, 1172 insertions, 0 deletions
diff --git a/third_party/rust/serde_yaml/tests/test_de.rs b/third_party/rust/serde_yaml/tests/test_de.rs new file mode 100644 index 0000000000..e3a8c0da12 --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_de.rs @@ -0,0 +1,396 @@ +#![allow( + clippy::cast_lossless, + clippy::cast_possible_wrap, + clippy::derive_partial_eq_without_eq +)] + +use indoc::indoc; +use serde_derive::Deserialize; +use serde_yaml::Value; +use std::collections::BTreeMap; +use std::fmt::Debug; + +fn test_de<T>(yaml: &str, expected: &T) +where + T: serde::de::DeserializeOwned + PartialEq + Debug, +{ + let deserialized: T = serde_yaml::from_str(yaml).unwrap(); + assert_eq!(*expected, deserialized); + + serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap(); + serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap(); +} + +fn test_de_seed<T, S>(yaml: &str, seed: S, expected: &T) +where + T: PartialEq + Debug, + S: for<'de> serde::de::DeserializeSeed<'de, Value = T>, +{ + let deserialized: T = serde_yaml::seed::from_str_seed(yaml, seed).unwrap(); + assert_eq!(*expected, deserialized); + + serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap(); + serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap(); +} + +#[test] +fn test_alias() { + let yaml = indoc! {" + --- + first: + &alias + 1 + second: + *alias + third: 3 + "}; + let mut expected = BTreeMap::new(); + { + expected.insert(String::from("first"), 1); + expected.insert(String::from("second"), 1); + expected.insert(String::from("third"), 3); + } + test_de(yaml, &expected); +} + +#[test] +fn test_option() { + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: Option<f64>, + b: Option<String>, + c: Option<bool>, + } + let yaml = indoc! {" + --- + b: + c: true + "}; + let expected = Data { + a: None, + b: None, + c: Some(true), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_option_alias() { + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: Option<f64>, + b: Option<String>, + c: Option<bool>, + d: Option<f64>, + e: Option<String>, + f: Option<bool>, + } + let yaml = indoc! {" + --- + none_f: + &none_f + ~ + none_s: + &none_s + ~ + none_b: + &none_b + ~ + + some_f: + &some_f + 1.0 + some_s: + &some_s + x + some_b: + &some_b + true + + a: *none_f + b: *none_s + c: *none_b + d: *some_f + e: *some_s + f: *some_b + "}; + let expected = Data { + a: None, + b: None, + c: None, + d: Some(1.0), + e: Some("x".to_owned()), + f: Some(true), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_enum_alias() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + A, + B(u8, u8), + } + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: E, + b: E, + } + let yaml = indoc! {" + --- + aref: + &aref + A + bref: + &bref + B: + - 1 + - 2 + + a: *aref + b: *bref + "}; + let expected = Data { + a: E::A, + b: E::B(1, 2), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_enum_tag() { + #[derive(Deserialize, PartialEq, Debug)] + enum E { + A(String), + B(String), + } + #[derive(Deserialize, PartialEq, Debug)] + struct Data { + a: E, + b: E, + } + let yaml = indoc! {" + --- + a: !A foo + b: !B bar + "}; + let expected = Data { + a: E::A("foo".into()), + b: E::B("bar".into()), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_number_as_string() { + #[derive(Deserialize, PartialEq, Debug)] + struct Num { + value: String, + } + let yaml = indoc! {" + --- + # Cannot be represented as u128 + value: 340282366920938463463374607431768211457 + "}; + let expected = Num { + value: "340282366920938463463374607431768211457".to_owned(), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_i128_big() { + let expected: i128 = ::std::i64::MIN as i128 - 1; + let yaml = indoc! {" + --- + -9223372036854775809 + "}; + assert_eq!(expected, serde_yaml::from_str::<i128>(yaml).unwrap()); +} + +#[test] +fn test_u128_big() { + let expected: u128 = ::std::u64::MAX as u128 + 1; + let yaml = indoc! {" + --- + 18446744073709551616 + "}; + assert_eq!(expected, serde_yaml::from_str::<u128>(yaml).unwrap()); +} + +#[test] +fn test_number_alias_as_string() { + #[derive(Deserialize, PartialEq, Debug)] + struct Num { + version: String, + value: String, + } + let yaml = indoc! {" + --- + version: &a 1.10 + value: *a + "}; + let expected = Num { + version: "1.10".to_owned(), + value: "1.10".to_owned(), + }; + test_de(yaml, &expected); +} + +#[test] +fn test_de_mapping() { + #[derive(Debug, Deserialize, PartialEq)] + struct Data { + pub substructure: serde_yaml::Mapping, + } + let yaml = indoc! {" + --- + substructure: + a: 'foo' + b: 'bar' + "}; + + let mut expected = Data { + substructure: serde_yaml::Mapping::new(), + }; + expected.substructure.insert( + serde_yaml::Value::String("a".to_owned()), + serde_yaml::Value::String("foo".to_owned()), + ); + expected.substructure.insert( + serde_yaml::Value::String("b".to_owned()), + serde_yaml::Value::String("bar".to_owned()), + ); + + test_de(yaml, &expected); +} + +#[test] +fn test_bomb() { + #[derive(Debug, Deserialize, PartialEq)] + struct Data { + expected: String, + } + + // This would deserialize an astronomical number of elements if we were + // vulnerable. + let yaml = indoc! {" + --- + a: &a ~ + b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a] + c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b] + d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c] + e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d] + f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e] + g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f] + h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g] + i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h] + j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i] + k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j] + l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k] + m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l] + n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m] + o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n] + p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o] + q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p] + r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q] + s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r] + t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s] + u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t] + v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u] + w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v] + x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w] + y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x] + z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y] + expected: string + "}; + + let expected = Data { + expected: "string".to_owned(), + }; + + assert_eq!(expected, serde_yaml::from_str::<Data>(yaml).unwrap()); +} + +#[test] +fn test_numbers() { + let cases = [ + ("0xF0", "240"), + ("+0xF0", "240"), + ("-0xF0", "-240"), + ("0o70", "56"), + ("+0o70", "56"), + ("-0o70", "-56"), + ("0b10", "2"), + ("+0b10", "2"), + ("-0b10", "-2"), + ("127", "127"), + ("+127", "127"), + ("-127", "-127"), + (".inf", ".inf"), + (".Inf", ".inf"), + (".INF", ".inf"), + ("-.inf", "-.inf"), + ("-.Inf", "-.inf"), + ("-.INF", "-.inf"), + (".nan", ".nan"), + (".NaN", ".nan"), + (".NAN", ".nan"), + ("0.1", "0.1"), + ]; + for &(yaml, expected) in &cases { + let value = serde_yaml::from_str::<Value>(yaml).unwrap(); + match value { + Value::Number(number) => assert_eq!(number.to_string(), expected), + _ => panic!("expected number. input={:?}, result={:?}", yaml, value), + } + } + + // NOT numbers. + let cases = ["0127", "+0127", "-0127"]; + for yaml in &cases { + let value = serde_yaml::from_str::<Value>(yaml).unwrap(); + match value { + Value::String(string) => assert_eq!(string, *yaml), + _ => panic!("expected string. input={:?}, result={:?}", yaml, value), + } + } +} + +#[test] +fn test_stateful() { + struct Seed(i64); + + impl<'de> serde::de::DeserializeSeed<'de> for Seed { + type Value = i64; + fn deserialize<D>(self, deserializer: D) -> Result<i64, D::Error> + where + D: serde::de::Deserializer<'de>, + { + struct Visitor(i64); + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = i64; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(formatter, "an integer") + } + + fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<i64, E> { + Ok(v * self.0) + } + + fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<i64, E> { + Ok(v as i64 * self.0) + } + } + + deserializer.deserialize_any(Visitor(self.0)) + } + } + + let cases = [("3", 5, 15), ("6", 7, 42), ("-5", 9, -45)]; + for &(yaml, seed, expected) in &cases { + test_de_seed(yaml, Seed(seed), &expected); + } +} diff --git a/third_party/rust/serde_yaml/tests/test_error.rs b/third_party/rust/serde_yaml/tests/test_error.rs new file mode 100644 index 0000000000..bd830c0fc0 --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_error.rs @@ -0,0 +1,287 @@ +use indoc::indoc; +use serde_derive::Deserialize; +use std::fmt::Debug; + +fn test_error<T>(yaml: &str, expected: &str) +where + T: serde::de::DeserializeOwned + Debug, +{ + let result = serde_yaml::from_str::<T>(yaml); + assert_eq!(expected, format!("{}", result.unwrap_err())); +} + +#[test] +fn test_incorrect_type() { + let yaml = indoc! {" + --- + str + "}; + let expected = "invalid type: string \"str\", expected i16 at line 2 column 1"; + test_error::<i16>(yaml, expected); +} + +#[test] +fn test_incorrect_nested_type() { + #[derive(Deserialize, Debug)] + struct A { + #[allow(dead_code)] + b: Vec<B>, + } + #[derive(Deserialize, Debug)] + enum B { + C(C), + } + #[derive(Deserialize, Debug)] + struct C { + #[allow(dead_code)] + d: bool, + } + let yaml = indoc! {" + --- + b: + - C: + d: fase + "}; + let expected = + "b[0].C.d: invalid type: string \"fase\", expected a boolean at line 4 column 10"; + test_error::<A>(yaml, expected); +} + +#[test] +fn test_empty() { + let expected = "EOF while parsing a value"; + test_error::<String>("", expected); +} + +#[test] +fn test_missing_field() { + #[derive(Deserialize, Debug)] + struct Basic { + #[allow(dead_code)] + v: bool, + #[allow(dead_code)] + w: bool, + } + let yaml = indoc! {" + --- + v: true + "}; + let expected = "missing field `w` at line 2 column 2"; + test_error::<Basic>(yaml, expected); +} + +#[test] +fn test_unknown_anchor() { + let yaml = indoc! {" + --- + *some + "}; + let expected = "while parsing node, found unknown anchor at line 2 column 1"; + test_error::<String>(yaml, expected); +} + +#[test] +fn test_ignored_unknown_anchor() { + #[derive(Deserialize, Debug)] + struct Wrapper { + #[allow(dead_code)] + c: (), + } + let yaml = indoc! {" + --- + b: [*a] + c: ~ + "}; + let expected = "while parsing node, found unknown anchor at line 2 column 5"; + test_error::<Wrapper>(yaml, expected); +} + +#[test] +fn test_two_documents() { + let yaml = indoc! {" + --- + 0 + --- + 1 + "}; + let expected = "deserializing from YAML containing more than one document is not supported"; + test_error::<usize>(yaml, expected); +} + +#[test] +fn test_variant_map_wrong_size() { + #[derive(Deserialize, Debug)] + enum E { + V(usize), + } + let yaml = indoc! {r#" + --- + "V": 16 + "other": 32 + "#}; + let expected = "invalid length 2, expected map containing 1 entry"; + test_error::<E>(yaml, expected); +} + +#[test] +fn test_variant_not_a_map() { + #[derive(Deserialize, Debug)] + enum E { + V(usize), + } + let yaml = indoc! {r#" + --- + - "V" + "#}; + let expected = "invalid type: sequence, expected string or singleton map at line 2 column 1"; + test_error::<E>(yaml, expected); +} + +#[test] +fn test_variant_not_string() { + #[derive(Deserialize, Debug)] + enum E { + V(bool), + } + let yaml = indoc! {r#" + --- + {}: true + "#}; + let expected = "invalid type: map, expected variant of enum `E` at line 2 column 1"; + test_error::<E>(yaml, expected); +} + +#[test] +fn test_bad_bool() { + let yaml = indoc! {" + --- + !!bool str + "}; + let expected = "invalid value: string \"str\", expected a boolean at line 2 column 8"; + test_error::<bool>(yaml, expected); +} + +#[test] +fn test_bad_int() { + let yaml = indoc! {" + --- + !!int str + "}; + let expected = "invalid value: string \"str\", expected an integer at line 2 column 7"; + test_error::<i64>(yaml, expected); +} + +#[test] +fn test_bad_float() { + let yaml = indoc! {" + --- + !!float str + "}; + let expected = "invalid value: string \"str\", expected a float at line 2 column 9"; + test_error::<f64>(yaml, expected); +} + +#[test] +fn test_bad_null() { + let yaml = indoc! {" + --- + !!null str + "}; + let expected = "invalid value: string \"str\", expected null at line 2 column 8"; + test_error::<()>(yaml, expected); +} + +#[test] +fn test_short_tuple() { + let yaml = indoc! {" + --- + [0, 0] + "}; + let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1"; + test_error::<(u8, u8, u8)>(yaml, expected); +} + +#[test] +fn test_long_tuple() { + let yaml = indoc! {" + --- + [0, 0, 0] + "}; + let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1"; + test_error::<(u8, u8)>(yaml, expected); +} + +#[test] +fn test_no_location() { + let invalid_utf8: Result<serde_yaml::Value, serde_yaml::Error> = + serde_yaml::from_slice(b"\x80\xae"); + + let utf8_location = invalid_utf8.unwrap_err().location(); + + assert!(utf8_location.is_none()); +} + +#[test] +fn test_invalid_scalar_type() { + #[derive(Deserialize, Debug)] + struct S { + #[allow(dead_code)] + x: [(); 1], + } + + let yaml = "x:\n"; + let expected = "x: invalid type: unit value, expected an array of length 1 at line 2 column 1"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_infinite_recursion_objects() { + #[derive(Deserialize, Debug)] + struct S { + #[allow(dead_code)] + x: Option<Box<S>>, + } + + let yaml = "&a {x: *a}"; + let expected = "recursion limit exceeded"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_infinite_recursion_arrays() { + #[derive(Deserialize, Debug)] + struct S { + #[allow(dead_code)] + x: Option<Box<S>>, + } + + let yaml = "&a [*a]"; + let expected = "recursion limit exceeded"; + test_error::<S>(yaml, expected); +} + +#[test] +fn test_finite_recursion_objects() { + #[derive(Deserialize, Debug)] + struct S { + #[allow(dead_code)] + x: Option<Box<S>>, + } + + let yaml = "{x:".repeat(1_000) + &"}".repeat(1_000); + let expected = "recursion limit exceeded at line 1 column 766"; + test_error::<i32>(&yaml, expected); +} + +#[test] +fn test_finite_recursion_arrays() { + #[derive(Deserialize, Debug)] + struct S { + #[allow(dead_code)] + x: Option<Box<S>>, + } + + let yaml = "[".repeat(1_000) + &"]".repeat(1_000); + let expected = "recursion limit exceeded at line 1 column 256"; + test_error::<S>(&yaml, expected); +} diff --git a/third_party/rust/serde_yaml/tests/test_serde.rs b/third_party/rust/serde_yaml/tests/test_serde.rs new file mode 100644 index 0000000000..8b3f34b3fc --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_serde.rs @@ -0,0 +1,434 @@ +#![allow( + clippy::decimal_literal_representation, + clippy::derive_partial_eq_without_eq, + clippy::unreadable_literal, + clippy::shadow_unrelated +)] + +use indoc::indoc; +use serde_derive::{Deserialize, Serialize}; +use serde_yaml::Value; +use std::collections::BTreeMap; +use std::f64; +use std::fmt::Debug; + +fn test_serde<T>(thing: &T, yaml: &str) +where + T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug, +{ + let serialized = serde_yaml::to_string(&thing).unwrap(); + assert_eq!(yaml, serialized); + + let value = serde_yaml::to_value(&thing).unwrap(); + let serialized = serde_yaml::to_string(&value).unwrap(); + assert_eq!(yaml, serialized); + + let deserialized: T = serde_yaml::from_str(yaml).unwrap(); + assert_eq!(*thing, deserialized); + + let value: Value = serde_yaml::from_str(yaml).unwrap(); + let deserialized: T = serde_yaml::from_value(value).unwrap(); + assert_eq!(*thing, deserialized); + + serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap(); +} + +#[test] +fn test_default() { + assert_eq!(Value::default(), Value::Null); +} + +#[test] +fn test_int() { + let thing = 256; + let yaml = indoc! {" + --- + 256 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_int_max_u64() { + let thing = ::std::u64::MAX; + let yaml = indoc! {" + --- + 18446744073709551615 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_int_min_i64() { + let thing = ::std::i64::MIN; + let yaml = indoc! {" + --- + -9223372036854775808 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_int_max_i64() { + let thing = ::std::i64::MAX; + let yaml = indoc! {" + --- + 9223372036854775807 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_i128_small() { + let thing: i128 = -256; + let yaml = indoc! {" + --- + -256 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_u128_small() { + let thing: u128 = 256; + let yaml = indoc! {" + --- + 256 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_float() { + let thing = 25.6; + let yaml = indoc! {" + --- + 25.6 + "}; + test_serde(&thing, yaml); + + let thing = 25.; + let yaml = indoc! {" + --- + 25.0 + "}; + test_serde(&thing, yaml); + + let thing = f64::INFINITY; + let yaml = indoc! {" + --- + .inf + "}; + test_serde(&thing, yaml); + + let thing = f64::NEG_INFINITY; + let yaml = indoc! {" + --- + -.inf + "}; + test_serde(&thing, yaml); + + let float: f64 = serde_yaml::from_str(indoc! {" + --- + .nan + "}) + .unwrap(); + assert!(float.is_nan()); +} + +#[test] +fn test_float32() { + let thing: f32 = 25.6; + let yaml = indoc! {" + --- + 25.6 + "}; + test_serde(&thing, yaml); + + let thing = f32::INFINITY; + let yaml = indoc! {" + --- + .inf + "}; + test_serde(&thing, yaml); + + let thing = f32::NEG_INFINITY; + let yaml = indoc! {" + --- + -.inf + "}; + test_serde(&thing, yaml); + + let single_float: f32 = serde_yaml::from_str(indoc! {" + --- + .nan + "}) + .unwrap(); + assert!(single_float.is_nan()); +} + +#[test] +fn test_vec() { + let thing = vec![1, 2, 3]; + let yaml = indoc! {" + --- + - 1 + - 2 + - 3 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_map() { + let mut thing = BTreeMap::new(); + thing.insert(String::from("x"), 1); + thing.insert(String::from("y"), 2); + let yaml = indoc! {" + --- + x: 1 + y: 2 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_basic_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Basic { + x: isize, + y: String, + z: bool, + } + let thing = Basic { + x: -4, + y: String::from("hi\tquoted"), + z: true, + }; + let yaml = indoc! {r#" + --- + x: -4 + y: "hi\tquoted" + z: true + "#}; + test_serde(&thing, yaml); +} + +#[test] +fn test_nested_vec() { + let thing = vec![vec![1, 2, 3], vec![4, 5, 6]]; + let yaml = indoc! {" + --- + - - 1 + - 2 + - 3 + - - 4 + - 5 + - 6 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_nested_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Outer { + inner: Inner, + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Inner { + v: u16, + } + let thing = Outer { + inner: Inner { v: 512 }, + }; + let yaml = indoc! {" + --- + inner: + v: 512 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_option() { + let thing = vec![Some(1), None, Some(3)]; + let yaml = indoc! {" + --- + - 1 + - ~ + - 3 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_unit() { + let thing = vec![(), ()]; + let yaml = indoc! {" + --- + - ~ + - ~ + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_unit_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Foo; + let thing = Foo; + let yaml = indoc! {" + --- + ~ + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_unit_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + First, + Second, + } + let thing = Variant::First; + let yaml = indoc! {" + --- + First + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_newtype_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct OriginalType { + v: u16, + } + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct NewType(OriginalType); + let thing = NewType(OriginalType { v: 1 }); + let yaml = indoc! {" + --- + v: 1 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_newtype_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Size(usize), + } + let thing = Variant::Size(127); + let yaml = indoc! {" + --- + Size: 127 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_tuple_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Rgb(u8, u8, u8), + } + let thing = Variant::Rgb(32, 64, 96); + let yaml = indoc! {" + --- + Rgb: + - 32 + - 64 + - 96 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_struct_variant() { + #[derive(Serialize, Deserialize, PartialEq, Debug)] + enum Variant { + Color { r: u8, g: u8, b: u8 }, + } + let thing = Variant::Color { + r: 32, + g: 64, + b: 96, + }; + let yaml = indoc! {" + --- + Color: + r: 32 + g: 64 + b: 96 + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_value() { + use serde_yaml::{Mapping, Number}; + + #[derive(Serialize, Deserialize, PartialEq, Debug)] + pub struct GenericInstructions { + #[serde(rename = "type")] + pub typ: String, + pub config: Value, + } + let thing = GenericInstructions { + typ: "primary".to_string(), + config: Value::Sequence(vec![ + Value::Null, + Value::Bool(true), + Value::Number(Number::from(65535)), + Value::Number(Number::from(0.54321)), + Value::String("s".into()), + Value::Mapping(Mapping::new()), + ]), + }; + let yaml = indoc! {" + --- + type: primary + config: + - ~ + - true + - 65535 + - 0.54321 + - s + - {} + "}; + test_serde(&thing, yaml); +} + +#[test] +fn test_mapping() { + use serde_yaml::Mapping; + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Data { + pub substructure: Mapping, + } + + let mut thing = Data { + substructure: Mapping::new(), + }; + thing.substructure.insert( + Value::String("a".to_owned()), + Value::String("foo".to_owned()), + ); + thing.substructure.insert( + Value::String("b".to_owned()), + Value::String("bar".to_owned()), + ); + + let yaml = indoc! {" + --- + substructure: + a: foo + b: bar + "}; + + test_serde(&thing, yaml); +} diff --git a/third_party/rust/serde_yaml/tests/test_value.rs b/third_party/rust/serde_yaml/tests/test_value.rs new file mode 100644 index 0000000000..c001b9d73d --- /dev/null +++ b/third_party/rust/serde_yaml/tests/test_value.rs @@ -0,0 +1,55 @@ +#![allow(clippy::derive_partial_eq_without_eq, clippy::eq_op)] + +use serde::de::IntoDeserializer; +use serde::Deserialize; +use serde_derive::Deserialize; +use serde_yaml::{Number, Value}; +use std::f64; + +#[test] +fn test_nan() { + let pos_nan = serde_yaml::from_str::<Value>(".nan").unwrap(); + assert!(pos_nan.is_f64()); + assert_eq!(pos_nan, pos_nan); + + let neg_fake_nan = serde_yaml::from_str::<Value>("-.nan").unwrap(); + assert!(neg_fake_nan.is_string()); + + let significand_mask = 0xF_FFFF_FFFF_FFFF; + let bits = (f64::NAN.to_bits() ^ significand_mask) | 1; + let different_pos_nan = Value::Number(Number::from(f64::from_bits(bits))); + assert_eq!(pos_nan, different_pos_nan); +} + +#[test] +fn test_digits() { + let num_string = serde_yaml::from_str::<Value>("01").unwrap(); + assert!(num_string.is_string()); +} + +#[test] +fn test_into_deserializer() { + #[derive(Debug, Deserialize, PartialEq)] + struct Test { + first: String, + second: u32, + } + + let value = serde_yaml::from_str::<Value>("xyz").unwrap(); + let s = String::deserialize(value.into_deserializer()).unwrap(); + assert_eq!(s, "xyz"); + + let value = serde_yaml::from_str::<Value>("- first\n- second\n- third").unwrap(); + let arr = Vec::<String>::deserialize(value.into_deserializer()).unwrap(); + assert_eq!(arr, &["first", "second", "third"]); + + let value = serde_yaml::from_str::<Value>("first: abc\nsecond: 99").unwrap(); + let test = Test::deserialize(value.into_deserializer()).unwrap(); + assert_eq!( + test, + Test { + first: "abc".to_string(), + second: 99 + } + ); +} |