summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_yaml/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/serde_yaml/tests
parentInitial commit. (diff)
downloadfirefox-esr-upstream.tar.xz
firefox-esr-upstream.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--third_party/rust/serde_yaml/tests/test_de.rs396
-rw-r--r--third_party/rust/serde_yaml/tests/test_error.rs287
-rw-r--r--third_party/rust/serde_yaml/tests/test_serde.rs434
-rw-r--r--third_party/rust/serde_yaml/tests/test_value.rs55
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
+ }
+ );
+}