mirror of
https://github.com/facebook/sapling.git
synced 2024-12-28 15:44:27 +03:00
renderdag: add tests showing how orders affect rendering
Summary: I wrote it to understand how renderdag draws the same graph with different orders. It seems useful for future optimization that tries to reduce the number of columns. So let's check it in. Reviewed By: xavierd Differential Revision: D19440713 fbshipit-source-id: 8bc580799f6b24c87886d5ac306020f50bb694e5
This commit is contained in:
parent
09618791bd
commit
52af332c28
@ -291,7 +291,7 @@ where
|
||||
mod tests {
|
||||
use crate::render::GraphRowRenderer;
|
||||
use crate::test_fixtures::{self, TestFixture};
|
||||
use crate::test_utils::render_string;
|
||||
use crate::test_utils::{render_string, render_string_with_order};
|
||||
|
||||
fn render(fixture: &TestFixture) -> String {
|
||||
let mut renderer = GraphRowRenderer::new().output().build_box_drawing();
|
||||
@ -525,4 +525,137 @@ mod tests {
|
||||
long message 3"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn different_orders() {
|
||||
let order = |order: &str| {
|
||||
let order = order.matches(|_: char| true).collect::<Vec<_>>();
|
||||
let mut renderer = GraphRowRenderer::new().output().build_box_drawing();
|
||||
render_string_with_order(&test_fixtures::ORDERS1, &mut renderer, Some(&order))
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
order("KJIHGFEDCBZA"),
|
||||
r#"
|
||||
o K
|
||||
├─╮
|
||||
│ o J
|
||||
│ ├─╮
|
||||
│ │ o I
|
||||
│ │ ├─╮
|
||||
│ │ │ o H
|
||||
│ │ │ ├─╮
|
||||
│ │ │ │ o G
|
||||
│ │ │ │ ├─╮
|
||||
o │ │ │ │ │ F
|
||||
│ │ │ │ │ │
|
||||
│ o │ │ │ │ E
|
||||
├─╯ │ │ │ │
|
||||
│ o │ │ │ D
|
||||
├───╯ │ │ │
|
||||
│ o │ │ C
|
||||
├─────╯ │ │
|
||||
│ o │ B
|
||||
├───────╯ │
|
||||
│ o Z
|
||||
│
|
||||
o A"#
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
order("KJIHGZBCDEFA"),
|
||||
r#"
|
||||
o K
|
||||
├─╮
|
||||
│ o J
|
||||
│ ├─╮
|
||||
│ │ o I
|
||||
│ │ ├─╮
|
||||
│ │ │ o H
|
||||
│ │ │ ├─╮
|
||||
│ │ │ │ o G
|
||||
│ │ │ │ ├─╮
|
||||
│ │ │ │ │ o Z
|
||||
│ │ │ │ │
|
||||
│ │ │ │ o B
|
||||
│ │ │ │ │
|
||||
│ │ │ o │ C
|
||||
│ │ │ ├─╯
|
||||
│ │ o │ D
|
||||
│ │ ├─╯
|
||||
│ o │ E
|
||||
│ ├─╯
|
||||
o │ F
|
||||
├─╯
|
||||
o A"#
|
||||
);
|
||||
|
||||
// Keeping the p1 branch the longest path (KFEDCBA) is a reasonable
|
||||
// optimization for a cleaner graph (less columns, more text space).
|
||||
assert_eq!(
|
||||
render(&test_fixtures::ORDERS2),
|
||||
r#"
|
||||
o K
|
||||
├─╮
|
||||
│ o J
|
||||
│ │
|
||||
o │ F
|
||||
├───╮
|
||||
│ │ o I
|
||||
│ ├─╯
|
||||
o │ E
|
||||
├───╮
|
||||
│ │ o H
|
||||
│ ├─╯
|
||||
o │ D
|
||||
├───╮
|
||||
│ │ o G
|
||||
│ ├─╯
|
||||
o │ C
|
||||
├───╮
|
||||
│ │ o Z
|
||||
│ │
|
||||
o │ B
|
||||
├─╯
|
||||
o A"#
|
||||
);
|
||||
|
||||
// Try to use the ORDERS2 order. However, the parent ordering in the
|
||||
// graph is different, which makes the rendering different.
|
||||
//
|
||||
// Note: it's KJFIEHDGCZBA in the ORDERS2 graph. To map it to ORDERS1,
|
||||
// follow:
|
||||
//
|
||||
// ORDERS1: KFJEIDHCGBZA
|
||||
// ORDERS2: KJFIEHDGCBZA
|
||||
//
|
||||
// And we get KFJEIDHCGZBA.
|
||||
assert_eq!(
|
||||
order("KFJEIDHCGZBA"),
|
||||
r#"
|
||||
o K
|
||||
├─╮
|
||||
o │ F
|
||||
│ │
|
||||
│ o J
|
||||
│ ├─╮
|
||||
│ o │ E
|
||||
├─╯ │
|
||||
│ o I
|
||||
│ ╭─┤
|
||||
│ │ o D
|
||||
├───╯
|
||||
│ o H
|
||||
│ ├─╮
|
||||
│ o │ C
|
||||
├─╯ │
|
||||
│ o G
|
||||
│ ╭─┤
|
||||
│ o │ Z
|
||||
│ │
|
||||
│ o B
|
||||
├───╯
|
||||
o A"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -127,3 +127,50 @@ pub(crate) const LONG_MESSAGES: TestFixture = TestFixture {
|
||||
ancestors: &[],
|
||||
missing: &["Y", "Z"],
|
||||
};
|
||||
|
||||
pub(crate) const ORDERS1: TestFixture = TestFixture {
|
||||
dag: r#"
|
||||
K
|
||||
/|
|
||||
F J
|
||||
/ /|
|
||||
| E I
|
||||
|/ /|
|
||||
| D H
|
||||
|/ /|
|
||||
| C G
|
||||
|/ /|
|
||||
| B Z
|
||||
|/
|
||||
A
|
||||
"#,
|
||||
messages: &[],
|
||||
heads: &["K"],
|
||||
reserve: &[],
|
||||
ancestors: &[],
|
||||
missing: &[],
|
||||
};
|
||||
|
||||
// Unlike ORDERS1, the first-parent branch (KFEDCBA) is the longest path.
|
||||
pub(crate) const ORDERS2: TestFixture = TestFixture {
|
||||
dag: r#"
|
||||
K
|
||||
/|
|
||||
J F
|
||||
/ /|
|
||||
| I E
|
||||
|/ /|
|
||||
| H D
|
||||
|/ /|
|
||||
| G C
|
||||
|/ /|
|
||||
| B Z
|
||||
|/
|
||||
A
|
||||
"#,
|
||||
messages: &[],
|
||||
heads: &["K"],
|
||||
reserve: &[],
|
||||
ancestors: &[],
|
||||
missing: &[],
|
||||
};
|
||||
|
@ -18,6 +18,14 @@ use crate::test_fixtures::TestFixture;
|
||||
pub(crate) fn render_string(
|
||||
fixture: &TestFixture,
|
||||
renderer: &mut dyn Renderer<Id, Output = String>,
|
||||
) -> String {
|
||||
render_string_with_order(fixture, renderer, None)
|
||||
}
|
||||
|
||||
pub(crate) fn render_string_with_order(
|
||||
fixture: &TestFixture,
|
||||
renderer: &mut dyn Renderer<Id, Output = String>,
|
||||
order: Option<&[&str]>,
|
||||
) -> String {
|
||||
let TestFixture {
|
||||
dag,
|
||||
@ -71,8 +79,16 @@ pub(crate) fn render_string(
|
||||
let parents_by_id = id_map.build_get_parents_by_id(&parents_by_name);
|
||||
let messages: HashMap<_, _> = messages.iter().cloned().collect();
|
||||
|
||||
let iter = match order {
|
||||
None => (0..=last_head).rev().collect::<Vec<_>>(),
|
||||
Some(order) => order
|
||||
.iter()
|
||||
.map(|name| id_map.find_id_by_name(name.as_bytes()).unwrap().unwrap().0)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let mut out = String::new();
|
||||
for id in (0..=last_head).rev() {
|
||||
for id in iter {
|
||||
let node = Id(id);
|
||||
if missing.contains(&node) {
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user