use crate::files_view::{PREVIEW_CAP, Preview};
use crate::workdiff::{Attempt, Change, Churn, FileChurn, WorkFile, render};
fn diffed() -> Vec<Attempt> {
vec![Attempt {
project: "proj".to_owned(),
ball_id: "bl-1".to_owned(),
handle: None,
delivered: None,
change: Change::Diff {
target: "main".to_owned(),
source: "work/bl-1".to_owned(),
target_oid: "aaaa1111bbbb".to_owned(),
source_oid: "cccc2222dddd".to_owned(),
files: vec![
FileChurn {
path: "src/a.rs".to_owned(),
churn: Churn::Text {
added: 12,
removed: 3,
},
},
FileChurn {
path: "logo.png".to_owned(),
churn: Churn::Binary,
},
],
truncated: true,
},
}]
}
fn painted(attempts: &[Attempt], patch: Option<&Preview>) -> String {
let mut sel = None;
crate::paint_probe::paint(|ui| {
render(ui, attempts, patch, &mut sel);
})
}
#[test]
fn the_tab_names_the_range_and_every_changed_file() {
let text = painted(&diffed(), None);
assert!(text.contains("bl-1"), "{text}");
assert!(text.contains("proj"), "{text}");
assert!(text.contains("main..work/bl-1"), "{text}");
assert!(text.contains("aaaa111"), "the target commit, short: {text}");
assert!(text.contains("cccc222"), "the source commit, short: {text}");
assert!(text.contains("+12 -3 src/a.rs"), "{text}");
assert!(text.contains("binary logo.png"), "{text}");
assert!(text.contains("more files changed"), "{text}");
assert!(text.contains("pick a file"), "{text}");
}
#[test]
fn clicking_a_file_picks_it_for_its_patch() {
let attempts = diffed();
let ctx = egui::Context::default();
let mut sel: Option<WorkFile> = None;
let frame = |input: egui::RawInput, sel: &mut Option<WorkFile>| {
let _ = ctx.run(input, |ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
render(ui, &attempts, None, sel);
});
});
};
let screen = crate::paint_probe::screen;
frame(screen(), &mut sel);
let painted = crate::paint_probe::painted_settled(1024.0, 4096.0, |ui| {
render(ui, &attempts, None, &mut None);
});
let pos = painted
.iter()
.find(|(text, _)| text == "+12 -3 src/a.rs")
.map(|(_, rect)| rect.center())
.expect("the row is on screen");
let button = |pressed| egui::Event::PointerButton {
pos,
button: egui::PointerButton::Primary,
pressed,
modifiers: egui::Modifiers::default(),
};
frame(
egui::RawInput {
events: vec![egui::Event::PointerMoved(pos), button(true), button(false)],
..screen()
},
&mut sel,
);
assert_eq!(
sel,
Some(WorkFile {
ball: "bl-1".to_owned(),
handle: None,
path: "src/a.rs".to_owned(),
})
);
}
#[test]
fn the_picked_files_patch_paints_bounded() {
let attempts = diffed();
let text = painted(&attempts, Some(&Preview::Text("+added line".to_owned())));
assert!(text.contains("+added line"), "{text}");
let empty = painted(&attempts, Some(&Preview::Text(String::new())));
assert!(empty.contains("came back empty"), "{empty}");
let binary = painted(&attempts, Some(&Preview::Binary { size: 41 }));
assert!(binary.contains("41 bytes"), "{binary}");
let long = painted(
&attempts,
Some(&Preview::Truncated {
text: "@@".to_owned(),
size: 99_999,
}),
);
assert!(
long.contains(&format!("{} KiB of 99999 bytes", PREVIEW_CAP / 1024)),
"{long}"
);
}
#[test]
fn a_candidate_wears_its_handle_and_its_delivered_mark() {
let mut candidate = diffed().remove(0);
candidate.handle = Some("at-0badcafe".to_owned());
candidate.delivered = Some("eeee3333ffff".to_owned());
let text = painted(std::slice::from_ref(&candidate), None);
assert!(text.contains("at-0badcafe"), "{text}");
assert!(
text.contains("delivered eeee333"),
"the mark, short: {text}"
);
let painted = crate::paint_probe::painted_settled(1024.0, 4096.0, |ui| {
render(ui, std::slice::from_ref(&candidate), None, &mut None);
});
let pos = painted
.iter()
.find(|(text, _)| text == "+12 -3 src/a.rs")
.map(|(_, rect)| rect.center())
.expect("the row is on screen");
let ctx = egui::Context::default();
let mut sel: Option<WorkFile> = None;
let button = |pressed| egui::Event::PointerButton {
pos,
button: egui::PointerButton::Primary,
pressed,
modifiers: egui::Modifiers::default(),
};
for input in [
crate::paint_probe::screen(),
egui::RawInput {
events: vec![egui::Event::PointerMoved(pos), button(true), button(false)],
..crate::paint_probe::screen()
},
] {
let _ = ctx.run(input, |ctx| {
egui::CentralPanel::default().show(ctx, |ui| {
render(ui, std::slice::from_ref(&candidate), None, &mut sel);
});
});
}
assert_eq!(
sel,
Some(WorkFile {
ball: "bl-1".to_owned(),
handle: Some("at-0badcafe".to_owned()),
path: "src/a.rs".to_owned(),
})
);
}
#[test]
fn every_decline_is_said_in_words() {
assert!(painted(&[], None).contains("holds no ball"));
let attempt = |change| {
vec![Attempt {
project: "proj".to_owned(),
ball_id: "bl-1".to_owned(),
handle: None,
delivered: None,
change,
}]
};
let unreadable = painted(&attempt(Change::Unreadable), None);
assert!(unreadable.contains("cannot be read here"), "{unreadable}");
let absent = painted(
&attempt(Change::Absent {
target: "main".to_owned(),
source: "work/bl-1".to_owned(),
missing: vec!["work/bl-1".to_owned()],
}),
None,
);
assert!(absent.contains("comparing main..work/bl-1"), "{absent}");
assert!(absent.contains("no work/bl-1"), "{absent}");
let quiet = painted(
&attempt(Change::Diff {
target: "main".to_owned(),
source: "work/bl-1".to_owned(),
target_oid: "aaaa1111".to_owned(),
source_oid: "aaaa1111".to_owned(),
files: Vec::new(),
truncated: false,
}),
None,
);
assert!(quiet.contains("nothing changed yet"), "{quiet}");
}