ok/jj
1
0
Fork 0
forked from mirrors/jj

conflicts: move Merge tests to merge module

I missed the tests when I moved the type.
This commit is contained in:
Martin von Zweigbergk 2023-08-06 15:12:15 -07:00 committed by Martin von Zweigbergk
parent af2dba1c8f
commit b9b285c985
2 changed files with 216 additions and 221 deletions

View file

@ -249,224 +249,3 @@ fn parse_conflict_hunk(input: &[u8]) -> Merge<ContentHunk> {
Merge::new(removes, adds)
}
#[cfg(test)]
mod tests {
use super::*;
fn c<T: Clone>(removes: &[T], adds: &[T]) -> Merge<T> {
Merge::new(removes.to_vec(), adds.to_vec())
}
#[test]
fn test_legacy_form_conversion() {
fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
where
T: Clone + PartialEq + std::fmt::Debug,
{
assert_eq!(merge.clone().into_legacy_form(), legacy_form);
assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
}
// Non-conflict
test_equivalent((vec![], vec![0]), Merge::new(vec![], vec![Some(0)]));
// Regular 3-way conflict
test_equivalent(
(vec![0], vec![1, 2]),
Merge::new(vec![Some(0)], vec![Some(1), Some(2)]),
);
// Modify/delete conflict
test_equivalent(
(vec![0], vec![1]),
Merge::new(vec![Some(0)], vec![Some(1), None]),
);
// Add/add conflict
test_equivalent(
(vec![], vec![0, 1]),
Merge::new(vec![None], vec![Some(0), Some(1)]),
);
// 5-way conflict
test_equivalent(
(vec![0, 1], vec![2, 3, 4]),
Merge::new(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
);
// 5-way delete/delete conflict
test_equivalent(
(vec![0, 1], vec![]),
Merge::new(vec![Some(0), Some(1)], vec![None, None, None]),
);
}
#[test]
fn test_as_resolved() {
assert_eq!(Merge::new(vec![], vec![0]).as_resolved(), Some(&0));
// Even a trivially resolvable merge is not resolved
assert_eq!(Merge::new(vec![0], vec![0, 1]).as_resolved(), None);
}
#[test]
fn test_simplify() {
// 1-way merge
assert_eq!(c(&[], &[0]).simplify(), c(&[], &[0]));
// 3-way merge
assert_eq!(c(&[0], &[0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0], &[0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0], &[1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0], &[1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0], &[1, 2]).simplify(), c(&[0], &[1, 2]));
// 5-way merge
assert_eq!(c(&[0, 0], &[0, 0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 0], &[0, 0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[0, 1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[0, 1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[0, 1, 2]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 0, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[1, 0, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[1, 0, 2]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 1, 0]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[1, 1, 1]).simplify(), c(&[0, 0], &[1, 1, 1]));
assert_eq!(c(&[0, 0], &[1, 1, 2]).simplify(), c(&[0, 0], &[1, 1, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 0]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 1]).simplify(), c(&[0, 0], &[1, 2, 1]));
assert_eq!(c(&[0, 0], &[1, 2, 2]).simplify(), c(&[0, 0], &[1, 2, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 3]).simplify(), c(&[0, 0], &[1, 2, 3]));
assert_eq!(c(&[0, 1], &[0, 0, 0]).simplify(), c(&[1], &[0, 0]));
assert_eq!(c(&[0, 1], &[0, 0, 1]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[0, 0, 2]).simplify(), c(&[1], &[0, 2]));
assert_eq!(c(&[0, 1], &[0, 1, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[0, 1, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[0, 1, 2]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[0, 2, 0]).simplify(), c(&[1], &[2, 0]));
assert_eq!(c(&[0, 1], &[0, 2, 1]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[0, 2, 2]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[0, 2, 3]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[1, 0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[1, 0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[1, 0, 2]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[1, 1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[1, 1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 1], &[1, 1, 2]).simplify(), c(&[0], &[2, 1]));
assert_eq!(c(&[0, 1], &[1, 2, 0]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[1, 2, 1]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 1], &[1, 2, 2]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[1, 2, 3]).simplify(), c(&[0], &[3, 2]));
assert_eq!(c(&[0, 1], &[2, 0, 0]).simplify(), c(&[1], &[2, 0]));
assert_eq!(c(&[0, 1], &[2, 0, 1]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[2, 0, 2]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 0, 3]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 1, 0]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[2, 1, 1]).simplify(), c(&[0], &[2, 1]));
assert_eq!(c(&[0, 1], &[2, 1, 2]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 1, 3]).simplify(), c(&[0], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 2, 0]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 1]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 2]).simplify(), c(&[0, 1], &[2, 2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 3]).simplify(), c(&[0, 1], &[2, 2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 0]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 1]).simplify(), c(&[0], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 2]).simplify(), c(&[0, 1], &[2, 3, 2]));
assert_eq!(c(&[0, 1], &[2, 3, 3]).simplify(), c(&[0, 1], &[2, 3, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 4]).simplify(), c(&[0, 1], &[2, 3, 4]));
assert_eq!(
c(&[0, 1, 2], &[3, 4, 5, 0]).simplify(),
c(&[1, 2], &[3, 5, 4])
);
}
#[test]
fn test_merge_invariants() {
fn check_invariants(removes: &[u32], adds: &[u32]) {
let merge = Merge::new(removes.to_vec(), adds.to_vec());
// `simplify()` is idempotent
assert_eq!(
merge.clone().simplify().simplify(),
merge.clone().simplify(),
"simplify() not idempotent for {merge:?}"
);
// `resolve_trivial()` is unaffected by `simplify()`
assert_eq!(
merge.clone().simplify().resolve_trivial(),
merge.resolve_trivial(),
"simplify() changed result of resolve_trivial() for {merge:?}"
);
}
// 1-way merge
check_invariants(&[], &[0]);
for i in 0..=1 {
for j in 0..=i + 1 {
// 3-way merge
check_invariants(&[0], &[i, j]);
for k in 0..=j + 1 {
for l in 0..=k + 1 {
// 5-way merge
check_invariants(&[0, i], &[j, k, l]);
}
}
}
}
}
#[test]
fn test_map() {
fn increment(i: &i32) -> i32 {
i + 1
}
// 1-way merge
assert_eq!(c(&[], &[1]).map(increment), c(&[], &[2]));
// 3-way merge
assert_eq!(c(&[1], &[3, 5]).map(increment), c(&[2], &[4, 6]));
}
#[test]
fn test_maybe_map() {
fn sqrt(i: &i32) -> Option<i32> {
if *i >= 0 {
Some((*i as f64).sqrt() as i32)
} else {
None
}
}
// 1-way merge
assert_eq!(c(&[], &[1]).maybe_map(sqrt), Some(c(&[], &[1])));
assert_eq!(c(&[], &[-1]).maybe_map(sqrt), None);
// 3-way merge
assert_eq!(c(&[1], &[4, 9]).maybe_map(sqrt), Some(c(&[1], &[2, 3])));
assert_eq!(c(&[-1], &[4, 9]).maybe_map(sqrt), None);
assert_eq!(c(&[1], &[-4, 9]).maybe_map(sqrt), None);
}
#[test]
fn test_try_map() {
fn sqrt(i: &i32) -> Result<i32, ()> {
if *i >= 0 {
Ok((*i as f64).sqrt() as i32)
} else {
Err(())
}
}
// 1-way merge
assert_eq!(c(&[], &[1]).try_map(sqrt), Ok(c(&[], &[1])));
assert_eq!(c(&[], &[-1]).try_map(sqrt), Err(()));
// 3-way merge
assert_eq!(c(&[1], &[4, 9]).try_map(sqrt), Ok(c(&[1], &[2, 3])));
assert_eq!(c(&[-1], &[4, 9]).try_map(sqrt), Err(()));
assert_eq!(c(&[1], &[-4, 9]).try_map(sqrt), Err(()));
}
#[test]
fn test_flatten() {
// 1-way merge of 1-way merge
assert_eq!(c(&[], &[c(&[], &[0])]).flatten(), c(&[], &[0]));
// 1-way merge of 3-way merge
assert_eq!(c(&[], &[c(&[0], &[1, 2])]).flatten(), c(&[0], &[1, 2]));
// 3-way merge of 1-way merges
assert_eq!(
c(&[c(&[], &[0])], &[c(&[], &[1]), c(&[], &[2])]).flatten(),
c(&[0], &[1, 2])
);
// 3-way merge of 3-way merges
assert_eq!(
c(&[c(&[0], &[1, 2])], &[c(&[3], &[4, 5]), c(&[6], &[7, 8])]).flatten(),
c(&[3, 2, 1, 6], &[4, 5, 0, 7, 8])
);
}
}

