// Copyright 2024 - Strixpyrr // SPDX-License-Identifier: Apache-2.0 #![cfg(feature = "default")] use std::collections::VecDeque; use std::fmt::{Debug, Formatter}; use std::str::from_utf8; use proptest::prelude::*; use proptest::string::bytes_regex; use data_streams::DataSource; struct Utf8Deque { deque: VecDeque, value: String } impl Debug for Utf8Deque { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("Utf8Deque") .field("deque", &self.deque.as_slices()) .field("value", &self.value) .finish() } } fn utf8_deque() -> impl Strategy { (any::(), any::()).prop_map(|(value, mut rotation)| { let mut deque = VecDeque::with_capacity(value.len()); rotation %= deque.len() + 1; let (front, back) = value.as_bytes().split_at(rotation); deque.extend(front); deque.rotate_left(rotation); deque.extend(back); Utf8Deque { deque, value } }) } struct InvalidUtf8Deque { deque: VecDeque, } impl Debug for InvalidUtf8Deque { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("InvalidUtf8Deque") .field("deque", &self.deque.as_slices()) .finish() } } fn invalid_deque() -> impl Strategy { (bytes_regex("(?s-u:.*)").unwrap(), any::()).prop_filter( "only invalid UTF-8", |(bytes, _)| from_utf8(bytes).is_err() ).prop_map(|(bytes, mut rotation)| { let mut deque = VecDeque::with_capacity(bytes.len()); rotation %= deque.len() + 1; let (front, back) = bytes.split_at(rotation); deque.extend(front); deque.rotate_left(rotation); deque.extend(back); InvalidUtf8Deque { deque } }) } proptest! { #[test] fn slice_nominal(input in "(?s:.*)") { let mut buf = vec![0; input.len()]; let result = input.as_bytes().read_utf8(&mut buf); prop_assert!(result.is_ok()); prop_assert_eq!(result.unwrap(), input); } #[test] fn vec_nominal(input in "(?s:.*)") { let mut buf = vec![0; input.len()]; let result = input.clone().into_bytes().read_utf8(&mut buf); prop_assert!(result.is_ok()); prop_assert_eq!(result.unwrap(), input); } #[test] fn vec_deque_nominal(input in utf8_deque()) { let mut buf = vec![0; input.value.len()]; let result = input.deque.clone().read_utf8(&mut buf); prop_assert!(result.is_ok()); prop_assert_eq!(result.unwrap(), input.value); } #[test] fn slice_invalid(input in bytes_regex("(?s-u:.*)").unwrap().prop_filter("only invalid UTF-8", |bytes| from_utf8(bytes).is_err() )) { let mut buf = vec![0; input.len()]; let result = input.as_slice().read_utf8(&mut buf); prop_assert!(result.is_err()); } #[test] fn vec_invalid(input in bytes_regex("(?s-u:.*)").unwrap().prop_filter("only invalid UTF-8", |bytes| from_utf8(bytes).is_err() )) { let mut buf = vec![0; input.len()]; let result = input.clone().read_utf8(&mut buf); prop_assert!(result.is_err()); } #[test] fn vec_deque_invalid(input in invalid_deque()) { let mut buf = vec![0; input.deque.len()]; let result = input.deque.clone().read_utf8(&mut buf); prop_assert!(result.is_err()); } }