mod tests {
use astack::*;
#[test]
fn unsafe_stack() {
unsafe {
let mut stack = Stack::<String, 4>::new();
stack.push_unchecked("String".into());
stack.push_unchecked("Another one!".into());
assert_eq!(stack.tos_unchecked(), "Another one!");
assert_eq!(stack.len(), 2);
stack.pop_unchecked();
stack.pop_unchecked();
assert_eq!(stack.tos(), None);
assert!(stack.is_empty());
}
}
#[test]
fn modify_popped() {
let mut stack = Stack::<String, 4>::new();
stack.push("Test!".into()).unwrap();
let mut string = stack.pop().unwrap();
string.push_str("Test again!");
assert_eq!(string, "Test!Test again!");
}
#[test]
fn test_stack_macro() {
let _empty = stack![&str; 10];
let _another_one = stack! {
[usize; 10] = [1, 2, 3]
};
println!("{:#?}", _empty);
println!("{:#?}", _another_one);
}
#[test]
fn test_drop() {
#[derive(Debug)]
struct Droppable;
impl Drop for Droppable {
fn drop(&mut self) {
println!("Dropped!");
}
}
let mut stack = stack![Droppable; 10];
stack.push(Droppable).unwrap();
stack.push(Droppable).unwrap();
stack.pop();
stack.pop();
assert!(stack.pop().is_none());
println!("Here");
println!("{:#?}", stack);
}
#[test]
fn const_assert_test() {
stack! { [i32; 3] = [1] };
stack! { [i32; 3] = [1, 2] };
stack! { [i32; 3] = [1, 2, 4] };
println!("{:#?}", stack! { [i32; 3] = [1, 2, 4] });
}
#[test]
fn test_eq() {
let stack1 = stack! {
[String; 10] = ["a".into()]
};
let stack2 = stack! {
[String; 10] = ["a".into()]
};
assert_eq!(stack1, stack2);
let stack_ne = stack! {
[String; 10] = ["a".into(), "b".into()]
};
assert_ne!(stack1, stack_ne);
assert_ne!(stack2, stack_ne);
let stack3 = stack! {
[char; 10] = ['z', 'y', 'z']
};
let stack4 = stack! {
[char; 10] = ['z', 'y', 'x']
};
assert_ne!(stack3, stack4);
}
#[test]
fn struct_test() {
use std::{cell::RefCell, rc::Rc};
#[derive(PartialEq, Debug)]
struct Yo<T>(Rc<RefCell<T>>);
impl<T> Yo<T> {
fn new(x: T) -> Self {
Self(Rc::new(RefCell::new(x)))
}
}
let stack = stack! {
[Yo<u32>; 4] = [Yo::new(0)]
};
let tos = unsafe { stack.tos_unchecked() };
*RefCell::<_>::borrow_mut(&tos.0) = 10;
assert_eq!(stack.tos(), Some(&Yo::new(10)));
let stack = stack! {
[Yo<String>; 4] = [Yo::new("Hello!".into())]
};
let tos = unsafe { stack.tos_unchecked() };
*RefCell::<_>::borrow_mut(&tos.0) = "World!".into();
assert_eq!(stack.tos(), Some(&Yo::new("World!".into())));
}
#[test]
fn full_stack() {
let mut stack = Stack::<String, 100>::fill_with_fn(|i| i.to_string());
assert!(stack.push(Default::default()).is_err());
stack.clear();
assert!(stack.pop().is_none());
}
#[test]
fn swap_tos_test() {
let mut stack = Stack::<String, 100>::fill_with_fn(|i| i.to_string());
stack.swap_tos("new_tos".into()).unwrap();
stack.clear();
assert!(stack.swap_tos("item".into()).is_err());
}
#[test]
fn test_extend_array() {
let x: [String; 0] = [];
assert_eq!(stack![String; 0], x);
let mut stack = stack![String; 10];
stack
.extend_array(["Test1".to_string(), "Test2".to_string()])
.unwrap();
assert_eq!(stack, ["Test1", "Test2"]);
stack
.extend_array(["Test3".to_string(), "Test4".to_string()])
.unwrap();
assert_eq!(stack, ["Test1", "Test2", "Test3", "Test4"]);
stack.clear();
stack.extend_array(["Final Test!".to_string()]).unwrap();
assert_eq!(stack.tos(), Some(&String::from("Final Test!")));
}
#[test]
fn truncate_items() {
let mut stack = Stack::<String, 10>::fill_with_default();
assert_eq!(stack.truncate(15), Err(StackError::Underflow));
stack.truncate(0).unwrap();
assert!(stack.is_empty());
stack
.extend_array([
"Test1".into(),
"Test2".into(),
"Test3".into(),
"Test4".into(),
])
.unwrap();
assert_eq!(stack.len(), 4);
}
#[test]
fn cut_items() {
let mut stack = Stack::<String, 10>::fill_with_default();
let top_three = stack.cut::<3>();
assert_eq!(top_three, Ok(<[String; 3]>::default()));
assert_eq!(stack, <[String; 7]>::default());
assert_eq!(stack.cut::<8>(), Err(StackError::Underflow));
let _others = stack.cut::<7>();
assert!(stack.is_empty());
}
#[test]
fn extend_items() {
let mut stack = stack![String; 10];
let it = (0..10).map(|n| (n * n).to_string());
assert_eq!(stack.extend(it), Ok(()));
assert!(stack.is_full());
let it = (0..10).map(|n| (n * n).to_string());
assert_eq!(stack.extend(it), Err(StackError::Overflow));
}
#[test]
fn test_clone() {
let stack = stack! {
[String; 5] = ["Test1".to_string(), "Test2".to_string()]
};
let clone = stack.clone();
assert_eq!(clone, stack);
}
#[cfg(feature = "std")]
#[test]
fn std_test() {
fn accepts_error(_err: &dyn std::error::Error) {}
accepts_error(&StackError::Overflow);
}
#[cfg(feature = "std")]
#[test]
fn vec_into_stack() {
let vec = std::vec![1, 2, 3, 4, 5, 6];
let stack = Stack::<i32, 8>::try_from(vec);
assert!(stack.is_ok());
let bigger_vec = std::vec![6, 7, 8, 9, 0, 1, 2, 3];
let smaller_stack = Stack::<i32, 4>::try_from(bigger_vec);
assert!(smaller_stack.is_err());
}
#[cfg(feature = "std")]
#[test]
fn stack_into_vec() {
let stack = stack! {
[String; 4] = ["Hello".to_string(), "world".to_string()]
};
assert_eq!(stack.tos(), Some(&String::from("world")));
let v = Vec::from(stack.clone());
dbg!(&v);
dbg!(&stack);
assert_eq!(v, ["Hello".to_string(), "world".to_string()]);
assert_eq!(stack.tos(), v.last());
}
#[cfg(feature = "std")]
#[test]
fn stack_into_iter_leak() {
let stack = stack! {
[String; 10] = ["1".into(), "3".into(), "5".into()]
};
let _it = stack.into_iter();
}
#[cfg(feature = "std")]
#[test]
fn stack_into_iter() {
let stack = stack! {
[String; 10] = ["1".into(), "3".into(), "5".into()]
};
assert_eq!(stack.tos(), Some(&String::from("5")));
let mut it = stack.into_iter();
assert_eq!(it.next(), Some(String::from("5")));
assert_eq!(it.next_back(), Some(String::from("1")));
assert_eq!(it.next_back(), Some(String::from("3")));
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
let another_one = Stack::<String, 12>::try_from(vec![
"1".to_string(),
"2".to_string(),
"3".to_string(),
"4".to_string(),
"5".to_string(),
"6".to_string(),
"7".to_string(),
"8".to_string(),
"9".to_string(),
"10".to_string(),
])
.unwrap();
assert_eq!(another_one.tos(), Some(&String::from("10")));
let mut it = another_one.into_iter();
assert_eq!(it.next(), Some(String::from("10")));
assert_eq!(it.next_back(), Some(String::from("1")));
assert_eq!(it.next(), Some(String::from("9")));
assert_eq!(it.next_back(), Some(String::from("2")));
dbg!(&it);
assert_eq!(
it.rev().collect::<Vec<_>>(),
vec![
"3".to_string(),
"4".to_string(),
"5".to_string(),
"6".to_string(),
"7".to_string(),
"8".to_string(),
]
);
}
#[cfg(feature = "std")]
#[test]
fn stack_iter_clone() {
let stack = stack! {
[String; 4] = [
"1".to_string(),
"2".to_string(),
"3".to_string(),
"4".to_string(),
]
};
let it = stack.into_iter();
let cloned = it.clone();
assert_eq!(it, cloned);
for (item1, item2) in it.zip(cloned) {
assert_eq!(item1, item2);
}
let mut it = stack![String; 0].into_iter();
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);
assert_eq!(it.next_back(), None);
}
}