chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

717
vendor/serde_yaml/tests/test_de.rs vendored Normal file
View File

@@ -0,0 +1,717 @@
#![allow(
clippy::cast_lossless,
clippy::cast_possible_wrap,
clippy::derive_partial_eq_without_eq,
clippy::similar_names,
clippy::uninlined_format_args
)]
use indoc::indoc;
use serde_derive::Deserialize;
use serde_yaml::{Deserializer, Number, 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);
let value: Value = serde_yaml::from_str(yaml).unwrap();
let deserialized = T::deserialize(&value).unwrap();
assert_eq!(*expected, deserialized);
let deserialized: T = serde_yaml::from_value(value).unwrap();
assert_eq!(*expected, deserialized);
serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
let mut deserializer = Deserializer::from_str(yaml);
let document = deserializer.next().unwrap();
let deserialized = T::deserialize(document).unwrap();
assert_eq!(*expected, deserialized);
assert!(deserializer.next().is_none());
}
fn test_de_no_value<'de, T>(yaml: &'de str, expected: &T)
where
T: serde::de::Deserialize<'de> + 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<'de, T, S>(yaml: &'de str, seed: S, expected: &T)
where
T: PartialEq + Debug,
S: serde::de::DeserializeSeed<'de, Value = T>,
{
let deserialized: T = seed.deserialize(Deserializer::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();
}
#[test]
fn test_borrowed() {
let yaml = indoc! {"
- plain nonàscii
- 'single quoted'
- \"double quoted\"
"};
let expected = vec!["plain nonàscii", "single quoted", "double quoted"];
test_de_no_value(yaml, &expected);
}
#[test]
fn test_alias() {
let yaml = indoc! {"
first:
&alias
1
second:
*alias
third: 3
"};
let mut expected = BTreeMap::new();
expected.insert("first".to_owned(), 1);
expected.insert("second".to_owned(), 1);
expected.insert("third".to_owned(), 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_representations() {
#[derive(Deserialize, PartialEq, Debug)]
enum Enum {
Unit,
Tuple(i32, i32),
Struct { x: i32, y: i32 },
String(String),
Number(f64),
}
let yaml = indoc! {"
- Unit
- 'Unit'
- !Unit
- !Unit ~
- !Unit null
- !Tuple [0, 0]
- !Tuple
- 0
- 0
- !Struct {x: 0, y: 0}
- !Struct
x: 0
y: 0
- !String '...'
- !String ...
- !Number 0
"};
let expected = vec![
Enum::Unit,
Enum::Unit,
Enum::Unit,
Enum::Unit,
Enum::Unit,
Enum::Tuple(0, 0),
Enum::Tuple(0, 0),
Enum::Struct { x: 0, y: 0 },
Enum::Struct { x: 0, y: 0 },
Enum::String("...".to_owned()),
Enum::String("...".to_owned()),
Enum::Number(0.0),
];
test_de(yaml, &expected);
let yaml = indoc! {"
- !String
"};
let expected = vec![Enum::String(String::new())];
test_de_no_value(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_no_value(yaml, &expected);
}
#[test]
fn test_empty_string() {
#[derive(Deserialize, PartialEq, Debug)]
struct Struct {
empty: String,
tilde: String,
}
let yaml = indoc! {"
empty:
tilde: ~
"};
let expected = Struct {
empty: String::new(),
tilde: "~".to_owned(),
};
test_de_no_value(yaml, &expected);
}
#[test]
fn test_i128_big() {
let expected: i128 = i64::MIN as i128 - 1;
let yaml = indoc! {"
-9223372036854775809
"};
assert_eq!(expected, serde_yaml::from_str::<i128>(yaml).unwrap());
let octal = indoc! {"
-0o1000000000000000000001
"};
assert_eq!(expected, serde_yaml::from_str::<i128>(octal).unwrap());
}
#[test]
fn test_u128_big() {
let expected: u128 = u64::MAX as u128 + 1;
let yaml = indoc! {"
18446744073709551616
"};
assert_eq!(expected, serde_yaml::from_str::<u128>(yaml).unwrap());
let octal = indoc! {"
0o2000000000000000000000
"};
assert_eq!(expected, serde_yaml::from_str::<u128>(octal).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_no_value(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_byte_order_mark() {
let yaml = "\u{feff}- 0\n";
let expected = vec![0];
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", "++.inf", "+-.inf", "++1", "+-1", "-+1", "--1", "0x+1", "0x-1",
"-0x+1", "-0x-1", "++0x1", "+-0x1", "-+0x1", "--0x1",
];
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_nan() {
// There is no negative NaN in YAML.
assert!(serde_yaml::from_str::<f32>(".nan")
.unwrap()
.is_sign_positive());
assert!(serde_yaml::from_str::<f64>(".nan")
.unwrap()
.is_sign_positive());
}
#[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);
}
}
#[test]
fn test_ignore_tag() {
#[derive(Deserialize, Debug, PartialEq)]
struct Data {
struc: Struc,
tuple: Tuple,
newtype: Newtype,
map: BTreeMap<char, usize>,
vec: Vec<usize>,
}
#[derive(Deserialize, Debug, PartialEq)]
struct Struc {
x: usize,
}
#[derive(Deserialize, Debug, PartialEq)]
struct Tuple(usize, usize);
#[derive(Deserialize, Debug, PartialEq)]
struct Newtype(usize);
let yaml = indoc! {"
struc: !wat
x: 0
tuple: !wat
- 0
- 0
newtype: !wat 0
map: !wat
x: 0
vec: !wat
- 0
"};
let expected = Data {
struc: Struc { x: 0 },
tuple: Tuple(0, 0),
newtype: Newtype(0),
map: {
let mut map = BTreeMap::new();
map.insert('x', 0);
map
},
vec: vec![0],
};
test_de(yaml, &expected);
}
#[test]
fn test_no_required_fields() {
#[derive(Deserialize, PartialEq, Debug)]
pub struct NoRequiredFields {
optional: Option<usize>,
}
for document in ["", "# comment\n"] {
let expected = NoRequiredFields { optional: None };
let deserialized: NoRequiredFields = serde_yaml::from_str(document).unwrap();
assert_eq!(expected, deserialized);
let expected = Vec::<String>::new();
let deserialized: Vec<String> = serde_yaml::from_str(document).unwrap();
assert_eq!(expected, deserialized);
let expected = BTreeMap::new();
let deserialized: BTreeMap<char, usize> = serde_yaml::from_str(document).unwrap();
assert_eq!(expected, deserialized);
let expected = None;
let deserialized: Option<String> = serde_yaml::from_str(document).unwrap();
assert_eq!(expected, deserialized);
let expected = Value::Null;
let deserialized: Value = serde_yaml::from_str(document).unwrap();
assert_eq!(expected, deserialized);
}
}
#[test]
fn test_empty_scalar() {
#[derive(Deserialize, PartialEq, Debug)]
struct Struct<T> {
thing: T,
}
let yaml = "thing:\n";
let expected = Struct {
thing: serde_yaml::Sequence::new(),
};
test_de(yaml, &expected);
let expected = Struct {
thing: serde_yaml::Mapping::new(),
};
test_de(yaml, &expected);
}
#[test]
fn test_python_safe_dump() {
#[derive(Deserialize, PartialEq, Debug)]
struct Frob {
foo: u32,
}
// This matches output produced by PyYAML's `yaml.safe_dump` when using the
// default_style parameter.
//
// >>> import yaml
// >>> d = {"foo": 7200}
// >>> print(yaml.safe_dump(d, default_style="|"))
// "foo": !!int |-
// 7200
//
let yaml = indoc! {r#"
"foo": !!int |-
7200
"#};
let expected = Frob { foo: 7200 };
test_de(yaml, &expected);
}
#[test]
fn test_tag_resolution() {
// https://yaml.org/spec/1.2.2/#1032-tag-resolution
let yaml = indoc! {"
- null
- Null
- NULL
- ~
-
- true
- True
- TRUE
- false
- False
- FALSE
- y
- Y
- yes
- Yes
- YES
- n
- N
- no
- No
- NO
- on
- On
- ON
- off
- Off
- OFF
"};
let expected = vec![
Value::Null,
Value::Null,
Value::Null,
Value::Null,
Value::Null,
Value::Bool(true),
Value::Bool(true),
Value::Bool(true),
Value::Bool(false),
Value::Bool(false),
Value::Bool(false),
Value::String("y".to_owned()),
Value::String("Y".to_owned()),
Value::String("yes".to_owned()),
Value::String("Yes".to_owned()),
Value::String("YES".to_owned()),
Value::String("n".to_owned()),
Value::String("N".to_owned()),
Value::String("no".to_owned()),
Value::String("No".to_owned()),
Value::String("NO".to_owned()),
Value::String("on".to_owned()),
Value::String("On".to_owned()),
Value::String("ON".to_owned()),
Value::String("off".to_owned()),
Value::String("Off".to_owned()),
Value::String("OFF".to_owned()),
];
test_de(yaml, &expected);
}
#[test]
fn test_parse_number() {
let n = "111".parse::<Number>().unwrap();
assert_eq!(n, Number::from(111));
let n = "-111".parse::<Number>().unwrap();
assert_eq!(n, Number::from(-111));
let n = "-1.1".parse::<Number>().unwrap();
assert_eq!(n, Number::from(-1.1));
let n = ".nan".parse::<Number>().unwrap();
assert_eq!(n, Number::from(f64::NAN));
assert!(n.as_f64().unwrap().is_sign_positive());
let n = ".inf".parse::<Number>().unwrap();
assert_eq!(n, Number::from(f64::INFINITY));
let n = "-.inf".parse::<Number>().unwrap();
assert_eq!(n, Number::from(f64::NEG_INFINITY));
let err = "null".parse::<Number>().unwrap_err();
assert_eq!(err.to_string(), "failed to parse YAML number");
let err = " 1 ".parse::<Number>().unwrap_err();
assert_eq!(err.to_string(), "failed to parse YAML number");
}

500
vendor/serde_yaml/tests/test_error.rs vendored Normal file
View File

@@ -0,0 +1,500 @@
#![allow(clippy::zero_sized_map_values)]
use indoc::indoc;
use serde::de::Deserialize;
#[cfg(not(miri))]
use serde::de::{SeqAccess, Visitor};
use serde_derive::{Deserialize, Serialize};
use serde_yaml::value::{Tag, TaggedValue};
use serde_yaml::{Deserializer, Value};
#[cfg(not(miri))]
use std::collections::BTreeMap;
#[cfg(not(miri))]
use std::fmt;
use std::fmt::Debug;
fn test_error<'de, T>(yaml: &'de str, expected: &str)
where
T: Deserialize<'de> + Debug,
{
let result = serde_yaml::from_str::<T>(yaml);
assert_eq!(expected, result.unwrap_err().to_string());
let mut deserializer = Deserializer::from_str(yaml);
if let Some(first_document) = deserializer.next() {
if deserializer.next().is_none() {
let result = T::deserialize(first_document);
assert_eq!(expected, result.unwrap_err().to_string());
}
}
}
#[test]
fn test_scan_error() {
let yaml = ">\n@";
let expected = "found character that cannot start any token at line 2 column 1, while scanning for the next token";
test_error::<Value>(yaml, expected);
}
#[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)]
pub struct A {
#[allow(dead_code)]
pub b: Vec<B>,
}
#[derive(Deserialize, Debug)]
pub enum B {
C(#[allow(dead_code)] C),
}
#[derive(Deserialize, Debug)]
pub struct C {
#[allow(dead_code)]
pub d: bool,
}
let yaml = indoc! {"
b:
- !C
d: fase
"};
let expected = "b[0].d: invalid type: string \"fase\", expected a boolean at line 3 column 8";
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)]
pub struct Basic {
#[allow(dead_code)]
pub v: bool,
#[allow(dead_code)]
pub w: bool,
}
let yaml = indoc! {"
---
v: true
"};
let expected = "missing field `w` at line 2 column 1";
test_error::<Basic>(yaml, expected);
}
#[test]
fn test_unknown_anchor() {
let yaml = indoc! {"
---
*some
"};
let expected = "unknown anchor at line 2 column 1";
test_error::<String>(yaml, expected);
}
#[test]
fn test_ignored_unknown_anchor() {
#[derive(Deserialize, Debug)]
pub struct Wrapper {
#[allow(dead_code)]
pub c: (),
}
let yaml = indoc! {"
b: [*a]
c: ~
"};
let expected = "unknown anchor at line 1 column 5";
test_error::<Wrapper>(yaml, expected);
}
#[test]
fn test_bytes() {
let expected = "serialization and deserialization of bytes in YAML is not implemented";
test_error::<&[u8]>("...", 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_second_document_syntax_error() {
let yaml = indoc! {"
---
0
---
]
"};
let mut de = Deserializer::from_str(yaml);
let first_doc = de.next().unwrap();
let result = <usize as serde::Deserialize>::deserialize(first_doc);
assert_eq!(0, result.unwrap());
let second_doc = de.next().unwrap();
let result = <usize as serde::Deserialize>::deserialize(second_doc);
let expected =
"did not find expected node content at line 4 column 1, while parsing a block node";
assert_eq!(expected, result.unwrap_err().to_string());
}
#[test]
fn test_missing_enum_tag() {
#[derive(Deserialize, Debug)]
pub enum E {
V(#[allow(dead_code)] usize),
}
let yaml = indoc! {r#"
"V": 16
"other": 32
"#};
let expected = "invalid type: map, expected a YAML tag starting with '!'";
test_error::<E>(yaml, expected);
}
#[test]
fn test_serialize_nested_enum() {
#[derive(Serialize, Debug)]
pub enum Outer {
Inner(Inner),
}
#[derive(Serialize, Debug)]
pub enum Inner {
Newtype(usize),
Tuple(usize, usize),
Struct { x: usize },
}
let expected = "serializing nested enums in YAML is not supported yet";
let e = Outer::Inner(Inner::Newtype(0));
let error = serde_yaml::to_string(&e).unwrap_err();
assert_eq!(error.to_string(), expected);
let e = Outer::Inner(Inner::Tuple(0, 0));
let error = serde_yaml::to_string(&e).unwrap_err();
assert_eq!(error.to_string(), expected);
let e = Outer::Inner(Inner::Struct { x: 0 });
let error = serde_yaml::to_string(&e).unwrap_err();
assert_eq!(error.to_string(), expected);
let e = Value::Tagged(Box::new(TaggedValue {
tag: Tag::new("Outer"),
value: Value::Tagged(Box::new(TaggedValue {
tag: Tag::new("Inner"),
value: Value::Null,
})),
}));
let error = serde_yaml::to_string(&e).unwrap_err();
assert_eq!(error.to_string(), expected);
}
#[test]
fn test_deserialize_nested_enum() {
#[derive(Deserialize, Debug)]
pub enum Outer {
Inner(#[allow(dead_code)] Inner),
}
#[derive(Deserialize, Debug)]
pub enum Inner {
Variant(#[allow(dead_code)] Vec<usize>),
}
let yaml = indoc! {"
---
!Inner []
"};
let expected = "deserializing nested enum in Outer::Inner from YAML is not supported yet at line 2 column 1";
test_error::<Outer>(yaml, expected);
let yaml = indoc! {"
---
!Variant []
"};
let expected = "unknown variant `Variant`, expected `Inner`";
test_error::<Outer>(yaml, expected);
let yaml = indoc! {"
---
!Inner !Variant []
"};
let expected = "deserializing nested enum in Outer::Inner from YAML is not supported yet at line 2 column 1";
test_error::<Outer>(yaml, expected);
}
#[test]
fn test_variant_not_a_seq() {
#[derive(Deserialize, Debug)]
pub enum E {
V(#[allow(dead_code)] usize),
}
let yaml = indoc! {"
---
!V
value: 0
"};
let expected = "invalid type: map, expected usize at line 2 column 1";
test_error::<E>(yaml, expected);
}
#[test]
fn test_struct_from_sequence() {
#[derive(Deserialize, Debug)]
pub struct Struct {
#[allow(dead_code)]
pub x: usize,
#[allow(dead_code)]
pub y: usize,
}
let yaml = indoc! {"
[0, 0]
"};
let expected = "invalid type: sequence, expected struct Struct";
test_error::<Struct>(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 1";
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 1";
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 1";
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 1";
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_invalid_scalar_type() {
#[derive(Deserialize, Debug)]
pub struct S {
#[allow(dead_code)]
pub x: [i32; 1],
}
let yaml = "x: ''\n";
let expected = "x: invalid type: string \"\", expected an array of length 1 at line 1 column 4";
test_error::<S>(yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_objects() {
#[derive(Deserialize, Debug)]
pub struct S {
#[allow(dead_code)]
pub x: Option<Box<S>>,
}
let yaml = "&a {'x': *a}";
let expected = "recursion limit exceeded";
test_error::<S>(yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_arrays() {
#[derive(Deserialize, Debug)]
pub struct S(
#[allow(dead_code)] pub usize,
#[allow(dead_code)] pub Option<Box<S>>,
);
let yaml = "&a [0, *a]";
let expected = "recursion limit exceeded";
test_error::<S>(yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_infinite_recursion_newtype() {
#[derive(Deserialize, Debug)]
pub struct S(#[allow(dead_code)] pub Option<Box<S>>);
let yaml = "&a [*a]";
let expected = "recursion limit exceeded";
test_error::<S>(yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_finite_recursion_objects() {
#[derive(Deserialize, Debug)]
pub struct S {
#[allow(dead_code)]
pub x: Option<Box<S>>,
}
let yaml = "{'x':".repeat(1_000) + &"}".repeat(1_000);
let expected = "recursion limit exceeded at line 1 column 641";
test_error::<S>(&yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_finite_recursion_arrays() {
#[derive(Deserialize, Debug)]
pub struct S(
#[allow(dead_code)] pub usize,
#[allow(dead_code)] pub Option<Box<S>>,
);
let yaml = "[0, ".repeat(1_000) + &"]".repeat(1_000);
let expected = "recursion limit exceeded at line 1 column 513";
test_error::<S>(&yaml, expected);
}
#[cfg(not(miri))]
#[test]
fn test_billion_laughs() {
#[derive(Debug)]
struct X;
impl<'de> Visitor<'de> for X {
type Value = X;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("exponential blowup")
}
fn visit_unit<E>(self) -> Result<X, E> {
Ok(X)
}
fn visit_seq<S>(self, mut seq: S) -> Result<X, S::Error>
where
S: SeqAccess<'de>,
{
while let Some(X) = seq.next_element()? {}
Ok(X)
}
}
impl<'de> Deserialize<'de> for X {
fn deserialize<D>(deserializer: D) -> Result<X, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(X)
}
}
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]
"};
let expected = "repetition limit exceeded";
test_error::<BTreeMap<String, X>>(yaml, expected);
}
#[test]
fn test_duplicate_keys() {
let yaml = indoc! {"
---
thing: true
thing: false
"};
let expected = "duplicate entry with key \"thing\" at line 2 column 1";
test_error::<Value>(yaml, expected);
let yaml = indoc! {"
---
null: true
~: false
"};
let expected = "duplicate entry with null key at line 2 column 1";
test_error::<Value>(yaml, expected);
let yaml = indoc! {"
---
99: true
99: false
"};
let expected = "duplicate entry with key 99 at line 2 column 1";
test_error::<Value>(yaml, expected);
let yaml = indoc! {"
---
{}: true
{}: false
"};
let expected = "duplicate entry in YAML map at line 2 column 1";
test_error::<Value>(yaml, expected);
}

578
vendor/serde_yaml/tests/test_serde.rs vendored Normal file
View File

@@ -0,0 +1,578 @@
#![allow(
clippy::decimal_literal_representation,
clippy::derive_partial_eq_without_eq,
clippy::unreadable_literal,
clippy::shadow_unrelated
)]
use indoc::indoc;
use serde::ser::SerializeMap;
use serde_derive::{Deserialize, Serialize};
use serde_yaml::{Mapping, Number, Value};
use std::collections::BTreeMap;
use std::fmt::Debug;
use std::iter;
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::deserialize(&value).unwrap();
assert_eq!(*thing, deserialized);
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 = u64::MAX;
let yaml = indoc! {"
18446744073709551615
"};
test_serde(&thing, yaml);
}
#[test]
fn test_int_min_i64() {
let thing = i64::MIN;
let yaml = indoc! {"
-9223372036854775808
"};
test_serde(&thing, yaml);
}
#[test]
fn test_int_max_i64() {
let thing = 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.5;
let yaml = indoc! {"
25.5
"};
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_char() {
let ch = '.';
let yaml = indoc! {"
'.'
"};
assert_eq!(yaml, serde_yaml::to_string(&ch).unwrap());
let ch = '#';
let yaml = indoc! {"
'#'
"};
assert_eq!(yaml, serde_yaml::to_string(&ch).unwrap());
let ch = '-';
let yaml = indoc! {"
'-'
"};
assert_eq!(yaml, serde_yaml::to_string(&ch).unwrap());
}
#[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("x".to_owned(), 1);
thing.insert("y".to_owned(), 2);
let yaml = indoc! {"
x: 1
y: 2
"};
test_serde(&thing, yaml);
}
#[test]
fn test_map_key_value() {
struct Map;
impl serde::Serialize for Map {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
// Test maps which do not serialize using serialize_entry.
let mut map = serializer.serialize_map(Some(1))?;
map.serialize_key("k")?;
map.serialize_value("v")?;
map.end()
}
}
let yaml = indoc! {"
k: v
"};
assert_eq!(yaml, serde_yaml::to_string(&Map).unwrap());
}
#[test]
fn test_basic_struct() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Basic {
x: isize,
y: String,
z: bool,
}
let thing = Basic {
x: -4,
y: "hi\tquoted".to_owned(),
z: true,
};
let yaml = indoc! {r#"
x: -4
y: "hi\tquoted"
z: true
"#};
test_serde(&thing, yaml);
}
#[test]
fn test_string_escapes() {
let yaml = indoc! {"
ascii
"};
test_serde(&"ascii".to_owned(), yaml);
let yaml = indoc! {r#"
"\0\a\b\t\n\v\f\r\e\"\\\N\L\P"
"#};
test_serde(
&"\0\u{7}\u{8}\t\n\u{b}\u{c}\r\u{1b}\"\\\u{85}\u{2028}\u{2029}".to_owned(),
yaml,
);
let yaml = indoc! {r#"
"\x1F\uFEFF"
"#};
test_serde(&"\u{1f}\u{feff}".to_owned(), yaml);
let yaml = indoc! {"
🎉
"};
test_serde(&"\u{1f389}".to_owned(), yaml);
}
#[test]
fn test_multiline_string() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Struct {
trailing_newline: String,
no_trailing_newline: String,
}
let thing = Struct {
trailing_newline: "aaa\nbbb\n".to_owned(),
no_trailing_newline: "aaa\nbbb".to_owned(),
};
let yaml = indoc! {"
trailing_newline: |
aaa
bbb
no_trailing_newline: |-
aaa
bbb
"};
test_serde(&thing, yaml);
}
#[test]
fn test_strings_needing_quote() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Struct {
boolean: String,
integer: String,
void: String,
leading_zeros: String,
}
let thing = Struct {
boolean: "true".to_owned(),
integer: "1".to_owned(),
void: "null".to_owned(),
leading_zeros: "007".to_owned(),
};
let yaml = indoc! {"
boolean: 'true'
integer: '1'
void: 'null'
leading_zeros: '007'
"};
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_nested_enum() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Outer {
Inner(Inner),
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Inner {
Unit,
}
let thing = Outer::Inner(Inner::Unit);
let yaml = indoc! {"
!Inner Unit
"};
test_serde(&thing, yaml);
}
#[test]
fn test_option() {
let thing = vec![Some(1), None, Some(3)];
let yaml = indoc! {"
- 1
- null
- 3
"};
test_serde(&thing, yaml);
}
#[test]
fn test_unit() {
let thing = vec![(), ()];
let yaml = indoc! {"
- null
- null
"};
test_serde(&thing, yaml);
}
#[test]
fn test_unit_struct() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Foo;
let thing = Foo;
let yaml = indoc! {"
null
"};
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_tagged_map_value() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Bindings {
profile: Profile,
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
enum Profile {
ClassValidator { class_name: String },
}
let thing = Bindings {
profile: Profile::ClassValidator {
class_name: "ApplicationConfig".to_owned(),
},
};
let yaml = indoc! {"
profile: !ClassValidator
class_name: ApplicationConfig
"};
test_serde(&thing, yaml);
}
#[test]
fn test_value() {
#[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:
- null
- true
- 65535
- 0.54321
- s
- {}
"};
test_serde(&thing, yaml);
}
#[test]
fn test_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);
}
#[test]
fn test_long_string() {
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct Data {
pub string: String,
}
let thing = Data {
string: iter::repeat(["word", " "]).flatten().take(69).collect(),
};
let yaml = indoc! {"
string: word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word
"};
test_serde(&thing, yaml);
}

153
vendor/serde_yaml/tests/test_value.rs vendored Normal file
View File

@@ -0,0 +1,153 @@
#![allow(
clippy::derive_partial_eq_without_eq,
clippy::eq_op,
clippy::uninlined_format_args
)]
use indoc::indoc;
use serde::de::IntoDeserializer;
use serde::Deserialize;
use serde_derive::{Deserialize, Serialize};
use serde_yaml::{Number, Value};
#[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.copysign(1.0).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
}
);
}
#[test]
fn test_merge() {
// From https://yaml.org/type/merge.html.
let yaml = indoc! {"
---
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }
# All the following maps are equal:
- # Explicit keys
x: 1
y: 2
r: 10
label: center/big
- # Merge one map
<< : *CENTER
r: 10
label: center/big
- # Merge multiple maps
<< : [ *CENTER, *BIG ]
label: center/big
- # Override
<< : [ *BIG, *LEFT, *SMALL ]
x: 1
label: center/big
"};
let mut value: Value = serde_yaml::from_str(yaml).unwrap();
value.apply_merge().unwrap();
for i in 5..=7 {
assert_eq!(value[4], value[i]);
}
}
#[test]
fn test_debug() {
let yaml = indoc! {"
'Null': ~
Bool: true
Number: 1
String: ...
Sequence:
- true
EmptySequence: []
EmptyMapping: {}
Tagged: !tag true
"};
let value: Value = serde_yaml::from_str(yaml).unwrap();
let debug = format!("{:#?}", value);
let expected = indoc! {r#"
Mapping {
"Null": Null,
"Bool": Bool(true),
"Number": Number(1),
"String": String("..."),
"Sequence": Sequence [
Bool(true),
],
"EmptySequence": Sequence [],
"EmptyMapping": Mapping {},
"Tagged": TaggedValue {
tag: !tag,
value: Bool(true),
},
}"#
};
assert_eq!(debug, expected);
}
#[test]
fn test_tagged() {
#[derive(Serialize)]
enum Enum {
Variant(usize),
}
let value = serde_yaml::to_value(&Enum::Variant(0)).unwrap();
let deserialized: serde_yaml::Value = serde_yaml::from_value(value.clone()).unwrap();
assert_eq!(value, deserialized);
let serialized = serde_yaml::to_value(&value).unwrap();
assert_eq!(value, serialized);
}