pub mod value; pub mod symbol; #[cfg(test)] mod dom { use super::value::{Value, PlainValue, NestedValue, Domain, Encoder, Codec}; #[derive(Debug, Hash, Clone, Ord, PartialEq, Eq, PartialOrd)] pub enum Dom { One, Two, } impl Domain for Dom { fn encode<'a, 'b, W: std::io::Write, N: NestedValue>( &self, enc: &mut Encoder<'a, 'b, W, N, Self>) -> super::value::encoder::Result { match self { Dom::One => enc.write_all(&[255, 255, 255, 255]), Dom::Two => enc.write(&self.as_preserves()?) } } fn as_preserves>(&self) -> Result { Ok(Value::symbol(&format!("Dom::{:?}", self)).wrap()) } } #[test] fn test_one() { let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), Value::Domain(Dom::One).wrap(), Value::from(2).wrap()]) .wrap(); assert_eq!(Codec::without_placeholders().encode_bytes(&v).unwrap(), [147, 49, 255, 255, 255, 255, 50]); } #[test] fn test_two() { let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), Value::Domain(Dom::Two).wrap(), Value::from(2).wrap()]) .wrap(); assert_eq!(Codec::without_placeholders().encode_bytes(&v).unwrap(), [147, 49, 120, 68, 111, 109, 58, 58, 84, 119, 111, 50]); } #[test] fn test_unit() { let v: PlainValue<_> = Value::from(vec![Value::from(1).wrap(), Value::Domain(()).wrap(), Value::from(2).wrap()]) .wrap(); let e = Codec::without_placeholders().encode_bytes(&v).err().unwrap(); assert_eq!(e.kind(), std::io::ErrorKind::InvalidData); assert_eq!(e.to_string(), "Cannot Preserves-encode domain-specific value ()"); } } #[cfg(test)] mod ieee754_section_5_10_total_order_tests { use std::cmp::Ordering::{Less, Equal, Greater}; use super::dom::Dom; use crate::value::{Value, PlainValue}; fn f(val: f32) -> Value, Dom> { Value::from(val) } fn d(val: f64) -> Value, Dom> { Value::from(val) } // TODO: Test cases with a few different signalling and non-signalling NaNs #[test] fn case32_a_1() { assert_eq!(f(1.0).cmp(&f(2.0)), Less) } #[test] fn case32_a_2() { assert_eq!(f(-1.0).cmp(&f(1.0)), Less) } #[test] fn case32_a_3() { assert_eq!(f(0.0).cmp(&f(1.0)), Less) } #[test] fn case32_a_4() { assert_eq!(f(-1.0).cmp(&f(0.0)), Less) } #[test] fn case32_a_5() { assert_eq!(f(-1e32).cmp(&f(-1e31)), Less) } #[test] fn case32_a_6() { assert_eq!(f(-1e32).cmp(&f(1e33)), Less) } #[test] fn case32_a_7() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(std::f32::INFINITY)), Less) } #[test] fn case32_a_8() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(0.0)), Less) } #[test] fn case32_a_9() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(1.0)), Less) } #[test] fn case32_a_10() { assert_eq!(f(std::f32::NEG_INFINITY).cmp(&f(1e33)), Less) } #[test] fn case32_a_11() { assert_eq!(f(0.0).cmp(&f(std::f32::INFINITY)), Less) } #[test] fn case32_a_12() { assert_eq!(f(1.0).cmp(&f(std::f32::INFINITY)), Less) } #[test] fn case32_a_13() { assert_eq!(f(1e33).cmp(&f(std::f32::INFINITY)), Less) } #[test] fn case32_b_1() { assert_eq!(f(2.0).cmp(&f(1.0)), Greater) } #[test] fn case32_b_2() { assert_eq!(f(1.0).cmp(&f(-1.0)), Greater) } #[test] fn case32_b_3() { assert_eq!(f(1.0).cmp(&f(0.0)), Greater) } #[test] fn case32_b_4() { assert_eq!(f(0.0).cmp(&f(-1.0)), Greater) } #[test] fn case32_b_5() { assert_eq!(f(-1e31).cmp(&f(-1e32)), Greater) } #[test] fn case32_b_6() { assert_eq!(f(1e33).cmp(&f(-1e32)), Greater) } #[test] fn case32_b_7() { assert_eq!(f(std::f32::INFINITY).cmp(&f(std::f32::NEG_INFINITY)), Greater) } #[test] fn case32_b_8() { assert_eq!(f(std::f32::INFINITY).cmp(&f(0.0)), Greater) } #[test] fn case32_b_9() { assert_eq!(f(std::f32::INFINITY).cmp(&f(1.0)), Greater) } #[test] fn case32_b_10() { assert_eq!(f(std::f32::INFINITY).cmp(&f(1e33)), Greater) } #[test] fn case32_b_11() { assert_eq!(f(0.0).cmp(&f(std::f32::NEG_INFINITY)), Greater) } #[test] fn case32_b_12() { assert_eq!(f(1.0).cmp(&f(std::f32::NEG_INFINITY)), Greater) } #[test] fn case32_b_13() { assert_eq!(f(1e33).cmp(&f(std::f32::NEG_INFINITY)), Greater) } #[test] fn case32_c1() { assert_eq!(f(-0.0).cmp(&f( 0.0)), Less) } #[test] fn case32_c2() { assert_eq!(f( 0.0).cmp(&f(-0.0)), Greater) } #[test] fn case32_c3_1() { assert_eq!(f(-0.0).cmp(&f(-0.0)), Equal) } #[test] fn case32_c3_2() { assert_eq!(f( 0.0).cmp(&f( 0.0)), Equal) } #[test] fn case32_c3_3() { assert_eq!(f(1.0).cmp(&f(1.0)), Equal) } #[test] fn case32_c3_4() { assert_eq!(f(-1.0).cmp(&f(-1.0)), Equal) } #[test] fn case32_c3_5() { assert_eq!(f(-1e32).cmp(&f(-1e32)), Equal) } #[test] fn case32_c3_6() { assert_eq!(f(1e33).cmp(&f(1e33)), Equal) } #[test] fn case64_a_1() { assert_eq!(d(1.0).cmp(&d(2.0)), Less) } #[test] fn case64_a_2() { assert_eq!(d(-1.0).cmp(&d(1.0)), Less) } #[test] fn case64_a_3() { assert_eq!(d(0.0).cmp(&d(1.0)), Less) } #[test] fn case64_a_4() { assert_eq!(d(-1.0).cmp(&d(0.0)), Less) } #[test] fn case64_a_5() { assert_eq!(d(-1e32).cmp(&d(-1e31)), Less) } #[test] fn case64_a_6() { assert_eq!(d(-1e32).cmp(&d(1e33)), Less) } #[test] fn case64_a_7() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_8() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(0.0)), Less) } #[test] fn case64_a_9() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1.0)), Less) } #[test] fn case64_a_10() { assert_eq!(d(std::f64::NEG_INFINITY).cmp(&d(1e33)), Less) } #[test] fn case64_a_11() { assert_eq!(d(0.0).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_12() { assert_eq!(d(1.0).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_a_13() { assert_eq!(d(1e33).cmp(&d(std::f64::INFINITY)), Less) } #[test] fn case64_b_1() { assert_eq!(d(2.0).cmp(&d(1.0)), Greater) } #[test] fn case64_b_2() { assert_eq!(d(1.0).cmp(&d(-1.0)), Greater) } #[test] fn case64_b_3() { assert_eq!(d(1.0).cmp(&d(0.0)), Greater) } #[test] fn case64_b_4() { assert_eq!(d(0.0).cmp(&d(-1.0)), Greater) } #[test] fn case64_b_5() { assert_eq!(d(-1e31).cmp(&d(-1e32)), Greater) } #[test] fn case64_b_6() { assert_eq!(d(1e33).cmp(&d(-1e32)), Greater) } #[test] fn case64_b_7() { assert_eq!(d(std::f64::INFINITY).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_b_8() { assert_eq!(d(std::f64::INFINITY).cmp(&d(0.0)), Greater) } #[test] fn case64_b_9() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1.0)), Greater) } #[test] fn case64_b_10() { assert_eq!(d(std::f64::INFINITY).cmp(&d(1e33)), Greater) } #[test] fn case64_b_11() { assert_eq!(d(0.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_b_12() { assert_eq!(d(1.0).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_b_13() { assert_eq!(d(1e33).cmp(&d(std::f64::NEG_INFINITY)), Greater) } #[test] fn case64_c1() { assert_eq!(d(-0.0).cmp(&d( 0.0)), Less) } #[test] fn case64_c2() { assert_eq!(d( 0.0).cmp(&d(-0.0)), Greater) } #[test] fn case64_c3_1() { assert_eq!(d(-0.0).cmp(&d(-0.0)), Equal) } #[test] fn case64_c3_2() { assert_eq!(d( 0.0).cmp(&d( 0.0)), Equal) } #[test] fn case64_c3_3() { assert_eq!(d(1.0).cmp(&d(1.0)), Equal) } #[test] fn case64_c3_4() { assert_eq!(d(-1.0).cmp(&d(-1.0)), Equal) } #[test] fn case64_c3_5() { assert_eq!(d(-1e32).cmp(&d(-1e32)), Equal) } #[test] fn case64_c3_6() { assert_eq!(d(1e33).cmp(&d(1e33)), Equal) } } #[cfg(test)] mod value_tests { use crate::value::{Value, PlainValue}; use num::bigint::BigInt; use super::dom::Dom; type VV = Value, Dom>; #[test] fn boolean_mut() { let mut b = VV::Boolean(true); assert!(b.is_boolean()); *(b.as_boolean_mut().unwrap()) = false; assert_eq!(b, VV::Boolean(false)); } #[test] fn float_mut() { let mut f = VV::from(1.0f32); assert!(f.is_float()); *(f.as_float_mut().unwrap()) = 123.45; assert_eq!(f, VV::from(123.45f32)); assert_eq!(f.as_float().unwrap(), 123.45f32); } #[test] fn double_mut() { let mut f = VV::from(1.0); assert!(f.is_double()); *(f.as_double_mut().unwrap()) = 123.45; assert_eq!(f, VV::from(123.45)); assert_eq!(f.as_double().unwrap(), 123.45); } #[test] fn signedinteger_mut() { let mut i = VV::from(123); assert!(i.is_signedinteger()); *(i.as_signedinteger_mut().unwrap()) = BigInt::from(234); assert_eq!(i, VV::from(234)); use num::traits::cast::ToPrimitive; assert_eq!(i.as_signedinteger().unwrap().to_i64().unwrap(), 234); } #[test] fn string_mut() { let mut s = VV::from("hello, world!"); assert!(s.is_string()); s.as_string_mut().unwrap().replace_range(7..12, "there"); assert_eq!(s, VV::from("hello, there!")); } #[test] fn bytes_mut() { let mut b = VV::from(&b"hello, world!"[..]); assert!(b.is_bytestring()); b.as_bytestring_mut().unwrap().splice(7..12, Vec::from(&b"there"[..])); assert_eq!(b, VV::from(&b"hello, there!"[..])); } #[test] fn symbol_mut() { let mut s = VV::symbol("abcd"); assert!(s.is_symbol()); s.as_symbol_mut().unwrap().replace_range(..2, "AB"); assert_eq!(s, VV::symbol("ABcd")); } #[test] fn record_mut() { let says = VV::symbol("says").wrap(); let mut r = VV::record(says.clone(), vec![VV::from("Tony").wrap(), VV::from("Hello!").wrap()]); r.as_record_mut().unwrap().1[0] = VV::from("Alice").wrap(); assert_eq!(r, VV::record(says, vec![VV::from("Alice").wrap(), VV::from("Hello!").wrap()])); } #[test] fn sequence_mut() { let mut s = VV::Sequence(vec![VV::from(1).wrap(), VV::from(2).wrap(), VV::from(3).wrap()]); let r = VV::Sequence(vec![VV::from(1).wrap(), VV::from(99).wrap(), VV::from(3).wrap()]); s.as_sequence_mut().unwrap()[1] = VV::from(99).wrap(); assert_eq!(r, s); } } #[cfg(test)] mod decoder_tests { use crate::value::Decoder; use crate::value::{Value, PlainValue, NestedValue}; use super::dom::Dom; #[test] fn read_123() { let mut buf = &b"abc"[..]; let mut d = Decoder::<_, PlainValue, Dom>::new(&mut buf, None); assert_eq!(d.read().ok(), Some(97)); assert_eq!(d.read().ok(), Some(98)); assert_eq!(d.read().ok(), Some(99)); assert!(d.read().err().unwrap().is_eof()) } #[test] fn skip_annotations_noskip() { let mut buf = &b"\x0521"[..]; let mut d = Decoder::<_, PlainValue, Dom>::new(&mut buf, None); let v = d.next().unwrap(); assert_eq!(v.annotations().len(), 1); assert_eq!(v.annotations()[0], Value::from(2).wrap()); assert_eq!(v.value(), &Value::from(1)); } #[test] fn skip_annotations_skip() { let mut buf = &b"\x0521"[..]; let mut d = Decoder::<_, PlainValue, Dom>::new(&mut buf, None); d.set_read_annotations(false); let v = d.next().unwrap(); assert_eq!(v.annotations().len(), 0); assert_eq!(v.value(), &Value::from(1)); } #[test] fn two_values_at_once() { let mut buf = &b"\x81tPing\x81tPong"[..]; assert_eq!(buf.len(), 12); let mut d = Decoder::<_, PlainValue, Dom>::new(&mut buf, None); assert_eq!(d.next().unwrap().value(), &Value::simple_record("Ping", vec![])); assert_eq!(d.next().unwrap().value(), &Value::simple_record("Pong", vec![])); assert_eq!(buf.len(), 0); } #[test] fn buf_advanced() { let mut buf = &b"\x81tPing\x81tPong"[..]; assert_eq!(buf.len(), 12); let mut d = Decoder::<_, PlainValue, Dom>::new(&mut buf, None); assert_eq!(d.next().unwrap().value(), &Value::simple_record("Ping", vec![])); assert_eq!(buf.len(), 6); } } #[cfg(test)] mod samples_tests { use crate::symbol::Symbol; use crate::value::{Codec, Decoder, decoder::Error}; use crate::value::{Value, PlainValue, Map}; use crate::value::DecodePlaceholderMap; use crate::value::to_value; use crate::value::from_value; use super::dom::Dom; #[derive(Debug, serde::Serialize, serde::Deserialize)] struct ExpectedPlaceholderMapping(DecodePlaceholderMap, Dom>); #[derive(Debug, serde::Serialize, serde::Deserialize)] struct TestCases { decode_placeholders: ExpectedPlaceholderMapping, tests: Map } #[derive(Debug, serde::Serialize, serde::Deserialize)] enum TestCase { Test(#[serde(with = "serde_bytes")] Vec, PlainValue), NondeterministicTest(#[serde(with = "serde_bytes")] Vec, PlainValue), StreamingTest(#[serde(with = "serde_bytes")] Vec, PlainValue), DecodeTest(#[serde(with = "serde_bytes")] Vec, PlainValue), ParseError(String), ParseShort(String), DecodeError(#[serde(with = "serde_bytes")] Vec), DecodeShort(#[serde(with = "serde_bytes")] Vec), } #[test] fn run() -> std::io::Result<()> { let mut fh = std::fs::File::open("../../tests/samples.bin").unwrap(); let mut d = Decoder::<_, PlainValue, Dom>::new(&mut fh, None); let tests: TestCases = from_value(&d.next().unwrap()).unwrap(); // println!("{:#?}", tests); let codec = Codec::new(tests.decode_placeholders.0); for (Symbol(ref name), ref case) in tests.tests { println!("{:?} ==> {:?}", name, case); match case { TestCase::Test(ref bin, ref val) => { assert_eq!(&codec.decode(&mut &codec.encode_bytes(val)?[..])?, val); assert_eq!(&codec.decode(&mut &bin[..])?, val); assert_eq!(&codec.encode_bytes(val)?, bin); } TestCase::NondeterministicTest(ref bin, ref val) => { // The test cases in samples.txt are carefully // written so that while strictly // "nondeterministic", the order of keys in // dictionaries follows Preserves order. assert_eq!(&codec.decode(&mut &codec.encode_bytes(val)?[..])?, val); assert_eq!(&codec.decode(&mut &bin[..])?, val); assert_eq!(&codec.encode_bytes(val)?, bin); } TestCase::StreamingTest(ref bin, ref val) => { assert_eq!(&codec.decode(&mut &codec.encode_bytes(val)?[..])?, val); assert_eq!(&codec.decode(&mut &bin[..])?, val); } TestCase::DecodeTest(ref bin, ref val) => { assert_eq!(&codec.decode(&mut &codec.encode_bytes(val)?[..])?, val); assert_eq!(&codec.decode(&mut &bin[..])?, val); } TestCase::ParseError(_) => (), TestCase::ParseShort(_) => (), TestCase::DecodeError(ref bin) => { match codec.decode(&mut &bin[..]) { Ok(_) => panic!("Unexpected success"), Err(Error::Syntax(_)) => (), Err(e) => panic!("Unexpected error {:?}", e), } } TestCase::DecodeShort(ref bin) => { match codec.decode(&mut &bin[..]) { Ok(_) => panic!("Unexpected success"), Err(Error::Eof) => (), Err(e) => panic!("Unexpected error {:?}", e), } } } } Ok(()) } #[test] fn simple_to_value() { #[derive(Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] struct SimpleValue<'a>(String, #[serde(with = "crate::symbol")] String, Symbol, &'a str, #[serde(with = "serde_bytes")] &'a [u8], #[serde(with = "serde_bytes")] Vec, i16, PlainValue); let v = SimpleValue("hello".to_string(), "sym1".to_string(), Symbol("sym2".to_string()), "world", &b"slice"[..], b"vec".to_vec(), 12345, Value::from("hi").wrap()); println!("{:#?}", v); let w: PlainValue = to_value(&v).unwrap(); println!("{:#?}", w); let x = from_value(&w).unwrap(); println!("{:#?}", &x); assert_eq!(v, x); } }