#![allow(clippy::expect_used)]
use pdfrum::{Document, FormSession, Modifiers, Point};
fn document() -> Document {
Document::open("tests/fixtures/combobox_form.pdf").expect("the combobox fixture must open")
}
const BEGIN_X: f64 = 102.0;
const END_X: f64 = 183.0;
const EDITABLE_Y: f64 = 360.0;
const NON_EDITABLE_Y: f64 = 410.0;
const READ_ONLY_Y: f64 = 510.0;
const OFF_FIELD: Point = Point::new(1.0, 1.0);
fn click(session: &mut FormSession<'_>, at: Point) {
session.mouse_move(0, at, Modifiers::NONE);
session.mouse_down(0, at, Modifiers::NONE);
session.mouse_up(0, at, Modifiers::NONE);
}
fn type_text(session: &mut FormSession<'_>, text: &str) {
for ch in text.chars() {
session.character(ch, Modifiers::NONE);
}
}
#[test]
fn focus_moves_between_the_two_combo_boxes() {
let doc = document();
let mut session = FormSession::new(&doc);
assert!(session.focused_text().is_none());
click(&mut session, Point::new(BEGIN_X, NON_EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("Banana"));
click(&mut session, Point::new(BEGIN_X, EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some(""));
click(&mut session, Point::new(END_X, NON_EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("Banana"));
click(&mut session, Point::new(BEGIN_X, NON_EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("Banana"));
session.blur();
assert!(session.focused_text().is_none());
}
#[test]
fn typing_into_an_editable_combo_inserts_and_persists() {
let doc = document();
let mut session = FormSession::new(&doc);
click(&mut session, Point::new(BEGIN_X, EDITABLE_Y));
type_text(&mut session, "ABC");
assert_eq!(session.focused_text().as_deref(), Some("ABC"));
click(&mut session, OFF_FIELD);
assert!(session.focused_text().is_none());
click(&mut session, Point::new(END_X, EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("ABC"));
type_text(&mut session, "ABC");
assert_eq!(session.focused_text().as_deref(), Some("ABCABC"));
}
#[test]
fn typing_into_a_gated_combo_selects_rather_than_inserts() {
let doc = document();
let mut session = FormSession::new(&doc);
click(&mut session, Point::new(BEGIN_X, NON_EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("Banana"));
type_text(&mut session, "A");
assert_eq!(
session.focused_text().as_deref(),
Some("Apple"),
"a character jumps to an option rather than being inserted"
);
type_text(&mut session, "C");
assert_eq!(session.focused_text().as_deref(), Some("Cherry"));
}
#[test]
fn a_read_only_combo_never_takes_focus() {
let doc = document();
let mut session = FormSession::new(&doc);
click(&mut session, Point::new(BEGIN_X, READ_ONLY_Y));
assert!(
session.focused_annot().is_none(),
"a read-only widget is not clickable"
);
}
#[test]
fn a_click_off_every_field_drops_focus() {
let doc = document();
let mut session = FormSession::new(&doc);
click(&mut session, Point::new(BEGIN_X, NON_EDITABLE_Y));
assert!(session.focused_annot().is_some());
click(&mut session, OFF_FIELD);
assert!(session.focused_annot().is_none());
assert!(session.focused_text().is_none());
}
#[test]
fn the_two_combo_boxes_keep_separate_state() {
let doc = document();
let mut session = FormSession::new(&doc);
click(&mut session, Point::new(BEGIN_X, EDITABLE_Y));
type_text(&mut session, "typed");
click(&mut session, Point::new(BEGIN_X, NON_EDITABLE_Y));
assert_eq!(session.focused_text().as_deref(), Some("Banana"));
click(&mut session, Point::new(BEGIN_X, EDITABLE_Y));
assert_eq!(
session.focused_text().as_deref(),
Some("typed"),
"the editable box kept what was typed into it"
);
}