summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_json/tests/test.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/serde_json/tests/test.rs')
-rw-r--r--third_party/rust/serde_json/tests/test.rs245
1 files changed, 171 insertions, 74 deletions
diff --git a/third_party/rust/serde_json/tests/test.rs b/third_party/rust/serde_json/tests/test.rs
index f62a545e7f..7e6adad76f 100644
--- a/third_party/rust/serde_json/tests/test.rs
+++ b/third_party/rust/serde_json/tests/test.rs
@@ -5,7 +5,9 @@
clippy::derive_partial_eq_without_eq,
clippy::excessive_precision,
clippy::float_cmp,
+ clippy::incompatible_msrv, // https://github.com/rust-lang/rust-clippy/issues/12257
clippy::items_after_statements,
+ clippy::let_underscore_untyped,
clippy::shadow_unrelated,
clippy::too_many_lines,
clippy::unreadable_literal,
@@ -13,9 +15,6 @@
clippy::vec_init_then_push,
clippy::zero_sized_map_values
)]
-#![cfg_attr(feature = "trace-macros", feature(trace_macros))]
-#[cfg(feature = "trace-macros")]
-trace_macros!(true);
#[macro_use]
mod macros;
@@ -32,27 +31,25 @@ use serde_json::{
from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value,
to_vec, Deserializer, Number, Value,
};
-use std::collections::hash_map::DefaultHasher;
use std::collections::BTreeMap;
#[cfg(feature = "raw_value")]
use std::collections::HashMap;
use std::fmt::{self, Debug};
+use std::hash::BuildHasher;
+#[cfg(feature = "raw_value")]
use std::hash::{Hash, Hasher};
use std::io;
use std::iter;
use std::marker::PhantomData;
use std::mem;
use std::str::FromStr;
-use std::string::ToString;
use std::{f32, f64};
-use std::{i16, i32, i64, i8};
-use std::{u16, u32, u64, u8};
macro_rules! treemap {
() => {
BTreeMap::new()
};
- ($($k:expr => $v:expr),+) => {
+ ($($k:expr => $v:expr),+ $(,)?) => {
{
let mut m = BTreeMap::new();
$(
@@ -159,16 +156,28 @@ fn test_write_f64() {
#[test]
fn test_encode_nonfinite_float_yields_null() {
- let v = to_value(::std::f64::NAN).unwrap();
+ let v = to_value(f64::NAN.copysign(1.0)).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(f64::NAN.copysign(-1.0)).unwrap();
assert!(v.is_null());
- let v = to_value(::std::f64::INFINITY).unwrap();
+ let v = to_value(f64::INFINITY).unwrap();
assert!(v.is_null());
- let v = to_value(::std::f32::NAN).unwrap();
+ let v = to_value(-f64::INFINITY).unwrap();
assert!(v.is_null());
- let v = to_value(::std::f32::INFINITY).unwrap();
+ let v = to_value(f32::NAN.copysign(1.0)).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(f32::NAN.copysign(-1.0)).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(f32::INFINITY).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(-f32::INFINITY).unwrap();
assert!(v.is_null());
}
@@ -263,7 +272,7 @@ fn test_write_object() {
(
treemap!(
"a".to_string() => true,
- "b".to_string() => false
+ "b".to_string() => false,
),
"{\"a\":true,\"b\":false}",
),
@@ -274,7 +283,7 @@ fn test_write_object() {
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
"{\"a\":{},\"b\":{},\"c\":{}}",
),
@@ -283,10 +292,10 @@ fn test_write_object() {
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
"{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}",
),
@@ -296,9 +305,9 @@ fn test_write_object() {
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
"{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}",
),
@@ -309,8 +318,8 @@ fn test_write_object() {
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
- ]
+ "c".to_string() => treemap![],
+ ],
],
"{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}",
),
@@ -323,7 +332,7 @@ fn test_write_object() {
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
pretty_str!({
"a": {},
@@ -336,10 +345,10 @@ fn test_write_object() {
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
pretty_str!({
"a": {
@@ -363,9 +372,9 @@ fn test_write_object() {
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
- "c".to_string() => treemap![]
+ "c".to_string() => treemap![],
],
pretty_str!({
"a": {},
@@ -390,8 +399,8 @@ fn test_write_object() {
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
- "c".to_string() => treemap![]
- ]
+ "c".to_string() => treemap![],
+ ],
],
pretty_str!({
"a": {},
@@ -422,7 +431,7 @@ fn test_write_object() {
(
treemap!(
"a".to_string() => true,
- "b".to_string() => false
+ "b".to_string() => false,
),
pretty_str!( {
"a": true,
@@ -1191,8 +1200,8 @@ fn test_parse_object() {
treemap!(
"a".to_string() => treemap!(
"b".to_string() => 3u64,
- "c".to_string() => 4
- )
+ "c".to_string() => 4,
+ ),
),
)]);
@@ -1368,7 +1377,7 @@ fn test_parse_enum() {
),
treemap!(
"a".to_string() => Animal::Dog,
- "b".to_string() => Animal::Frog("Henry".to_string(), vec![])
+ "b".to_string() => Animal::Frog("Henry".to_string(), vec![]),
),
)]);
}
@@ -1451,7 +1460,6 @@ fn test_serialize_seq_with_no_len() {
where
T: ser::Serialize,
{
- #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
@@ -1478,7 +1486,6 @@ fn test_serialize_seq_with_no_len() {
formatter.write_str("array")
}
- #[inline]
fn visit_unit<E>(self) -> Result<MyVec<T>, E>
where
E: de::Error,
@@ -1486,7 +1493,6 @@ fn test_serialize_seq_with_no_len() {
Ok(MyVec(Vec::new()))
}
- #[inline]
fn visit_seq<V>(self, mut visitor: V) -> Result<MyVec<T>, V::Error>
where
V: de::SeqAccess<'de>,
@@ -1537,7 +1543,6 @@ fn test_serialize_map_with_no_len() {
K: ser::Serialize + Ord,
V: ser::Serialize,
{
- #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
@@ -1565,7 +1570,6 @@ fn test_serialize_map_with_no_len() {
formatter.write_str("map")
}
- #[inline]
fn visit_unit<E>(self) -> Result<MyMap<K, V>, E>
where
E: de::Error,
@@ -1573,7 +1577,6 @@ fn test_serialize_map_with_no_len() {
Ok(MyMap(BTreeMap::new()))
}
- #[inline]
fn visit_map<Visitor>(self, mut visitor: Visitor) -> Result<MyMap<K, V>, Visitor::Error>
where
Visitor: de::MapAccess<'de>,
@@ -1660,22 +1663,11 @@ fn test_deserialize_from_stream() {
}
#[test]
-fn test_serialize_rejects_bool_keys() {
- let map = treemap!(
- true => 2,
- false => 4
- );
-
- let err = to_vec(&map).unwrap_err();
- assert_eq!(err.to_string(), "key must be a string");
-}
-
-#[test]
fn test_serialize_rejects_adt_keys() {
let map = treemap!(
Some("a") => 2,
Some("b") => 4,
- None => 6
+ None => 6,
);
let err = to_vec(&map).unwrap_err();
@@ -1889,23 +1881,41 @@ fn test_integer_key() {
// map with integer keys
let map = treemap!(
1 => 2,
- -1 => 6
+ -1 => 6,
);
let j = r#"{"-1":6,"1":2}"#;
test_encode_ok(&[(&map, j)]);
test_parse_ok(vec![(j, map)]);
- let j = r#"{"x":null}"#;
- test_parse_err::<BTreeMap<i32, ()>>(&[(
- j,
- "invalid type: string \"x\", expected i32 at line 1 column 4",
- )]);
+ test_parse_err::<BTreeMap<i32, ()>>(&[
+ (
+ r#"{"x":null}"#,
+ "invalid value: expected key to be a number in quotes at line 1 column 2",
+ ),
+ (
+ r#"{" 123":null}"#,
+ "invalid value: expected key to be a number in quotes at line 1 column 2",
+ ),
+ (r#"{"123 ":null}"#, "expected `\"` at line 1 column 6"),
+ ]);
+
+ let err = from_value::<BTreeMap<i32, ()>>(json!({" 123":null})).unwrap_err();
+ assert_eq!(
+ err.to_string(),
+ "invalid value: expected key to be a number in quotes",
+ );
+
+ let err = from_value::<BTreeMap<i32, ()>>(json!({"123 ":null})).unwrap_err();
+ assert_eq!(
+ err.to_string(),
+ "invalid value: expected key to be a number in quotes",
+ );
}
#[test]
fn test_integer128_key() {
let map = treemap! {
- 100000000000000000000000000000000000000u128 => ()
+ 100000000000000000000000000000000000000u128 => (),
};
let j = r#"{"100000000000000000000000000000000000000":null}"#;
assert_eq!(to_string(&map).unwrap(), j);
@@ -1913,24 +1923,107 @@ fn test_integer128_key() {
}
#[test]
-fn test_deny_float_key() {
- #[derive(Eq, PartialEq, Ord, PartialOrd)]
+fn test_float_key() {
+ #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)]
struct Float;
impl Serialize for Float {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
- serializer.serialize_f32(1.0)
+ serializer.serialize_f32(1.23)
+ }
+ }
+ impl<'de> Deserialize<'de> for Float {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ f32::deserialize(deserializer).map(|_| Float)
}
}
// map with float key
- let map = treemap!(Float => "x");
+ let map = treemap!(Float => "x".to_owned());
+ let j = r#"{"1.23":"x"}"#;
+
+ test_encode_ok(&[(&map, j)]);
+ test_parse_ok(vec![(j, map)]);
+
+ let j = r#"{"x": null}"#;
+ test_parse_err::<BTreeMap<Float, ()>>(&[(
+ j,
+ "invalid value: expected key to be a number in quotes at line 1 column 2",
+ )]);
+}
+
+#[test]
+fn test_deny_non_finite_f32_key() {
+ // We store float bits so that we can derive Ord, and other traits. In a
+ // real context the code might involve a crate like ordered-float.
+
+ #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)]
+ struct F32Bits(u32);
+ impl Serialize for F32Bits {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_f32(f32::from_bits(self.0))
+ }
+ }
+
+ let map = treemap!(F32Bits(f32::INFINITY.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
+
+ let map = treemap!(F32Bits(f32::NEG_INFINITY.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
+
+ let map = treemap!(F32Bits(f32::NAN.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
assert!(serde_json::to_value(map).is_err());
}
#[test]
+fn test_deny_non_finite_f64_key() {
+ // We store float bits so that we can derive Ord, and other traits. In a
+ // real context the code might involve a crate like ordered-float.
+
+ #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)]
+ struct F64Bits(u64);
+ impl Serialize for F64Bits {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_f64(f64::from_bits(self.0))
+ }
+ }
+
+ let map = treemap!(F64Bits(f64::INFINITY.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
+
+ let map = treemap!(F64Bits(f64::NEG_INFINITY.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
+
+ let map = treemap!(F64Bits(f64::NAN.to_bits()) => "x".to_owned());
+ assert!(serde_json::to_string(&map).is_err());
+ assert!(serde_json::to_value(map).is_err());
+}
+
+#[test]
+fn test_boolean_key() {
+ let map = treemap!(false => 0, true => 1);
+ let j = r#"{"false":0,"true":1}"#;
+ test_encode_ok(&[(&map, j)]);
+ test_parse_ok(vec![(j, map)]);
+}
+
+#[test]
fn test_borrowed_key() {
let map: BTreeMap<&str, ()> = from_str("{\"borrowed\":null}").unwrap();
let expected = treemap! { "borrowed" => () };
@@ -1953,7 +2046,7 @@ fn test_effectively_string_keys() {
}
let map = treemap! {
Enum::One => 1,
- Enum::Two => 2
+ Enum::Two => 2,
};
let expected = r#"{"One":1,"Two":2}"#;
test_encode_ok(&[(&map, expected)]);
@@ -1963,7 +2056,7 @@ fn test_effectively_string_keys() {
struct Wrapper(String);
let map = treemap! {
Wrapper("zero".to_owned()) => 0,
- Wrapper("one".to_owned()) => 1
+ Wrapper("one".to_owned()) => 1,
};
let expected = r#"{"one":1,"zero":0}"#;
test_encode_ok(&[(&map, expected)]);
@@ -2145,8 +2238,8 @@ fn null_invalid_type() {
#[test]
fn test_integer128() {
- let signed = &[i128::min_value(), -1, 0, 1, i128::max_value()];
- let unsigned = &[0, 1, u128::max_value()];
+ let signed = &[i128::MIN, -1, 0, 1, i128::MAX];
+ let unsigned = &[0, 1, u128::MAX];
for integer128 in signed {
let expected = integer128.to_string();
@@ -2182,8 +2275,8 @@ fn test_integer128() {
#[test]
fn test_integer128_to_value() {
- let signed = &[i128::from(i64::min_value()), i128::from(u64::max_value())];
- let unsigned = &[0, u128::from(u64::max_value())];
+ let signed = &[i128::from(i64::MIN), i128::from(u64::MAX)];
+ let unsigned = &[0, u128::from(u64::MAX)];
for integer128 in signed {
let expected = integer128.to_string();
@@ -2196,7 +2289,7 @@ fn test_integer128_to_value() {
}
if !cfg!(feature = "arbitrary_precision") {
- let err = to_value(u128::from(u64::max_value()) + 1).unwrap_err();
+ let err = to_value(u128::from(u64::MAX) + 1).unwrap_err();
assert_eq!(err.to_string(), "number out of range");
}
}
@@ -2240,6 +2333,8 @@ fn test_raw_value_in_map_key() {
#[repr(transparent)]
struct RawMapKey(RawValue);
+ #[allow(unknown_lints)]
+ #[allow(non_local_definitions)] // false positive: https://github.com/rust-lang/rust/issues/121621
impl<'de> Deserialize<'de> for &'de RawMapKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -2384,25 +2479,27 @@ fn test_value_into_deserializer() {
let mut map = BTreeMap::new();
map.insert("inner", json!({ "string": "Hello World" }));
+ let outer = Outer::deserialize(serde::de::value::MapDeserializer::new(
+ map.iter().map(|(k, v)| (*k, v)),
+ ))
+ .unwrap();
+ assert_eq!(outer.inner.string, "Hello World");
+
let outer = Outer::deserialize(map.into_deserializer()).unwrap();
assert_eq!(outer.inner.string, "Hello World");
}
#[test]
fn hash_positive_and_negative_zero() {
- fn hash(obj: impl Hash) -> u64 {
- let mut hasher = DefaultHasher::new();
- obj.hash(&mut hasher);
- hasher.finish()
- }
+ let rand = std::hash::RandomState::new();
let k1 = serde_json::from_str::<Number>("0.0").unwrap();
let k2 = serde_json::from_str::<Number>("-0.0").unwrap();
if cfg!(feature = "arbitrary_precision") {
assert_ne!(k1, k2);
- assert_ne!(hash(k1), hash(k2));
+ assert_ne!(rand.hash_one(k1), rand.hash_one(k2));
} else {
assert_eq!(k1, k2);
- assert_eq!(hash(k1), hash(k2));
+ assert_eq!(rand.hash_one(k1), rand.hash_one(k2));
}
}