mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-08 21:55:47 +00:00
dag_walk: add a few more tests for topo_order_reverse(), extract callbacks
I'm going to add an iterator version which can load linear part of the operation history lazily.
This commit is contained in:
parent
459e9174ad
commit
d9c417dcb8
1 changed files with 94 additions and 12 deletions
|
@ -196,6 +196,8 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::panic;
|
||||||
|
|
||||||
use maplit::{hashmap, hashset};
|
use maplit::{hashmap, hashset};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -212,10 +214,14 @@ mod tests {
|
||||||
'B' => vec!['A'],
|
'B' => vec!['A'],
|
||||||
'C' => vec!['B'],
|
'C' => vec!['B'],
|
||||||
};
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
let common =
|
let common = topo_order_reverse(vec!['C'], id_fn, neighbors_fn);
|
||||||
topo_order_reverse(vec!['C'], |node| *node, move |node| neighbors[node].clone());
|
assert_eq!(common, vec!['C', 'B', 'A']);
|
||||||
|
let common = topo_order_reverse(vec!['C', 'B'], id_fn, neighbors_fn);
|
||||||
|
assert_eq!(common, vec!['C', 'B', 'A']);
|
||||||
|
let common = topo_order_reverse(vec!['B', 'C'], id_fn, neighbors_fn);
|
||||||
assert_eq!(common, vec!['C', 'B', 'A']);
|
assert_eq!(common, vec!['C', 'B', 'A']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,11 +245,49 @@ mod tests {
|
||||||
'E' => vec!['A'],
|
'E' => vec!['A'],
|
||||||
'F' => vec!['E', 'D'],
|
'F' => vec!['E', 'D'],
|
||||||
};
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
let common =
|
let common = topo_order_reverse(vec!['F'], id_fn, neighbors_fn);
|
||||||
topo_order_reverse(vec!['F'], |node| *node, move |node| neighbors[node].clone());
|
|
||||||
|
|
||||||
assert_eq!(common, vec!['F', 'E', 'D', 'C', 'B', 'A']);
|
assert_eq!(common, vec!['F', 'E', 'D', 'C', 'B', 'A']);
|
||||||
|
let common = topo_order_reverse(vec!['F', 'E', 'C'], id_fn, neighbors_fn);
|
||||||
|
assert_eq!(common, vec!['F', 'D', 'E', 'C', 'B', 'A']);
|
||||||
|
let common = topo_order_reverse(vec!['F', 'D', 'E'], id_fn, neighbors_fn);
|
||||||
|
assert_eq!(common, vec!['F', 'D', 'C', 'B', 'E', 'A']);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_topo_order_reverse_nested_merges() {
|
||||||
|
// This graph:
|
||||||
|
// o I
|
||||||
|
// |\
|
||||||
|
// | o H
|
||||||
|
// | |\
|
||||||
|
// | | o G
|
||||||
|
// | o | F
|
||||||
|
// | | o E
|
||||||
|
// o |/ D
|
||||||
|
// | o C
|
||||||
|
// o | B
|
||||||
|
// |/
|
||||||
|
// o A
|
||||||
|
|
||||||
|
let neighbors = hashmap! {
|
||||||
|
'A' => vec![],
|
||||||
|
'B' => vec!['A'],
|
||||||
|
'C' => vec!['A'],
|
||||||
|
'D' => vec!['B'],
|
||||||
|
'E' => vec!['C'],
|
||||||
|
'F' => vec!['C'],
|
||||||
|
'G' => vec!['E'],
|
||||||
|
'H' => vec!['F', 'G'],
|
||||||
|
'I' => vec!['D', 'H'],
|
||||||
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
|
let common = topo_order_reverse(vec!['I'], id_fn, neighbors_fn);
|
||||||
|
assert_eq!(common, vec!['I', 'D', 'B', 'H', 'F', 'G', 'E', 'C', 'A']);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -268,16 +312,54 @@ mod tests {
|
||||||
'E' => vec!['A'],
|
'E' => vec!['A'],
|
||||||
'F' => vec!['E', 'D'],
|
'F' => vec!['E', 'D'],
|
||||||
};
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
let common = topo_order_reverse(
|
let common = topo_order_reverse(vec!['F', 'C'], id_fn, neighbors_fn);
|
||||||
vec!['F', 'C'],
|
|
||||||
|node| *node,
|
|
||||||
move |node| neighbors[node].clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(common, vec!['F', 'E', 'D', 'C', 'B', 'A']);
|
assert_eq!(common, vec!['F', 'E', 'D', 'C', 'B', 'A']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_topo_order_reverse_multiple_roots() {
|
||||||
|
// This graph:
|
||||||
|
// o D
|
||||||
|
// | \
|
||||||
|
// o | C
|
||||||
|
// o B
|
||||||
|
// o A
|
||||||
|
|
||||||
|
let neighbors = hashmap! {
|
||||||
|
'A' => vec![],
|
||||||
|
'B' => vec!['A'],
|
||||||
|
'C' => vec![],
|
||||||
|
'D' => vec!['C', 'B'],
|
||||||
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
|
let common = topo_order_reverse(vec!['D'], id_fn, neighbors_fn);
|
||||||
|
assert_eq!(common, vec!['D', 'C', 'B', 'A']);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_topo_order_reverse_cycle_linear() {
|
||||||
|
// This graph:
|
||||||
|
// o C
|
||||||
|
// o B
|
||||||
|
// o A (to C)
|
||||||
|
|
||||||
|
let neighbors = hashmap! {
|
||||||
|
'A' => vec!['C'],
|
||||||
|
'B' => vec!['A'],
|
||||||
|
'C' => vec!['B'],
|
||||||
|
};
|
||||||
|
let id_fn = |node: &char| *node;
|
||||||
|
let neighbors_fn = |node: &char| neighbors[node].clone();
|
||||||
|
|
||||||
|
let result = panic::catch_unwind(|| topo_order_reverse(vec!['C'], id_fn, neighbors_fn));
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_closest_common_node_tricky() {
|
fn test_closest_common_node_tricky() {
|
||||||
// Test this case where A is the shortest distance away, but we still want the
|
// Test this case where A is the shortest distance away, but we still want the
|
||||||
|
|
Loading…
Reference in a new issue