mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-02 22:41:47 -06:00
* Build each crate's integration tests as one binary Every tests/*.rs file is its own executable that links the whole crate graph. Move each crate's test files into tests/it/ as modules of one tests/it/main.rs, for apps/pdfcraft, apps/pdfcraft-cli, automation, cos, crypt, engine, render, sign and ui-egui. ui-egui's ui_group binary and the support modules move into tests/it/ too. Crates with a single test file keep it. The test executables go from 150 to 52, and every crate runs the same number of tests as before. ui-egui perf keeps its own binary (own process): its frame-time budgets would charge each measurement for the other tests running beside it. What the move needs: - include_str!/include_bytes! and #[path] paths gain one "../". - ui-egui: one GPU lock in tests/it/main.rs replaces the five per-file ones (content, document_links, editing, fill_sign, view), so one process creates one wgpu device at a time. The drop-line test in ui.rs and the screenshot blocks behind PDFCRAFT_*_SHOT(S) and CRAFT_UI_DOCKING_DIR, which render without holding it, take it too. - pdfcraft winit_wayland_scroll: the vendored winit source it compiles names crate::event, so that shim lives in main.rs. - parity evidence names the new paths. * Name the one-binary test paths in docs and comments - READMEs, docs, ATTRIBUTION and source comments name tests/it/<file>.rs. - The oracle README's example filters with --test it encryption::qpdf_agrees. - pdfcraft's GPU lock comment points at the UI tests' shared lock in crates/ui-egui/tests/it/main.rs.
93 lines
3.2 KiB
Rust
93 lines
3.2 KiB
Rust
//! Crop tool, Set Page Boxes and Duplicate pages in the real shell (egui_kittest).
|
||
|
||
use egui_kittest::Harness;
|
||
use egui_kittest::kittest::Queryable;
|
||
use pdfcraft_ui_egui::{Dialog, PdfCraftApp, QuickTool};
|
||
|
||
const FIXTURE: &[u8] = b"%PDF-1.7
|
||
1 0 obj << /Type /Catalog /Pages 2 0 R >> endobj
|
||
2 0 obj << /Type /Pages /Kids [3 0 R 4 0 R] /Count 2 /MediaBox [0 0 300 400] >> endobj
|
||
3 0 obj << /Type /Page /Parent 2 0 R >> endobj
|
||
4 0 obj << /Type /Page /Parent 2 0 R >> endobj
|
||
trailer << /Root 1 0 R >>
|
||
%%EOF";
|
||
|
||
fn harness() -> Harness<'static, PdfCraftApp> {
|
||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
|
||
let mut app = PdfCraftApp::new();
|
||
app.set_option("language", "en").unwrap();
|
||
app.open_bytes("doc.pdf", None, FIXTURE.to_vec()).unwrap();
|
||
app.set_option("left", "closed").unwrap();
|
||
app.set_option("zoom", "150").unwrap();
|
||
app
|
||
});
|
||
h.run_steps(6);
|
||
h
|
||
}
|
||
|
||
fn size(h: &Harness<'static, PdfCraftApp>, page: usize) -> (f32, f32) {
|
||
let s = h.state();
|
||
let p = &s.session.get(s.views[0].id).unwrap().info.pages[page];
|
||
(p.width, p.height)
|
||
}
|
||
|
||
#[test]
|
||
fn the_crop_tool_crops_to_the_dragged_rectangle_then_returns_to_select() {
|
||
let mut h = harness();
|
||
assert!(h.state_mut().execute("page.crop"));
|
||
assert_eq!(h.state().quick_tool, QuickTool::Crop);
|
||
h.run_steps(2);
|
||
let r = h.state().views[0].page_screen_rect(0).unwrap();
|
||
// The middle half of the page in both directions.
|
||
let (a, b) = (r.min + r.size() * 0.25, r.min + r.size() * 0.75);
|
||
h.hover_at(a);
|
||
h.run_steps(1);
|
||
h.drag_at(a);
|
||
h.run_steps(1);
|
||
for k in 1..=4 {
|
||
h.hover_at(a + (b - a) * (k as f32 / 4.0));
|
||
h.run_steps(1);
|
||
}
|
||
h.drop_at(b);
|
||
h.run_steps(4);
|
||
let (w, hh) = size(&h, 0);
|
||
assert!((w - 150.0).abs() < 2.0 && (hh - 200.0).abs() < 2.0, "{w}×{hh}");
|
||
assert_eq!(size(&h, 1), (300.0, 400.0));
|
||
assert_eq!(h.state().quick_tool, QuickTool::Select);
|
||
assert_eq!(h.state().session.get(h.state().views[0].id).unwrap().can_undo(), Some("Crop page"));
|
||
}
|
||
|
||
#[test]
|
||
fn set_page_boxes_dialog_applies_margins_to_the_chosen_pages() {
|
||
let mut h = harness();
|
||
assert!(h.state_mut().execute("page.boxes"));
|
||
h.run_steps(3);
|
||
assert_eq!(h.state().dialog, Some(Dialog::PageBoxes));
|
||
h.get_by_label("Set Page Boxes");
|
||
// One inch off every side (the units default to inches; margins are stored in points).
|
||
h.state_mut().boxes_draft.margins = [72.0; 4];
|
||
h.run_steps(2);
|
||
h.get_by_label("OK").click();
|
||
h.run_steps(4);
|
||
assert_eq!(h.state().dialog, None);
|
||
assert_eq!(size(&h, 0), (156.0, 256.0));
|
||
assert_eq!(size(&h, 1), (156.0, 256.0), "All pages by default");
|
||
// Set to zero resets the box.
|
||
h.state_mut().execute("page.boxes");
|
||
h.run_steps(3);
|
||
h.get_by_label("Set to zero").click();
|
||
h.run_steps(1);
|
||
h.get_by_label("OK").click();
|
||
h.run_steps(4);
|
||
assert_eq!(size(&h, 0), (300.0, 400.0));
|
||
}
|
||
|
||
#[test]
|
||
fn duplicate_pages_copies_the_current_page() {
|
||
let mut h = harness();
|
||
assert!(h.state_mut().execute("page.duplicate"));
|
||
h.run_steps(3);
|
||
let s = h.state();
|
||
assert_eq!(s.session.get(s.views[0].id).unwrap().info.pages.len(), 3);
|
||
}
|