Jeff Vander Stoep | 0029ba4 | 2021-06-25 09:40:28 +0200 | [diff] [blame^] | 1 | use crate::{decode_config, encode::encoded_size, encode_config_buf, CharacterSet, Config}; |
| 2 | |
| 3 | use std::str; |
| 4 | |
| 5 | use rand::{ |
| 6 | distributions::{Distribution, Uniform}, |
| 7 | seq::SliceRandom, |
| 8 | FromEntropy, Rng, |
| 9 | }; |
| 10 | |
| 11 | #[test] |
| 12 | fn roundtrip_random_config_short() { |
| 13 | // exercise the slower encode/decode routines that operate on shorter buffers more vigorously |
| 14 | roundtrip_random_config(Uniform::new(0, 50), 10_000); |
| 15 | } |
| 16 | |
| 17 | #[test] |
| 18 | fn roundtrip_random_config_long() { |
| 19 | roundtrip_random_config(Uniform::new(0, 1000), 10_000); |
| 20 | } |
| 21 | |
| 22 | pub fn assert_encode_sanity(encoded: &str, config: Config, input_len: usize) { |
| 23 | let input_rem = input_len % 3; |
| 24 | let expected_padding_len = if input_rem > 0 { |
| 25 | if config.pad { |
| 26 | 3 - input_rem |
| 27 | } else { |
| 28 | 0 |
| 29 | } |
| 30 | } else { |
| 31 | 0 |
| 32 | }; |
| 33 | |
| 34 | let expected_encoded_len = encoded_size(input_len, config).unwrap(); |
| 35 | |
| 36 | assert_eq!(expected_encoded_len, encoded.len()); |
| 37 | |
| 38 | let padding_len = encoded.chars().filter(|&c| c == '=').count(); |
| 39 | |
| 40 | assert_eq!(expected_padding_len, padding_len); |
| 41 | |
| 42 | let _ = str::from_utf8(encoded.as_bytes()).expect("Base64 should be valid utf8"); |
| 43 | } |
| 44 | |
| 45 | fn roundtrip_random_config(input_len_range: Uniform<usize>, iterations: u32) { |
| 46 | let mut input_buf: Vec<u8> = Vec::new(); |
| 47 | let mut encoded_buf = String::new(); |
| 48 | let mut rng = rand::rngs::SmallRng::from_entropy(); |
| 49 | |
| 50 | for _ in 0..iterations { |
| 51 | input_buf.clear(); |
| 52 | encoded_buf.clear(); |
| 53 | |
| 54 | let input_len = input_len_range.sample(&mut rng); |
| 55 | |
| 56 | let config = random_config(&mut rng); |
| 57 | |
| 58 | for _ in 0..input_len { |
| 59 | input_buf.push(rng.gen()); |
| 60 | } |
| 61 | |
| 62 | encode_config_buf(&input_buf, config, &mut encoded_buf); |
| 63 | |
| 64 | assert_encode_sanity(&encoded_buf, config, input_len); |
| 65 | |
| 66 | assert_eq!(input_buf, decode_config(&encoded_buf, config).unwrap()); |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | pub fn random_config<R: Rng>(rng: &mut R) -> Config { |
| 71 | const CHARSETS: &[CharacterSet] = &[ |
| 72 | CharacterSet::UrlSafe, |
| 73 | CharacterSet::Standard, |
| 74 | CharacterSet::Crypt, |
| 75 | CharacterSet::ImapMutf7, |
| 76 | CharacterSet::BinHex, |
| 77 | ]; |
| 78 | let charset = *CHARSETS.choose(rng).unwrap(); |
| 79 | |
| 80 | Config::new(charset, rng.gen()) |
| 81 | } |