diff --git a/src/decode_impl.rs b/src/decode_impl.rs index 0963a0c..30d0a3c 100644 --- a/src/decode_impl.rs +++ b/src/decode_impl.rs @@ -261,9 +261,13 @@ pub fn decode(input: &str, output: &mut Vec, bits: u64) -> Result<(), ZBase3 #[cfg(test)] mod tests { + #[cfg(feature = "std")] use super::decode; + use super::decode_slices; + use super::required_octets_buffer_len; use crate::test_data::{TestCase, RANDOM_TEST_DATA, STANDARD_TEST_DATA}; + #[cfg(feature = "std")] fn run_tests(test_cases: &[TestCase]) { let mut buffer = Vec::new(); for test in test_cases { @@ -273,13 +277,63 @@ mod tests { } } + fn run_low_level_tests(test_cases: &[TestCase]) { + // the largest sample in src/test_data.rs has 128 bits. + let mut buffer: [u8; 256] = [0; 256]; + for test in test_cases { + let outsz:usize = required_octets_buffer_len(test.bits).unwrap(); + decode_slices(test.encoded.as_bytes(), &mut buffer[..outsz], test.bits).unwrap(); + assert_eq!(&buffer[..outsz], test.unencoded); + } + } + #[test] + #[cfg(feature = "std")] fn test_decode_standard() { run_tests(STANDARD_TEST_DATA); } #[test] + #[cfg(feature = "std")] fn test_decode_random() { run_tests(RANDOM_TEST_DATA); } + + #[test] + fn test_decode_low_level_standard() { + run_low_level_tests(STANDARD_TEST_DATA); + } + + #[test] + fn test_decode_low_level_random() { + run_low_level_tests(RANDOM_TEST_DATA); + } + + #[test] + fn test_decode_non_zbase32_characters() { + let badcharacters = [ "0", "L", "💩", " ", "!", "_", "2", "v"]; + let mut out:[u8; 1] = [0]; + for character in badcharacters { + assert!(decode_slices(character.as_bytes(), &mut out, 5).is_err(), + "'{}' is not valid zbase32 character", character); + } + } + + #[test] + fn test_decode_non_full_byte_strings() { + // Should really also test different length encodings and bit + // boundaries, not just two chars in, one octet out. But it's + // clumsy to do this in no_std (without allocation), so just a + // simple test for now. + + // these two-character strings have some bits set in the + // trailing bits after the last full octet: + let badstrings = [ "99", "y9", "on", "yt", "zb"]; + let mut out:[u8;1] = [0]; + for string in badstrings { + assert!(decode_slices(string.as_bytes(), &mut out, 8).is_err(), + "'{}' should have produced bits beyond bit 8, should not have decoded, got {:#?}", + string, out); + } + } } diff --git a/src/encode_impl.rs b/src/encode_impl.rs index 49aab2d..4e6a539 100644 --- a/src/encode_impl.rs +++ b/src/encode_impl.rs @@ -250,9 +250,13 @@ pub fn encode(input: &[u8], output: &mut String, bits: u64) -> Result<(), ZBase3 #[cfg(test)] mod tests { + #[cfg(feature = "std")] use super::encode; + use super::encode_slices; + use super::required_quintets_buffer_len; use crate::test_data::{TestCase, RANDOM_TEST_DATA, STANDARD_TEST_DATA}; + #[cfg(feature = "std")] fn run_tests(test_cases: &[TestCase]) { let mut buffer = String::new(); for test in test_cases { @@ -262,13 +266,35 @@ mod tests { } } + fn run_low_level_tests(test_cases: &[TestCase]) { + // the largest sample in src/test_data.rs has 128 bits. + let mut buffer: [u8; 256] = [0; 256]; + for test in test_cases { + let outsz:usize = required_quintets_buffer_len(test.bits).unwrap(); + encode_slices(test.unencoded, &mut buffer[..outsz], test.bits).unwrap(); + assert_eq!(&buffer[..outsz], test.encoded.as_bytes()); + } + } + #[test] + #[cfg(feature = "std")] fn test_encode_standard() { run_tests(STANDARD_TEST_DATA); } #[test] + #[cfg(feature = "std")] fn test_encode_random() { run_tests(RANDOM_TEST_DATA); } + + #[test] + fn test_encode_low_level_standard() { + run_low_level_tests(STANDARD_TEST_DATA); + } + + #[test] + fn test_encode_low_level_random() { + run_low_level_tests(RANDOM_TEST_DATA); + } }