diff options
Diffstat (limited to 'vendor/base64ct/tests/proptests.rs')
-rw-r--r-- | vendor/base64ct/tests/proptests.rs | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/vendor/base64ct/tests/proptests.rs b/vendor/base64ct/tests/proptests.rs new file mode 100644 index 000000000..eaa5ae3ec --- /dev/null +++ b/vendor/base64ct/tests/proptests.rs @@ -0,0 +1,149 @@ +//! Equivalence tests between `base64` crate and `base64ct`. + +#![cfg(feature = "std")] + +use base64ct::{Base64 as Base64ct, Encoding}; +use proptest::{prelude::*, string::*}; +use std::iter; + +/// Incremental Base64 decoder. +type Decoder<'a> = base64ct::Decoder<'a, Base64ct>; + +/// Incremental Base64 encoder. +type Encoder<'a> = base64ct::Encoder<'a, Base64ct>; + +proptest! { + /// Ensure `base64ct` decodes data encoded by `base64` ref crate + #[test] + fn decode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) { + let encoded = base64::encode(&bytes); + let decoded = Base64ct::decode_vec(&encoded); + prop_assert_eq!(Ok(bytes), decoded); + } + + /// Ensure that `base64ct`'s incremental decoder is able to decode randomly + /// generated inputs encoded by the `base64` ref crate + #[test] + fn decode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) { + let encoded = base64::encode(&bytes); + let chunk_size = match chunk_size % bytes.len() { + 0 => 1, + n => n + }; + + let mut buffer = [0u8; 384]; + let mut decoder = Decoder::new(encoded.as_bytes()).unwrap(); + let mut remaining_len = decoder.remaining_len(); + + for chunk in bytes.chunks(chunk_size) { + prop_assert!(!decoder.is_finished()); + + let decoded = decoder.decode(&mut buffer[..chunk.len()]); + prop_assert_eq!(Ok(chunk), decoded); + + remaining_len -= decoded.unwrap().len(); + prop_assert_eq!(remaining_len, decoder.remaining_len()); + } + + prop_assert!(decoder.is_finished()); + prop_assert_eq!(decoder.remaining_len(), 0); + } + + #[test] + fn decode_incremental_wrapped( + bytes in bytes_regex(".{1,256}").unwrap(), + line_width in 4..128usize, + chunk_size in 1..256usize + ) { + for line_ending in ["\r", "\n", "\r\n"] { + let encoded = base64::encode(&bytes); + + let mut encoded_wrapped = Vec::new(); + let mut lines = encoded.as_bytes().chunks_exact(line_width); + + for line in &mut lines { + encoded_wrapped.extend_from_slice(line); + encoded_wrapped.extend_from_slice(line_ending.as_bytes()); + } + + let last = lines.remainder(); + + if last.is_empty() { + encoded_wrapped.truncate(encoded_wrapped.len() - line_ending.len()); + } else { + encoded_wrapped.extend_from_slice(last); + } + + let chunk_size = match chunk_size % bytes.len() { + 0 => 1, + n => n + }; + + let mut buffer = [0u8; 384]; + let mut decoder = Decoder::new_wrapped(&encoded_wrapped, line_width).unwrap(); + let mut remaining_len = decoder.remaining_len(); + + for chunk in bytes.chunks(chunk_size) { + prop_assert!(!decoder.is_finished()); + + let decoded = decoder.decode(&mut buffer[..chunk.len()]); + prop_assert_eq!(Ok(chunk), decoded); + + remaining_len -= decoded.unwrap().len(); + prop_assert_eq!(remaining_len, decoder.remaining_len()); + } + + prop_assert!(decoder.is_finished()); + prop_assert_eq!(decoder.remaining_len(), 0); + } + } + + /// Ensure `base64ct` and `base64` ref crate decode randomly generated + /// inputs equivalently. + /// + /// Inputs are selected to be valid characters in the standard Base64 + /// padded alphabet, but are not necessarily valid Base64. + #[test] + fn decode_random(base64ish in string_regex("[A-Za-z0-9+/]{0,256}").unwrap()) { + let base64ish_padded = match base64ish.len() % 4 { + 0 => base64ish, + n => { + let padding_len = 4 - n; + base64ish + &iter::repeat("=").take(padding_len).collect::<String>() + } + }; + + let decoded_ct = Base64ct::decode_vec(&base64ish_padded).ok(); + let decoded_ref = base64::decode(&base64ish_padded).ok(); + prop_assert_eq!(decoded_ct, decoded_ref); + } + + /// Ensure `base64ct` and the `base64` ref crate encode randomly generated + /// inputs equivalently. + #[test] + fn encode_equiv(bytes in bytes_regex(".{0,256}").unwrap()) { + let encoded_ct = Base64ct::encode_string(&bytes); + let encoded_ref = base64::encode(&bytes); + prop_assert_eq!(encoded_ct, encoded_ref); + } + + /// Ensure that `base64ct`'s incremental encoder is able to encode randomly + /// generated inputs which match what's encoded by the `base64` ref crate + #[test] + fn encode_incremental(bytes in bytes_regex(".{1,256}").unwrap(), chunk_size in 1..256usize) { + let expected = base64::encode(&bytes); + let chunk_size = match chunk_size % bytes.len() { + 0 => 1, + n => n + }; + + let mut buffer = [0u8; 1024]; + let mut encoder = Encoder::new(&mut buffer).unwrap(); + + for chunk in bytes.chunks(chunk_size) { + encoder.encode(chunk).unwrap(); + } + + prop_assert_eq!(expected, encoder.finish().unwrap()); + } +} |