Add unit tests for ElementMap::remap
This commit is contained in:
+140
@@ -142,6 +142,7 @@ impl<E: Copy, T: Clone> IndexMut<E> for ElementMap<E, T> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn initial_values_are_default() {
|
fn initial_values_are_default() {
|
||||||
@@ -238,4 +239,143 @@ mod tests {
|
|||||||
"slot added by grow should hold the mapped default"
|
"slot added by grow should hold the mapped default"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap() {
|
||||||
|
let mut source = ElementMap::new('-', |e| e, 3);
|
||||||
|
source[0] = 'a';
|
||||||
|
source[1] = 'b';
|
||||||
|
source[2] = 'c';
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 3);
|
||||||
|
mapping[0] = 2;
|
||||||
|
mapping[1] = 0;
|
||||||
|
mapping[2] = 1;
|
||||||
|
let template = ElementMap::new((), |f| f, 3);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(result[0], 'b', "unexpected value at slot 0");
|
||||||
|
assert_eq!(result[1], 'c', "unexpected value at slot 1");
|
||||||
|
assert_eq!(result[2], 'a', "unexpected value at slot 2");
|
||||||
|
assert_eq!(
|
||||||
|
result.default, '-',
|
||||||
|
"default should be taken from the source map"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_skips_default() {
|
||||||
|
let mut source = ElementMap::new(0, |e| e, 3);
|
||||||
|
source[0] = 1;
|
||||||
|
source[1] = 2;
|
||||||
|
source[2] = 3;
|
||||||
|
// Slot 1 stays unmapped, which would be out of bounds for the template if it was used.
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 3);
|
||||||
|
mapping[0] = 1;
|
||||||
|
mapping[2] = 0;
|
||||||
|
let template = ElementMap::new((), |f| f, 2);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(result[0], 3, "unexpected value at slot 0");
|
||||||
|
assert_eq!(result[1], 1, "unexpected value at slot 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_unmapped_slots() {
|
||||||
|
let mut source = ElementMap::new(9, |e| e, 2);
|
||||||
|
source[0] = 1;
|
||||||
|
source[1] = 2;
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 2);
|
||||||
|
mapping[0] = 0;
|
||||||
|
mapping[1] = 2;
|
||||||
|
let template = ElementMap::new((), |f| f, 4);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(
|
||||||
|
result.data,
|
||||||
|
vec![1, 9, 2, 9],
|
||||||
|
"should have the template's length, with unmapped slots holding the source's default"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_index_function() {
|
||||||
|
let mut source = ElementMap::<usize, i32>::new(0, |e| e, 3);
|
||||||
|
source[0] = 10;
|
||||||
|
source[1] = 20;
|
||||||
|
source[2] = 30;
|
||||||
|
let mut mapping = ElementMap::<usize, u32>::new(u32::MAX, |e| e, 3);
|
||||||
|
mapping[0] = 0;
|
||||||
|
mapping[1] = 1;
|
||||||
|
mapping[2] = 2;
|
||||||
|
// Reverses the order of the slots.
|
||||||
|
let template = ElementMap::<u32, ()>::new((), |f| 2 - f as usize, 3);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(
|
||||||
|
result.data,
|
||||||
|
vec![30, 20, 10],
|
||||||
|
"values should be written at the slots given by the template's index function"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
(result.to_index)(0),
|
||||||
|
2,
|
||||||
|
"index function should be taken from the template"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_shorter_source() {
|
||||||
|
let mut source = ElementMap::new(9, |e| e, 2);
|
||||||
|
source[0] = 5;
|
||||||
|
source[1] = 6;
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 4);
|
||||||
|
for i in 0..4 {
|
||||||
|
mapping[i] = i;
|
||||||
|
}
|
||||||
|
let template = ElementMap::new((), |f| f, 4);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(result.data, vec![5, 6, 9, 9], "unexpected data");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_longer_source() {
|
||||||
|
let mut source = ElementMap::new(0, |e| e, 4);
|
||||||
|
for i in 0..4 {
|
||||||
|
source[i] = i + 1;
|
||||||
|
}
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 2);
|
||||||
|
mapping[0] = 1;
|
||||||
|
mapping[1] = 0;
|
||||||
|
let template = ElementMap::new((), |f| f, 2);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(result.data, vec![2, 1], "unexpected data");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_empty() {
|
||||||
|
let source = ElementMap::new(0, |e| e, 0);
|
||||||
|
let mapping = ElementMap::new(usize::MAX, |e| e, 0);
|
||||||
|
let template = ElementMap::new((), |f| f, 0);
|
||||||
|
let result = source.remap(&mapping, &template);
|
||||||
|
assert_eq!(result.data, Vec::<i32>::new(), "should be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remap_clones_values() {
|
||||||
|
let value = Rc::new(1);
|
||||||
|
let mut source = ElementMap::new(Rc::new(0), |e| e, 1);
|
||||||
|
source[0] = Rc::clone(&value);
|
||||||
|
let mut mapping = ElementMap::new(usize::MAX, |e| e, 1);
|
||||||
|
mapping[0] = 0;
|
||||||
|
let template = ElementMap::new((), |f| f, 1);
|
||||||
|
let _result = source.remap(&mapping, &template);
|
||||||
|
// The local variable, the source slot and the result slot each hold one reference.
|
||||||
|
assert_eq!(
|
||||||
|
Rc::strong_count(&value),
|
||||||
|
3,
|
||||||
|
"result should hold its own clone of the value"
|
||||||
|
);
|
||||||
|
drop(source);
|
||||||
|
assert_eq!(
|
||||||
|
Rc::strong_count(&value),
|
||||||
|
2,
|
||||||
|
"result should keep the value alive on its own"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user