use crate::{FloatConst, String, Vec, VecChunk, vec_ as vec};
#[test]
fn new() {
let chunk: VecChunk<i32> = VecChunk::default();
assert!(chunk.is_null());
}
#[test]
fn default() {
let chunk: VecChunk<i32> = VecChunk::default();
assert!(chunk.is_null());
}
#[test]
fn is_null() {
let empty: VecChunk<i32> = VecChunk::default();
assert!(empty.is_null());
let non_empty = empty.append(1);
assert!(!non_empty.is_null());
}
#[test]
fn append() {
let chunk = VecChunk::default().append(1).append(2).append(3);
assert_eq!(chunk.as_vec(), vec![1, 2, 3]);
let chunk1 = VecChunk::default().append(1);
let chunk2 = chunk1.clone().append(2);
assert_eq!(chunk1.as_vec(), vec![1]);
assert_eq!(chunk2.as_vec(), vec![1, 2]);
}
#[test]
fn concat() {
let chunk1 = VecChunk::default().append(1).append(2);
let chunk2 = VecChunk::default().append(3).append(4);
let combined = chunk1.clone().concat(chunk2.clone());
assert_eq!(combined.as_vec(), vec![1, 2, 3, 4]);
let empty = VecChunk::default();
assert_eq!(empty.clone().concat(chunk1.clone()).as_vec(), chunk1.as_vec());
assert_eq!(chunk1.clone().concat(empty.clone()).as_vec(), chunk1.as_vec());
assert_eq!(empty.clone().concat(empty).as_vec(), Vec::<i32>::new());
}
#[test]
fn as_vec() {
let empty: VecChunk<i32> = VecChunk::default();
assert_eq!(empty.as_vec(), Vec::<i32>::new());
let single = VecChunk::default().append(42);
assert_eq!(single.as_vec(), vec![42]);
let multiple = VecChunk::default().append(1).append(2).append(3);
assert_eq!(multiple.as_vec(), vec![1, 2, 3]);
let chunk1 = VecChunk::default().append(1).append(2);
let chunk2 = VecChunk::default().append(3).append(4);
let complex = chunk1.concat(chunk2);
assert_eq!(complex.as_vec(), vec![1, 2, 3, 4]);
}
#[test]
fn structural_sharing() {
let chunk1 = VecChunk::default().append(1).append(2);
let chunk2 = chunk1.clone().append(3);
let chunk3 = chunk1.clone().append(4);
assert_eq!(chunk1.as_vec(), vec![1, 2]);
assert_eq!(chunk2.as_vec(), vec![1, 2, 3]);
assert_eq!(chunk3.as_vec(), vec![1, 2, 4]);
}
#[test]
fn with_different_types() {
let string_chunk =
VecChunk::default().append(String::from("hello")).append(String::from("world"));
assert_eq!(string_chunk.as_vec().len(), 2);
let float_chunk = VecChunk::default().append(f64::PI).append(f64::E);
assert_eq!(float_chunk.as_vec(), vec![f64::PI, f64::E]);
let bool_chunk = VecChunk::default().append(true).append(false).append(true);
assert_eq!(bool_chunk.as_vec(), vec![true, false, true]);
}
#[test]
fn transform() {
let empty: VecChunk<i32> = VecChunk::default();
let transformed_empty = empty.transform(|x| x * 2);
assert_eq!(transformed_empty.as_vec(), Vec::<i32>::new());
let single = VecChunk::default().append(5);
let doubled = single.transform(|x| x * 2);
assert_eq!(doubled.as_vec(), vec![10]);
let multiple = VecChunk::default().append(1).append(2).append(3);
let doubled = multiple.transform(|x| x * 2);
assert_eq!(doubled.as_vec(), vec![2, 4, 6]);
let string_chunk =
VecChunk::default().append(String::from("hello")).append(String::from("world"));
let uppercase = string_chunk.transform(|s| s.to_uppercase());
assert_eq!(uppercase.as_vec(), vec!["HELLO", "WORLD"]);
let numbers = VecChunk::default().append(1).append(2).append(3);
let result = numbers.transform(|x| x * 2).transform(|x| x + 1).transform(|x| x * 3);
assert_eq!(result.as_vec(), vec![9, 15, 21]);
}
#[test]
fn transform_flatten() {
let empty: VecChunk<i32> = VecChunk::default();
let transformed_empty = empty.transform_flatten(|x| VecChunk::new(x * 2));
assert_eq!(transformed_empty.as_vec(), Vec::<i32>::new());
let single = VecChunk::default().append(5);
let doubled = single.transform_flatten(|x| VecChunk::new(x * 2));
assert_eq!(doubled.as_vec(), vec![10]);
let numbers = VecChunk::default().append(1).append(2);
let expanded = numbers.transform_flatten(|x| VecChunk::default().append(x + 1).append(x));
assert_eq!(expanded.as_vec(), vec![2, 1, 3, 2]);
let chunk = VecChunk::default().append(1).append(2).append(3);
let nested = chunk.transform_flatten(|x| {
if x % 2 == 0 {
VecChunk::default().append(x).append(x + 1)
} else {
VecChunk::new(x)
}
});
assert_eq!(nested.as_vec(), vec![1, 2, 3, 3]);
let numbers = VecChunk::default().append(1).append(2);
let result = numbers
.transform_flatten(|x| VecChunk::default().append(x).append(x))
.transform_flatten(|x| VecChunk::default().append(x).append(x + 1));
assert_eq!(result.as_vec(), vec![1, 2, 1, 2, 2, 3, 2, 3]);
let chunk = VecChunk::default().append(1).append(2);
let filtered = chunk.transform_flatten(|x| {
if x % 2 == 0 {
VecChunk::new(x)
} else {
VecChunk::default() }
});
assert_eq!(filtered.as_vec(), vec![2]);
}
#[test]
fn prepend() {
let chunk = VecChunk::default().prepend(1).prepend(2).prepend(3);
assert_eq!(chunk.as_vec(), vec![3, 2, 1]);
let chunk1 = VecChunk::default().prepend(1);
let chunk2 = chunk1.clone().prepend(2);
assert_eq!(chunk1.as_vec(), vec![1]);
assert_eq!(chunk2.as_vec(), vec![2, 1]);
let mixed = VecChunk::default()
.prepend(1) .append(2) .prepend(3); assert_eq!(mixed.as_vec(), vec![3, 1, 2]);
}
#[test]
fn from_iterator() {
let empty_vec: Vec<i32> = vec![];
let empty_chunk: VecChunk<i32> = empty_vec.into_iter().collect();
assert!(empty_chunk.is_null());
let vec = vec![1, 2, 3];
let chunk: VecChunk<_> = vec.into_iter().collect();
assert_eq!(chunk.as_vec(), vec![1, 2, 3]);
let range_chunk: VecChunk<_> = (1..=5).collect();
assert_eq!(range_chunk.as_vec(), vec![1, 2, 3, 4, 5]);
let doubled: VecChunk<_> = vec![1, 2, 3].into_iter().map(|x| x * 2).collect();
assert_eq!(doubled.as_vec(), vec![2, 4, 6]);
}
#[test]
fn concat_optimization() {
let collected: VecChunk<i32> = vec![1, 2, 3].into_iter().collect();
let result = collected.concat(VecChunk::Single(4));
assert_eq!(result.as_vec(), vec![1, 2, 3, 4]);
match result {
VecChunk::Collect(_) => (), _ => panic!("Expected Collect variant after optimization"),
}
}