dyn_vec/src/test.rs
2022-06-08 23:00:11 -05:00

206 lines
5.3 KiB
Rust

//! Always use `cargo miri test`, and never just `cargo test`.
use super::prelude::{*, vec};
use std::{fmt::Debug, sync::atomic::{AtomicBool, Ordering}, any::Any};
trait DebugExt: Debug {
fn debug(&self) -> String {
format!("{:?}", self)
}
}
impl<T: Debug + ?Sized> DebugExt for T {}
#[test]
fn basic_push() {
let mut vec: Vec<i32> = Vec::new();
vec.push(3);
vec.push(5);
vec.push(7);
assert_eq!(vec, [3, 5, 7]);
}
#[test]
fn box_push() {
let mut vec: Vec<dyn Debug> = Vec::new();
vec.push_box(Box::new(1));
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() {
let mut vec: Vec<dyn Debug> = Vec::new();
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 _);
assert_eq!(vec.debug(), "[1, \"foo\", true]");
}
#[test]
fn all_macro() {
let vec: Vec<i32> = vec![3, 5, 7];
assert_eq!(vec, [3, 5, 7]);
let vec2: Vec<dyn Debug> = vec![box:
Box::new(1) as _,
Box::new(String::from("foo")) as _,
Box::new(true) as _,
];
let vec3: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec2.debug(), vec3.debug());
let vec4: Vec<i32> = vec![3; 5];
assert_eq!(vec4, [3; 5]);
}
#[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);
}
}
let vec: Vec<dyn Debug> = vec![unsized: 1, FunkyDrop, true];
assert!(!DROPPED.load(Ordering::SeqCst));
drop(vec);
assert!(DROPPED.load(Ordering::SeqCst));
}
#[test]
fn get() {
let vec: Vec<i32> = vec![3, 5, 7];
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() {
let vec: Vec<i32> = vec![3, 5, 7];
assert_eq!(vec[0], 3);
assert_eq!(vec[1], 5);
assert_eq!(vec[2], 7);
let _ = vec[3];
}
#[test]
fn slice_flatten() {
let mut vec: Vec<[i32]> = vec![unsized: [1, 2, 3], [4, 5], [6, 7, 8, 9]];
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() {
let mut vec: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
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");
assert_eq!(iter.next().map(|_|()), None);
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");
assert_eq!(iter.next().map(|_|()), None);
let mut debugs = Vec::new(); // using custom vec instead of std vec >:)
for item in vec {
debugs.push(item.debug());
}
assert_eq!(debugs, ["1", "\"foo\"", "true"]);
}
#[test]
fn zst() {
#[derive(Debug, PartialEq, Eq)]
struct Zst;
let vec: Vec<Zst> = vec![Zst, Zst, Zst];
assert_eq!(vec[1], Zst);
for el in vec.iter() {
let _ = el;
}
assert_eq!(vec.debug(), "[Zst, Zst, Zst]");
let vec: Vec<dyn Debug> = vec![unsized: Zst, (), Zst];
assert_eq!(vec[1].debug(), "()");
for el in vec.iter() {
let _ = el;
}
assert_eq!(vec.debug(), "[Zst, (), Zst]");
}
#[test]
fn downcast() {
let mut vec: Vec<dyn Any> = vec![unsized: 1, String::from("foo"), true];
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);
assert_eq!(vec.downcast_get_mut::<String>(1), Some(&mut String::from("foo")));
assert_eq!(vec.downcast_pop::<f32>(), None);
assert_eq!(vec.downcast_pop::<bool>(), Some(true));
}
#[test]
fn pop() {
let mut vec: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
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`
let mut vec = Vec::with_capacity(4);
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());
vec.push(5);
// should have realloc'ed by now
assert_ne!(prev_ptr, vec.as_ptr());
}
#[test]
fn unsize() {
let vec = vec![1, 2, 3];
let mut vec: Vec<dyn Debug> = vec.unsize_stable(|v| v as _);
vec.push_unsize_stable(String::from("foo"), |v| v as _);
assert_eq!(vec.debug(), "[1, 2, 3, \"foo\"]");
}
#[test]
fn remove() {
let mut vec: Vec<dyn Debug> = vec![unsized: 1, String::from("foo"), true];
assert_eq!(vec.remove(1).unwrap().debug(), "\"foo\"");
assert_eq!(vec.debug(), "[1, true]");
}