2022-08-14 17:41:10 -05:00
|
|
|
//! Always use `cargo miri test --all-features`, and never just `cargo test`.
|
2022-05-13 13:14:18 -05:00
|
|
|
|
2022-12-26 11:39:50 -06:00
|
|
|
#[cfg(all(miri, not(feature = "unstable")))]
|
|
|
|
#[test]
|
|
|
|
#[allow(warnings)]
|
|
|
|
fn aaaaaaaaaa_first_alphabetical() {
|
|
|
|
let you_should_specify_dash_dash_all_features = std::ptr::null::<()>();
|
|
|
|
unsafe {
|
|
|
|
*you_should_specify_dash_dash_all_features;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-14 15:13:56 -05:00
|
|
|
use rand::{thread_rng, Rng};
|
|
|
|
|
2022-12-26 11:39:50 -06:00
|
|
|
use super::{dyn_vec, DynVec};
|
2022-08-14 14:21:40 -05:00
|
|
|
use std::{
|
|
|
|
any::Any,
|
|
|
|
fmt::Debug,
|
|
|
|
sync::atomic::{AtomicBool, Ordering},
|
|
|
|
};
|
2022-05-11 13:26:53 -05:00
|
|
|
|
|
|
|
trait DebugExt: Debug {
|
|
|
|
fn debug(&self) -> String {
|
2022-12-26 11:39:50 -06:00
|
|
|
format!("{self:?}")
|
2022-05-11 13:26:53 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-11 13:37:54 -05:00
|
|
|
impl<T: Debug + ?Sized> DebugExt for T {}
|
2022-05-11 13:26:53 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn basic_push() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<i32> = DynVec::new();
|
2022-05-11 13:26:53 -05:00
|
|
|
vec.push(3);
|
|
|
|
vec.push(5);
|
|
|
|
vec.push(7);
|
|
|
|
assert_eq!(vec, [3, 5, 7]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn box_push() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = DynVec::new();
|
2022-08-14 15:32:39 -05:00
|
|
|
vec.push_box(Box::new(1) as _); // makes r-a happy, idk
|
2022-05-11 13:26:53 -05:00
|
|
|
vec.push_box(Box::new(String::from("foo")));
|
|
|
|
vec.push_box(Box::new(true));
|
|
|
|
assert_eq!(vec.debug(), "[1, \"foo\", true]");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn unsize_push() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = DynVec::new();
|
2022-06-08 23:00:11 -05:00
|
|
|
vec.push_unsize_stable(1, |v| v as _);
|
|
|
|
vec.push_unsize_stable(String::from("foo"), |v| v as _);
|
|
|
|
vec.push_unsize_stable(true, |v| v as _);
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec.debug(), "[1, \"foo\", true]");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn all_macro() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec, [3, 5, 7]);
|
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec2: DynVec<dyn Debug> = dyn_vec![box:
|
2022-05-11 13:26:53 -05:00
|
|
|
Box::new(1) as _,
|
|
|
|
Box::new(String::from("foo")) as _,
|
|
|
|
Box::new(true) as _,
|
|
|
|
];
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec3: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec2.debug(), vec3.debug());
|
2022-05-16 09:42:00 -05:00
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec4: DynVec<i32> = dyn_vec![3; 5];
|
2022-05-16 09:42:00 -05:00
|
|
|
assert_eq!(vec4, [3; 5]);
|
2022-05-11 13:26:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn dropped() {
|
|
|
|
static DROPPED: AtomicBool = AtomicBool::new(false);
|
|
|
|
|
|
|
|
#[derive(Debug)] // for dyn Debug
|
|
|
|
struct FunkyDrop;
|
|
|
|
impl Drop for FunkyDrop {
|
|
|
|
fn drop(&mut self) {
|
|
|
|
DROPPED.store(true, Ordering::SeqCst);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, FunkyDrop, true];
|
2022-05-11 13:26:53 -05:00
|
|
|
|
2022-06-08 23:00:11 -05:00
|
|
|
assert!(!DROPPED.load(Ordering::SeqCst));
|
2022-05-11 13:26:53 -05:00
|
|
|
|
|
|
|
drop(vec);
|
|
|
|
|
2022-06-08 23:00:11 -05:00
|
|
|
assert!(DROPPED.load(Ordering::SeqCst));
|
2022-05-11 13:26:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn get() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec.get(0).copied(), Some(3));
|
|
|
|
assert_eq!(vec.get(1).copied(), Some(5));
|
|
|
|
assert_eq!(vec.get(2).copied(), Some(7));
|
|
|
|
assert_eq!(vec.get(3).copied(), None);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic = "index out of bounds: the len is 3 but the index is 3"]
|
|
|
|
fn index() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<i32> = dyn_vec![3, 5, 7];
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec[0], 3);
|
|
|
|
assert_eq!(vec[1], 5);
|
|
|
|
assert_eq!(vec[2], 7);
|
2022-06-08 23:00:11 -05:00
|
|
|
let _ = vec[3];
|
2022-05-11 13:26:53 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn slice_flatten() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<[i32]> = dyn_vec![unsized: [1, 2, 3], [4, 5], [6, 7, 8, 9]];
|
2022-05-11 13:26:53 -05:00
|
|
|
assert_eq!(vec.as_slice_flatten(), [1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
|
|
|
vec.as_mut_slice_flatten()[4] = 10;
|
|
|
|
assert_eq!(vec[1], [4, 10]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn iteration() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
|
2022-05-11 13:26:53 -05:00
|
|
|
|
|
|
|
let mut iter = vec.iter();
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "1");
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "\"foo\"");
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "true");
|
2022-08-14 14:21:40 -05:00
|
|
|
assert_eq!(iter.next().map(|_| ()), None);
|
2022-05-11 13:26:53 -05:00
|
|
|
|
|
|
|
let mut iter = vec.iter_mut(); // TODO: create a trait to properly test this
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "1");
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "\"foo\"");
|
|
|
|
assert_eq!(iter.next().unwrap().debug(), "true");
|
2022-08-14 14:21:40 -05:00
|
|
|
assert_eq!(iter.next().map(|_| ()), None);
|
2022-05-11 13:26:53 -05:00
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut debugs = DynVec::new(); // using custom vec instead of std vec >:)
|
2022-05-11 13:26:53 -05:00
|
|
|
for item in vec {
|
|
|
|
debugs.push(item.debug());
|
|
|
|
}
|
|
|
|
assert_eq!(debugs, ["1", "\"foo\"", "true"]);
|
2022-05-11 13:37:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn zst() {
|
2022-06-08 23:00:11 -05:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
|
|
|
struct Zst;
|
2022-05-11 13:37:54 -05:00
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<Zst> = dyn_vec![Zst, Zst, Zst];
|
2022-06-08 23:00:11 -05:00
|
|
|
|
|
|
|
assert_eq!(vec[1], Zst);
|
2022-05-11 13:37:54 -05:00
|
|
|
for el in vec.iter() {
|
2022-06-08 23:00:11 -05:00
|
|
|
let _ = el;
|
2022-05-11 13:37:54 -05:00
|
|
|
}
|
2022-06-08 23:00:11 -05:00
|
|
|
assert_eq!(vec.debug(), "[Zst, Zst, Zst]");
|
2022-05-11 13:37:54 -05:00
|
|
|
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec: DynVec<dyn Debug> = dyn_vec![unsized: Zst, (), Zst];
|
2022-05-11 13:37:54 -05:00
|
|
|
|
|
|
|
assert_eq!(vec[1].debug(), "()");
|
|
|
|
for el in vec.iter() {
|
2022-06-08 23:00:11 -05:00
|
|
|
let _ = el;
|
2022-05-11 13:37:54 -05:00
|
|
|
}
|
2022-06-08 23:00:11 -05:00
|
|
|
assert_eq!(vec.debug(), "[Zst, (), Zst]");
|
2022-05-13 13:14:18 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn downcast() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Any> = dyn_vec![unsized: 1, String::from("foo"), true];
|
2022-05-13 13:14:18 -05:00
|
|
|
|
|
|
|
assert_eq!(vec.downcast_get::<f32>(0), None);
|
|
|
|
assert_eq!(vec.downcast_get::<i32>(0), Some(&1));
|
|
|
|
assert_eq!(vec.downcast_get_mut::<f32>(1), None);
|
2022-08-14 14:21:40 -05:00
|
|
|
assert_eq!(
|
|
|
|
vec.downcast_get_mut::<String>(1),
|
|
|
|
Some(&mut String::from("foo"))
|
|
|
|
);
|
2022-05-13 13:14:18 -05:00
|
|
|
assert_eq!(vec.downcast_pop::<f32>(), None);
|
|
|
|
assert_eq!(vec.downcast_pop::<bool>(), Some(true));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn pop() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
|
2022-05-13 13:14:18 -05:00
|
|
|
|
|
|
|
assert_eq!(vec.pop().debug(), "Some(true)");
|
|
|
|
assert_eq!(vec.pop().debug(), "Some(\"foo\")");
|
|
|
|
assert_eq!(vec.pop().debug(), "Some(1)");
|
|
|
|
assert_eq!(vec.pop().debug(), "None");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn with_capacity() {
|
|
|
|
// 4 and not 3 cause of `Layout::pad_to_align`
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec = DynVec::with_capacity(4);
|
2022-05-13 13:14:18 -05:00
|
|
|
|
|
|
|
let prev_ptr = vec.as_ptr();
|
|
|
|
|
|
|
|
vec.push(1);
|
|
|
|
vec.push(2);
|
|
|
|
vec.push(3);
|
|
|
|
vec.push(4);
|
|
|
|
|
|
|
|
assert_eq!(prev_ptr, vec.as_ptr());
|
2022-05-16 09:42:00 -05:00
|
|
|
|
|
|
|
vec.push(5);
|
|
|
|
// should have realloc'ed by now
|
|
|
|
|
|
|
|
assert_ne!(prev_ptr, vec.as_ptr());
|
2022-05-16 10:02:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn unsize() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let vec = dyn_vec![1, 2, 3];
|
|
|
|
let mut vec: DynVec<dyn Debug> = vec.unsize_stable(|v| v as _);
|
2022-06-08 23:00:11 -05:00
|
|
|
vec.push_unsize_stable(String::from("foo"), |v| v as _);
|
2022-05-16 10:02:03 -05:00
|
|
|
assert_eq!(vec.debug(), "[1, 2, 3, \"foo\"]");
|
2022-05-17 09:47:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn remove() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = dyn_vec![unsized: 1, String::from("foo"), true];
|
2022-05-17 09:47:54 -05:00
|
|
|
assert_eq!(vec.remove(1).unwrap().debug(), "\"foo\"");
|
|
|
|
assert_eq!(vec.debug(), "[1, true]");
|
2022-08-14 14:21:40 -05:00
|
|
|
}
|
2022-08-14 15:13:56 -05:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn stress_test() {
|
2022-08-19 12:13:36 -05:00
|
|
|
let mut vec: DynVec<dyn Debug> = DynVec::new();
|
2022-08-14 15:13:56 -05:00
|
|
|
|
|
|
|
let mut rng = thread_rng();
|
|
|
|
|
|
|
|
let mut len = 0;
|
|
|
|
|
2022-08-19 11:52:34 -05:00
|
|
|
let iterations = if cfg!(miri) { 100 } else { 1_000_000 };
|
2022-08-14 15:13:56 -05:00
|
|
|
|
|
|
|
for _ in 0..iterations {
|
|
|
|
if len == 0 || rng.gen_bool(0.7) {
|
|
|
|
len += 1;
|
|
|
|
|
|
|
|
match rng.gen_range(1..=3) {
|
|
|
|
1 => vec.push_unsize_stable("a string", |v| v as _),
|
|
|
|
2 => vec.push_unsize_stable(1, |v| v as _),
|
|
|
|
3 => vec.push_unsize_stable(true, |v| v as _),
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
len -= 1;
|
|
|
|
|
|
|
|
vec.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(len, vec.len());
|
|
|
|
}
|
|
|
|
}
|