diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/lexical.rs | 5 | ||||
-rw-r--r-- | tests/lexical/parse.rs | 2 | ||||
-rw-r--r-- | tests/map.rs | 1 | ||||
-rw-r--r-- | tests/regression/issue1004.rs | 12 | ||||
-rw-r--r-- | tests/regression/issue845.rs | 1 | ||||
-rw-r--r-- | tests/test.rs | 224 | ||||
-rw-r--r-- | tests/ui/parse_key.stderr | 2 |
7 files changed, 73 insertions, 174 deletions
diff --git a/tests/lexical.rs b/tests/lexical.rs index 368c844..d3dfb85 100644 --- a/tests/lexical.rs +++ b/tests/lexical.rs @@ -26,6 +26,11 @@ extern crate alloc; #[path = "../src/lexical/mod.rs"] mod lexical; +mod lib { + pub use std::vec::Vec; + pub use std::{cmp, iter, mem, ops}; +} + #[path = "lexical/algorithm.rs"] mod algorithm; diff --git a/tests/lexical/parse.rs b/tests/lexical/parse.rs index 03ec1a9..80ca25e 100644 --- a/tests/lexical/parse.rs +++ b/tests/lexical/parse.rs @@ -1,7 +1,7 @@ // Adapted from https://github.com/Alexhuszagh/rust-lexical. use crate::lexical::num::Float; -use crate::lexical::{parse_concise_float, parse_truncated_float}; +use crate::lexical::parse::{parse_concise_float, parse_truncated_float}; use core::f64; use core::fmt::Debug; diff --git a/tests/map.rs b/tests/map.rs index 538cd16..ae01969 100644 --- a/tests/map.rs +++ b/tests/map.rs @@ -35,6 +35,7 @@ fn test_append() { assert!(val.is_empty()); } +#[cfg(not(no_btreemap_retain))] #[test] fn test_retain() { let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap(); diff --git a/tests/regression/issue1004.rs b/tests/regression/issue1004.rs deleted file mode 100644 index c09fb96..0000000 --- a/tests/regression/issue1004.rs +++ /dev/null @@ -1,12 +0,0 @@ -#![cfg(feature = "arbitrary_precision")] - -#[test] -fn test() { - let float = 5.55f32; - let value = serde_json::to_value(float).unwrap(); - let json = serde_json::to_string(&value).unwrap(); - - // If the f32 were cast to f64 by Value before serialization, then this - // would incorrectly serialize as 5.550000190734863. - assert_eq!(json, "5.55"); -} diff --git a/tests/regression/issue845.rs b/tests/regression/issue845.rs index e8b0c0f..56037ae 100644 --- a/tests/regression/issue845.rs +++ b/tests/regression/issue845.rs @@ -1,6 +1,7 @@ #![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757 use serde::{Deserialize, Deserializer}; +use std::convert::TryFrom; use std::fmt::{self, Display}; use std::marker::PhantomData; use std::str::FromStr; diff --git a/tests/test.rs b/tests/test.rs index 05b7f86..6c08cc8 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -14,6 +14,9 @@ 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; @@ -30,12 +33,11 @@ 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; @@ -51,7 +53,7 @@ macro_rules! treemap { () => { BTreeMap::new() }; - ($($k:expr => $v:expr),+ $(,)?) => { + ($($k:expr => $v:expr),+) => { { let mut m = BTreeMap::new(); $( @@ -158,29 +160,17 @@ fn test_write_f64() { #[test] fn test_encode_nonfinite_float_yields_null() { - let v = to_value(::std::f64::NAN.copysign(1.0)).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f64::NAN.copysign(-1.0)).unwrap(); + let v = to_value(::std::f64::NAN).unwrap(); assert!(v.is_null()); let v = to_value(::std::f64::INFINITY).unwrap(); assert!(v.is_null()); - let v = to_value(-::std::f64::INFINITY).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f32::NAN.copysign(1.0)).unwrap(); - assert!(v.is_null()); - - let v = to_value(::std::f32::NAN.copysign(-1.0)).unwrap(); + let v = to_value(::std::f32::NAN).unwrap(); assert!(v.is_null()); let v = to_value(::std::f32::INFINITY).unwrap(); assert!(v.is_null()); - - let v = to_value(-::std::f32::INFINITY).unwrap(); - assert!(v.is_null()); } #[test] @@ -274,7 +264,7 @@ fn test_write_object() { ( treemap!( "a".to_string() => true, - "b".to_string() => false, + "b".to_string() => false ), "{\"a\":true,\"b\":false}", ), @@ -285,7 +275,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\":{}}", ), @@ -294,10 +284,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\":{}}", ), @@ -307,9 +297,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\":{}}", ), @@ -320,8 +310,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\":{}}}", ), @@ -334,7 +324,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": {}, @@ -347,10 +337,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": { @@ -374,9 +364,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": {}, @@ -401,8 +391,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": {}, @@ -433,7 +423,7 @@ fn test_write_object() { ( treemap!( "a".to_string() => true, - "b".to_string() => false, + "b".to_string() => false ), pretty_str!( { "a": true, @@ -1202,8 +1192,8 @@ fn test_parse_object() { treemap!( "a".to_string() => treemap!( "b".to_string() => 3u64, - "c".to_string() => 4, - ), + "c".to_string() => 4 + ) ), )]); @@ -1379,7 +1369,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![]) ), )]); } @@ -1462,6 +1452,7 @@ 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, @@ -1488,6 +1479,7 @@ 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, @@ -1495,6 +1487,7 @@ 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>, @@ -1545,6 +1538,7 @@ 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, @@ -1572,6 +1566,7 @@ 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, @@ -1579,6 +1574,7 @@ 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>, @@ -1665,11 +1661,22 @@ 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(); @@ -1883,41 +1890,23 @@ 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)]); - 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", - ); + let j = r#"{"x":null}"#; + test_parse_err::<BTreeMap<i32, ()>>(&[( + j, + "invalid type: string \"x\", expected i32 at line 1 column 4", + )]); } #[test] fn test_integer128_key() { let map = treemap! { - 100000000000000000000000000000000000000u128 => (), + 100000000000000000000000000000000000000u128 => () }; let j = r#"{"100000000000000000000000000000000000000":null}"#; assert_eq!(to_string(&map).unwrap(), j); @@ -1925,107 +1914,24 @@ fn test_integer128_key() { } #[test] -fn test_float_key() { - #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone)] +fn test_deny_float_key() { + #[derive(Eq, PartialEq, Ord, PartialOrd)] struct Float; impl Serialize for Float { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer, { - 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) + serializer.serialize_f32(1.0) } } // map with float key - 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()); + let map = treemap!(Float => "x"); 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" => () }; @@ -2048,7 +1954,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)]); @@ -2058,7 +1964,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)]); @@ -2479,27 +2385,25 @@ 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() { - let rand = std::hash::RandomState::new(); + fn hash(obj: impl Hash) -> u64 { + let mut hasher = DefaultHasher::new(); + obj.hash(&mut hasher); + hasher.finish() + } 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!(rand.hash_one(k1), rand.hash_one(k2)); + assert_ne!(hash(k1), hash(k2)); } else { assert_eq!(k1, k2); - assert_eq!(rand.hash_one(k1), rand.hash_one(k2)); + assert_eq!(hash(k1), hash(k2)); } } diff --git a/tests/ui/parse_key.stderr b/tests/ui/parse_key.stderr index 15662dc..f10c218 100644 --- a/tests/ui/parse_key.stderr +++ b/tests/ui/parse_key.stderr @@ -2,4 +2,4 @@ error[E0609]: no field `s` on type `&'static str` --> tests/ui/parse_key.rs:4:16 | 4 | json!({ "".s : true }); - | ^ unknown field + | ^ |