View file

@ -550,6 +550,10 @@ fn get_file_contents(store: &Store, path: &RepoPath, term: &Option<FileId>) -> C
mod tests {
use super::*;
fn c<T: Clone>(removes: &[T], adds: &[T]) -> Merge<T> {
Merge::new(removes.to_vec(), adds.to_vec())
}
#[test]
fn test_trivial_merge() {
assert_eq!(trivial_merge(&[], &[0]), Some(&0));
@ -611,4 +615,216 @@ mod tests {
assert_eq!(trivial_merge(&[0, 1], &[2, 3, 3]), None);
assert_eq!(trivial_merge(&[0, 1], &[2, 3, 4]), None);
}
#[test]
fn test_legacy_form_conversion() {
fn test_equivalent<T>(legacy_form: (Vec<T>, Vec<T>), merge: Merge<Option<T>>)
where
T: Clone + PartialEq + std::fmt::Debug,
{
assert_eq!(merge.clone().into_legacy_form(), legacy_form);
assert_eq!(Merge::from_legacy_form(legacy_form.0, legacy_form.1), merge);
}
// Non-conflict
test_equivalent((vec![], vec![0]), Merge::new(vec![], vec![Some(0)]));
// Regular 3-way conflict
test_equivalent(
(vec![0], vec![1, 2]),
Merge::new(vec![Some(0)], vec![Some(1), Some(2)]),
);
// Modify/delete conflict
test_equivalent(
(vec![0], vec![1]),
Merge::new(vec![Some(0)], vec![Some(1), None]),
);
// Add/add conflict
test_equivalent(
(vec![], vec![0, 1]),
Merge::new(vec![None], vec![Some(0), Some(1)]),
);
// 5-way conflict
test_equivalent(
(vec![0, 1], vec![2, 3, 4]),
Merge::new(vec![Some(0), Some(1)], vec![Some(2), Some(3), Some(4)]),
);
// 5-way delete/delete conflict
test_equivalent(
(vec![0, 1], vec![]),
Merge::new(vec![Some(0), Some(1)], vec![None, None, None]),
);
}
#[test]
fn test_as_resolved() {
assert_eq!(Merge::new(vec![], vec![0]).as_resolved(), Some(&0));
// Even a trivially resolvable merge is not resolved
assert_eq!(Merge::new(vec![0], vec![0, 1]).as_resolved(), None);
}
#[test]
fn test_simplify() {
// 1-way merge
assert_eq!(c(&[], &[0]).simplify(), c(&[], &[0]));
// 3-way merge
assert_eq!(c(&[0], &[0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0], &[0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0], &[1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0], &[1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0], &[1, 2]).simplify(), c(&[0], &[1, 2]));
// 5-way merge
assert_eq!(c(&[0, 0], &[0, 0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 0], &[0, 0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[0, 1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[0, 1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[0, 1, 2]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 0, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 0], &[1, 0, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[1, 0, 2]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 1, 0]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 0], &[1, 1, 1]).simplify(), c(&[0, 0], &[1, 1, 1]));
assert_eq!(c(&[0, 0], &[1, 1, 2]).simplify(), c(&[0, 0], &[1, 1, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 0]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 1]).simplify(), c(&[0, 0], &[1, 2, 1]));
assert_eq!(c(&[0, 0], &[1, 2, 2]).simplify(), c(&[0, 0], &[1, 2, 2]));
assert_eq!(c(&[0, 0], &[1, 2, 3]).simplify(), c(&[0, 0], &[1, 2, 3]));
assert_eq!(c(&[0, 1], &[0, 0, 0]).simplify(), c(&[1], &[0, 0]));
assert_eq!(c(&[0, 1], &[0, 0, 1]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[0, 0, 2]).simplify(), c(&[1], &[0, 2]));
assert_eq!(c(&[0, 1], &[0, 1, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[0, 1, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[0, 1, 2]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[0, 2, 0]).simplify(), c(&[1], &[2, 0]));
assert_eq!(c(&[0, 1], &[0, 2, 1]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[0, 2, 2]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[0, 2, 3]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[1, 0, 0]).simplify(), c(&[], &[0]));
assert_eq!(c(&[0, 1], &[1, 0, 1]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[1, 0, 2]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[1, 1, 0]).simplify(), c(&[], &[1]));
assert_eq!(c(&[0, 1], &[1, 1, 1]).simplify(), c(&[0], &[1, 1]));
assert_eq!(c(&[0, 1], &[1, 1, 2]).simplify(), c(&[0], &[2, 1]));
assert_eq!(c(&[0, 1], &[1, 2, 0]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[1, 2, 1]).simplify(), c(&[0], &[1, 2]));
assert_eq!(c(&[0, 1], &[1, 2, 2]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[1, 2, 3]).simplify(), c(&[0], &[3, 2]));
assert_eq!(c(&[0, 1], &[2, 0, 0]).simplify(), c(&[1], &[2, 0]));
assert_eq!(c(&[0, 1], &[2, 0, 1]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[2, 0, 2]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 0, 3]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 1, 0]).simplify(), c(&[], &[2]));
assert_eq!(c(&[0, 1], &[2, 1, 1]).simplify(), c(&[0], &[2, 1]));
assert_eq!(c(&[0, 1], &[2, 1, 2]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 1, 3]).simplify(), c(&[0], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 2, 0]).simplify(), c(&[1], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 1]).simplify(), c(&[0], &[2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 2]).simplify(), c(&[0, 1], &[2, 2, 2]));
assert_eq!(c(&[0, 1], &[2, 2, 3]).simplify(), c(&[0, 1], &[2, 2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 0]).simplify(), c(&[1], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 1]).simplify(), c(&[0], &[2, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 2]).simplify(), c(&[0, 1], &[2, 3, 2]));
assert_eq!(c(&[0, 1], &[2, 3, 3]).simplify(), c(&[0, 1], &[2, 3, 3]));
assert_eq!(c(&[0, 1], &[2, 3, 4]).simplify(), c(&[0, 1], &[2, 3, 4]));
assert_eq!(
c(&[0, 1, 2], &[3, 4, 5, 0]).simplify(),
c(&[1, 2], &[3, 5, 4])
);
}
#[test]
fn test_merge_invariants() {
fn check_invariants(removes: &[u32], adds: &[u32]) {
let merge = Merge::new(removes.to_vec(), adds.to_vec());
// `simplify()` is idempotent
assert_eq!(
merge.clone().simplify().simplify(),
merge.clone().simplify(),
"simplify() not idempotent for {merge:?}"
);
// `resolve_trivial()` is unaffected by `simplify()`
assert_eq!(
merge.clone().simplify().resolve_trivial(),
merge.resolve_trivial(),
"simplify() changed result of resolve_trivial() for {merge:?}"
);
}
// 1-way merge
check_invariants(&[], &[0]);
for i in 0..=1 {
for j in 0..=i + 1 {
// 3-way merge
check_invariants(&[0], &[i, j]);
for k in 0..=j + 1 {
for l in 0..=k + 1 {
// 5-way merge
check_invariants(&[0, i], &[j, k, l]);
}
}
}
}
}
#[test]
fn test_map() {
fn increment(i: &i32) -> i32 {
i + 1
}
// 1-way merge
assert_eq!(c(&[], &[1]).map(increment), c(&[], &[2]));
// 3-way merge
assert_eq!(c(&[1], &[3, 5]).map(increment), c(&[2], &[4, 6]));
}
#[test]
fn test_maybe_map() {
fn sqrt(i: &i32) -> Option<i32> {
if *i >= 0 {
Some((*i as f64).sqrt() as i32)
} else {
None
}
}
// 1-way merge
assert_eq!(c(&[], &[1]).maybe_map(sqrt), Some(c(&[], &[1])));
assert_eq!(c(&[], &[-1]).maybe_map(sqrt), None);
// 3-way merge
assert_eq!(c(&[1], &[4, 9]).maybe_map(sqrt), Some(c(&[1], &[2, 3])));
assert_eq!(c(&[-1], &[4, 9]).maybe_map(sqrt), None);
assert_eq!(c(&[1], &[-4, 9]).maybe_map(sqrt), None);
}
#[test]
fn test_try_map() {
fn sqrt(i: &i32) -> Result<i32, ()> {
if *i >= 0 {
Ok((*i as f64).sqrt() as i32)
} else {
Err(())
}
}
// 1-way merge
assert_eq!(c(&[], &[1]).try_map(sqrt), Ok(c(&[], &[1])));
assert_eq!(c(&[], &[-1]).try_map(sqrt), Err(()));
// 3-way merge
assert_eq!(c(&[1], &[4, 9]).try_map(sqrt), Ok(c(&[1], &[2, 3])));
assert_eq!(c(&[-1], &[4, 9]).try_map(sqrt), Err(()));
assert_eq!(c(&[1], &[-4, 9]).try_map(sqrt), Err(()));
}
#[test]
fn test_flatten() {
// 1-way merge of 1-way merge
assert_eq!(c(&[], &[c(&[], &[0])]).flatten(), c(&[], &[0]));
// 1-way merge of 3-way merge
assert_eq!(c(&[], &[c(&[0], &[1, 2])]).flatten(), c(&[0], &[1, 2]));
// 3-way merge of 1-way merges
assert_eq!(
c(&[c(&[], &[0])], &[c(&[], &[1]), c(&[], &[2])]).flatten(),
c(&[0], &[1, 2])
);
// 3-way merge of 3-way merges
assert_eq!(
c(&[c(&[0], &[1, 2])], &[c(&[3], &[4, 5]), c(&[6], &[7, 8])]).flatten(),
c(&[3, 2, 1, 6], &[4, 5, 0, 7, 8])
);
}
}