diff --git a/Makefile b/Makefile index 72dba30..b3f0363 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,10 @@ # These hacks are required for the test binaries depending on the dynamic library libstd-*.so # See: https://github.com/rust-lang/cargo/issues/4651 +# +# We also need to exclude the derive macro from coverage because it will always show as 0% by +# virtue of executing at compile-time outside the view of Tarpaulin. coverage: env LD_LIBRARY_PATH="$(shell rustc --print sysroot)/lib" \ - cargo-tarpaulin --workspace --all-features --out xml + cargo-tarpaulin --workspace --all-features --out xml --exclude ethereum_ssz_derive .PHONY: coverage diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..bfdc987 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,8 @@ +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true diff --git a/ssz/tests/tests.rs b/ssz/tests/tests.rs index f52d2c5..95b1248 100644 --- a/ssz/tests/tests.rs +++ b/ssz/tests/tests.rs @@ -1,13 +1,24 @@ -use ethereum_types::H256; +use ethereum_types::{H160, H256}; use ssz::{Decode, DecodeError, Encode}; use ssz_derive::{Decode, Encode}; +use std::num::NonZeroUsize; mod round_trip { use super::*; - use std::collections::BTreeMap; + use std::collections::{BTreeMap, BTreeSet}; use std::iter::FromIterator; + use std::sync::Arc; fn round_trip(items: Vec) { + assert_eq!( + ::is_ssz_fixed_len(), + ::is_ssz_fixed_len() + ); + assert_eq!( + ::ssz_fixed_len(), + ::ssz_fixed_len() + ); + for item in items { let encoded = &item.as_ssz_bytes(); assert_eq!(item.ssz_bytes_len(), encoded.len()); @@ -36,6 +47,23 @@ mod round_trip { round_trip(items); } + #[test] + fn h160() { + let items: Vec = vec![H160::zero(), H160::from([1; 20]), H160::random()]; + + round_trip(items); + } + + #[test] + fn vec_of_h160() { + let items: Vec> = vec![ + vec![], + vec![H160::zero(), H160::from([1; 20]), H160::random()], + ]; + + round_trip(items); + } + #[test] fn h256() { let items: Vec = vec![H256::zero(), H256::from([1; 32]), H256::random()]; @@ -155,7 +183,7 @@ mod round_trip { round_trip(items); } - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, Eq, Encode, Decode)] struct VariableLen { a: u16, b: Vec, @@ -277,7 +305,7 @@ mod round_trip { round_trip(items); } - #[derive(Debug, PartialEq, Encode, Decode)] + #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Encode, Decode)] struct ThreeVariableLen { a: u16, b: Vec, @@ -387,4 +415,83 @@ mod round_trip { ]; round_trip(data); } + + #[test] + fn btree_set_fixed() { + let data = vec![BTreeSet::new(), BTreeSet::from_iter(vec![0u16, 2, 4, 6])]; + round_trip(data); + } + + #[test] + fn btree_set_variable_len() { + let data = vec![ + BTreeSet::new(), + BTreeSet::from_iter(vec![ + ThreeVariableLen { + a: 1, + b: vec![3, 5, 7], + c: vec![], + d: vec![0, 0], + }, + ThreeVariableLen { + a: 99, + b: vec![1], + c: vec![2, 3, 4, 5, 6, 7, 8, 9, 10], + d: vec![4, 5, 6, 7, 8], + }, + ThreeVariableLen { + a: 0, + b: vec![], + c: vec![], + d: vec![], + }, + ]), + ]; + round_trip(data); + } + + #[test] + fn non_zero_usize() { + let data = vec![ + NonZeroUsize::new(1).unwrap(), + NonZeroUsize::new(u16::MAX as usize).unwrap(), + NonZeroUsize::new(usize::MAX).unwrap(), + ]; + round_trip(data); + } + + #[test] + fn arc_u64() { + let data = vec![Arc::new(0u64), Arc::new(u64::MAX)]; + round_trip(data); + } + + #[test] + fn arc_vec_u64() { + let data = vec![Arc::new(vec![0u64]), Arc::new(vec![u64::MAX; 10])]; + round_trip(data); + } +} + +/// Decode tests that are expected to fail. +mod decode_fail { + use super::*; + + #[test] + fn non_zero_usize() { + let zero_bytes = 0usize.as_ssz_bytes(); + assert!(NonZeroUsize::from_ssz_bytes(&zero_bytes).is_err()); + } + + #[test] + fn hash160() { + let long_bytes = H256::repeat_byte(0xff).as_ssz_bytes(); + assert!(H160::from_ssz_bytes(&long_bytes).is_err()); + } + + #[test] + fn hash256() { + let long_bytes = vec![0xff; 257]; + assert!(H256::from_ssz_bytes(&long_bytes).is_err()); + } }