tests.rs (7532B)
1 use super::DecodeErr; 2 #[cfg(any( 3 target_pointer_width = "16", 4 target_pointer_width = "32", 5 target_pointer_width = "64", 6 ))] 7 use super::MAX_ENCODE_INPUT_LEN; 8 #[cfg(feature = "alloc")] 9 use alloc::{borrow::ToOwned as _, string::String, vec}; 10 use core::fmt::{self, Write}; 11 #[cfg(any( 12 target_pointer_width = "16", 13 target_pointer_width = "32", 14 target_pointer_width = "64", 15 ))] 16 use rand::{RngExt as _, rngs::SmallRng}; 17 #[expect( 18 clippy::as_conversions, 19 clippy::cast_possible_truncation, 20 reason = "comment justifies correctness" 21 )] 22 #[cfg(any( 23 target_pointer_width = "16", 24 target_pointer_width = "32", 25 target_pointer_width = "64", 26 ))] 27 #[ignore = "slow"] 28 #[test] 29 fn encode_decode_len() { 30 assert_eq!(MAX_ENCODE_INPUT_LEN, 3 * (usize::MAX.div_ceil(4)) - 1); 31 let mut rng = rand::make_rng::<SmallRng>(); 32 for _ in 0u32..10_000_000 { 33 // `uN as usize` is fine since we `cfg` by pointer width. 34 #[cfg(target_pointer_width = "16")] 35 let len = rng.random::<u16>() as usize; 36 #[cfg(target_pointer_width = "32")] 37 let len = rng.random::<u32>() as usize; 38 #[cfg(target_pointer_width = "64")] 39 let len = rng.random::<u64>() as usize; 40 if len <= MAX_ENCODE_INPUT_LEN { 41 assert_eq!( 42 super::encode_len_checked(len).map(super::decode_len), 43 Some(Some(len)) 44 ); 45 } else { 46 assert!(super::encode_len_checked(len).is_none()); 47 } 48 } 49 for i in 0..1025 { 50 assert_eq!( 51 super::encode_len_checked(i).map(super::decode_len), 52 Some(Some(i)) 53 ); 54 } 55 #[cfg(target_pointer_width = "16")] 56 for i in MAX_ENCODE_INPUT_LEN + 1.. { 57 assert!(super::encode_len_checked(i).is_none()); 58 } 59 #[cfg(not(target_pointer_width = "16"))] 60 for i in MAX_ENCODE_INPUT_LEN + 1..MAX_ENCODE_INPUT_LEN + 1_000_000 { 61 assert!(super::encode_len_checked(i).is_none()); 62 } 63 assert!(super::encode_len_checked(usize::MAX).is_none()); 64 assert_eq!( 65 super::encode_len_checked(MAX_ENCODE_INPUT_LEN), 66 Some(usize::MAX) 67 ); 68 for _ in 0u32..10_000_000 { 69 #[cfg(target_pointer_width = "16")] 70 let len = rng.random::<u16>() as usize; 71 #[cfg(target_pointer_width = "32")] 72 let len = rng.random::<u32>() as usize; 73 #[cfg(target_pointer_width = "64")] 74 let len = rng.random::<u64>() as usize; 75 if len & 3 == 1 { 76 assert!(super::decode_len(len).is_none()); 77 } else { 78 assert_eq!( 79 super::decode_len(len).map(super::encode_len_checked), 80 Some(Some(len)) 81 ); 82 } 83 } 84 for i in 0..1025 { 85 if i & 3 == 1 { 86 assert!(super::decode_len(i).is_none()); 87 } else { 88 assert_eq!( 89 super::decode_len(i).map(super::encode_len_checked), 90 Some(Some(i)) 91 ); 92 } 93 } 94 #[cfg(target_pointer_width = "16")] 95 for i in 0..=usize::MAX { 96 if i & 3 == 1 { 97 assert!(super::decode_len(i).is_none()); 98 } else { 99 assert_eq!( 100 super::decode_len(i).map(super::encode_len_checked), 101 Some(Some(i)) 102 ); 103 } 104 } 105 #[cfg(not(target_pointer_width = "16"))] 106 for i in usize::MAX - 1_000_000..=usize::MAX { 107 if i & 3 == 1 { 108 assert!(super::decode_len(i).is_none()); 109 } else { 110 assert_eq!( 111 super::decode_len(i).map(super::encode_len_checked), 112 Some(Some(i)) 113 ); 114 } 115 } 116 assert_eq!(super::decode_len(usize::MAX), Some(MAX_ENCODE_INPUT_LEN)); 117 } 118 #[expect(clippy::indexing_slicing, reason = "comments justify correctness")] 119 #[cfg(feature = "alloc")] 120 #[test] 121 fn encode_write() { 122 let input = [9; 8192]; 123 let mut buffer = String::with_capacity(super::encode_len(input.len())); 124 let cap = buffer.capacity(); 125 let mut write_len; 126 for len in 0..input.len() { 127 write_len = super::encode_len(len); 128 match write_len.checked_add(buffer.len()) { 129 None => { 130 buffer.clear(); 131 // Indexing is fine since `len <= input.len()`. 132 assert_eq!(super::encode_write(&input[..len], &mut buffer), Ok(())); 133 assert_eq!(buffer.len(), write_len); 134 } 135 Some(l) => { 136 if l > cap { 137 buffer.clear(); 138 // Indexing is fine since `len <= input.len()`. 139 assert_eq!(super::encode_write(&input[..len], &mut buffer), Ok(())); 140 assert_eq!(buffer.len(), write_len); 141 } else { 142 // Indexing is fine since `len <= input.len()`. 143 assert_eq!(super::encode_write(&input[..len], &mut buffer), Ok(())); 144 assert_eq!(buffer.len(), l); 145 } 146 } 147 } 148 assert!( 149 buffer 150 .as_bytes() 151 .iter() 152 .all(|b| { matches!(*b, b'C' | b'J' | b'Q' | b'k') }) 153 ); 154 } 155 } 156 #[cfg(feature = "alloc")] 157 #[test] 158 fn try_encode() { 159 assert_eq!(super::try_encode(&[0]), Ok("AA".to_owned())); 160 } 161 #[cfg(feature = "alloc")] 162 #[test] 163 fn encode() { 164 assert_eq!(super::encode(&[0]), "AA".to_owned()); 165 } 166 #[cfg(feature = "alloc")] 167 #[test] 168 fn try_encode_append() { 169 let mut val = "Hi".to_owned(); 170 assert_eq!( 171 super::try_encode_append(&[0], &mut val), 172 Ok("AA".to_owned().as_mut_str()) 173 ); 174 assert_eq!(val, "HiAA"); 175 } 176 #[cfg(feature = "alloc")] 177 #[test] 178 fn encode_append() { 179 let mut val = "Hi".to_owned(); 180 assert_eq!( 181 super::encode_append(&[0], &mut val), 182 "AA".to_owned().as_mut_str() 183 ); 184 assert_eq!(val, "HiAA"); 185 } 186 #[cfg(feature = "alloc")] 187 #[test] 188 fn try_encode_append_only() { 189 let mut val = "Hi".to_owned(); 190 assert_eq!(super::try_encode_append_only(&[0], &mut val), Ok(())); 191 assert_eq!(val, "HiAA"); 192 } 193 #[cfg(feature = "alloc")] 194 #[test] 195 fn encode_append_only() { 196 let mut val = "Hi".to_owned(); 197 super::encode_append_only(&[0], &mut val); 198 assert_eq!(val, "HiAA"); 199 } 200 #[test] 201 fn decode_buffer() { 202 assert_eq!( 203 super::decode_buffer(b"AA", &mut [0]), 204 Ok([0].as_mut_slice()) 205 ); 206 assert_eq!( 207 super::decode_buffer(b"AA", &mut []), 208 Err(DecodeErr::BufferLen) 209 ); 210 } 211 #[cfg(feature = "alloc")] 212 #[test] 213 fn decode() { 214 assert_eq!(super::decode(b"AA"), Ok(vec![0])); 215 } 216 #[test] 217 fn validate_encoded_data() { 218 assert_eq!(super::validate_encoded_data(b"AA"), Ok(())); 219 } 220 #[test] 221 fn encode_buffer_exact() { 222 let mut output = [0; 2]; 223 super::encode_buffer_exact(&[0], &mut output); 224 assert_eq!(output, *b"AA"); 225 } 226 #[test] 227 fn decode_buffer_exact() { 228 let mut output = [1]; 229 assert_eq!(super::decode_buffer_exact(b"AA", &mut output), Ok(())); 230 assert_eq!(output, [0]); 231 } 232 #[test] 233 fn encode_write_core() { 234 struct Writer<'a>(&'a mut [u8]); 235 impl Write for Writer<'_> { 236 fn write_str(&mut self, s: &str) -> fmt::Result { 237 self.0.get_mut(..s.len()).ok_or(fmt::Error).map(|bytes| { 238 bytes.copy_from_slice(s.as_bytes()); 239 }) 240 } 241 } 242 let mut writer = Writer(&mut [0, 0, 1]); 243 assert_eq!(super::encode_write(&[0], &mut writer), Ok(())); 244 assert_eq!(writer.0, b"AA\x01"); 245 assert_eq!( 246 super::encode_write(&[0, 0, 0], &mut writer), 247 Err(fmt::Error) 248 ); 249 }