tests: pin the interface language so the suite passes outside English (#502)
The ui-egui integration tests drive the shell by its English labels, and `i18n::system_lang` returns `Lang::EN` under `cfg!(test)` so they can. That only covers the unit tests: an integration test links the library as it ships, where `cfg!(test)` is off, so `PdfCraftApp::new()` leaves `language` on `auto` and the shell is drawn in the system language. On a Spanish Windows eleven of the test binaries fail; a French, Russian, Chinese, Japanese, Portuguese, Czech or Telugu machine does the same. CI never sees it because its locale is English. `tests/theme.rs` and `tests/create.rs` already pin the option; the other 119 harnesses now do too, and the comment in `system_lang` says why, so a test copied from an existing one keeps the line. Also `i18n::tests::windows_display_language_query_returns_a_locale_tag` treated the return of `windows_ui_language()` as a single tag. It is the preferred-language list, one tag per line, as `first_supported` reads it, so on a Windows with two or more display languages the assertion tripped over the newline. It now checks the shape of every line. Co-authored-by: Fernando Areán <soporte@codebit.es> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e93a6f255f
commit
966bd0ffce
|
|
@ -218,7 +218,9 @@ pub fn lang_from_tag(tag: &str) -> Option<Lang> {
|
|||
|
||||
/// The system language (cached). English when it can't be determined.
|
||||
pub fn system_lang() -> Lang {
|
||||
// Tests drive the UI by its English labels whatever the developer's locale is.
|
||||
// Tests drive the UI by its English labels whatever the developer's locale is. This covers
|
||||
// the unit tests; the integration tests link the library as it ships, where `cfg!(test)` is
|
||||
// off, so each of their harnesses pins the `language` option to `en` instead.
|
||||
if cfg!(test) {
|
||||
return Lang::EN;
|
||||
}
|
||||
|
|
@ -450,10 +452,14 @@ mod tests {
|
|||
#[cfg(target_os = "windows")]
|
||||
#[test]
|
||||
fn windows_display_language_query_returns_a_locale_tag() {
|
||||
let tag = windows_ui_language().expect("Windows should report a display language");
|
||||
let tag = tag.trim();
|
||||
assert!(!tag.is_empty());
|
||||
assert!(tag.split('-').all(|part| !part.is_empty() && part.bytes().all(|b| b.is_ascii_alphanumeric())));
|
||||
// One tag per line, as `first_supported` reads them: a machine with several display
|
||||
// languages reports them all, so each line is checked rather than the list as a whole.
|
||||
let list = windows_ui_language().expect("Windows should report a display language");
|
||||
let tags: Vec<&str> = list.lines().map(str::trim).filter(|t| !t.is_empty()).collect();
|
||||
assert!(!tags.is_empty(), "no display language in {list:?}");
|
||||
for tag in tags {
|
||||
assert!(tag.split('-').all(|part| !part.is_empty() && part.bytes().all(|b| b.is_ascii_alphanumeric())), "not a locale tag: {tag:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ fn checking_fixing_skipping_and_reporting() {
|
|||
let d = dir.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("notes.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
app.export_dir_override = Some(d.to_string_lossy().into_owned());
|
||||
app
|
||||
|
|
@ -110,6 +111,7 @@ trailer << /Root 1 0 R >>
|
|||
fn setting_alternate_text_figure_by_figure() {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("figures.pdf", None, FIGURES.to_vec()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ fn run_and_create_actions() {
|
|||
let d = dir.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.run_inline = true;
|
||||
app.export_dir_override = Some(d.join("out").to_string_lossy().into_owned());
|
||||
app.action_files_override = Some(vec![d.join("r.pdf").to_string_lossy().into_owned()]);
|
||||
|
|
@ -49,6 +50,7 @@ fn run_and_create_actions() {
|
|||
h.get_by_label("1. Add watermark: DRAFT");
|
||||
let saved = h.state().persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
assert_eq!(fresh.custom_actions, h.state().custom_actions);
|
||||
h.get_by_label("Start").click();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ trailer << /Root 1 0 R >>
|
|||
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("pages.pdf", None, PAGES.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "bookmarks").unwrap();
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ fn buttons_reset_navigate_and_print() {
|
|||
let path_str = path.to_string_lossy().into_owned();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("buttons.pdf", Some(path_str), fixture()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
@ -124,6 +125,7 @@ fn name_hidden(h: &Harness<'static, PdfCraftApp>) -> bool {
|
|||
fn hide_actions_hide_and_show_fields() {
|
||||
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("show-hide.pdf", None, show_hide_fixture()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ fn fixture(n: usize) -> Vec<u8> {
|
|||
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(3)).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
@ -70,6 +71,7 @@ fn every_registered_command_is_implemented() {
|
|||
continue;
|
||||
}
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
if spec.id.starts_with("form.") || spec.id == "comment.flatten" {
|
||||
app.open_bytes("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
} else {
|
||||
|
|
@ -139,6 +141,7 @@ fn every_registered_command_is_implemented() {
|
|||
#[test]
|
||||
fn disabled_commands_explain_themselves() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
assert!(!app.execute("file.save"));
|
||||
assert_eq!(app.toast.as_ref().map(|t| t.0.as_str()), Some("Open a document first"));
|
||||
app.open_bytes("doc.pdf", None, fixture(2)).unwrap();
|
||||
|
|
@ -206,6 +209,7 @@ fn the_open_recent_menu_lists_files_and_opens_one() {
|
|||
let path = path.clone();
|
||||
move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture(3)).unwrap();
|
||||
app.recent.push(pdfcraft_ui_egui::RecentFile { name: "recent.pdf".into(), path, pages: 2, size: 0 });
|
||||
app
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ trailer << /Root 1 0 R >>
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("text.pdf", None, TEXT_FIXTURE.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("author", "Tester").unwrap();
|
||||
|
|
@ -539,6 +540,7 @@ fn hovering_a_comment_shows_its_author_and_text() {
|
|||
);
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("hover.pdf", None, pdf.into_bytes()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
// No Comments panel: the comment's text should only appear in the hover popup.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ fn compare_two_versions() {
|
|||
let v2 = s.create_from_text("t", "Delivery within three days. Returns accepted for a week.").unwrap().to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("v1.pdf", None, v1.clone()).unwrap();
|
||||
app.open_bytes("v2.pdf", None, v2.clone()).unwrap();
|
||||
app
|
||||
|
|
@ -49,6 +50,7 @@ fn compare_panel_screenshot() {
|
|||
let v2 = s.create_from_text("t", "Delivery within three days. Returns accepted for a week.").unwrap().to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("v1.pdf", None, v1.clone()).unwrap();
|
||||
app.open_bytes("v2.pdf", None, v2.clone()).unwrap();
|
||||
app
|
||||
|
|
@ -68,6 +70,7 @@ fn pdfa_dialog_verifies_and_converts() {
|
|||
let doc = Session::new().create_from_text("t", "Keep forever").unwrap().to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("keep.pdf", None, doc.clone()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
@ -93,6 +96,7 @@ fn export_to_word_html_and_rtf() {
|
|||
let dir = std::env::temp_dir().join(format!("pdfcraft-office-ui-{}", std::process::id()));
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("e.pdf", None, doc).unwrap();
|
||||
for ext in ["docx", "html", "rtf"] {
|
||||
let out = dir.join(format!("e.{ext}"));
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use pdfcraft_ui_egui::{PdfCraftApp, QuickTool};
|
|||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ fn harness_pages(pages: usize) -> (Harness<'static, PdfCraftApp>, ControlClient)
|
|||
let s = slot.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
*s.lock().unwrap() = Some(app.attach_control(&cc.egui_ctx));
|
||||
app.open_bytes("doc.pdf", None, fixture(pages)).unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ fn image_import_dialog_chooses_dpi_and_cancels() {
|
|||
#[test]
|
||||
fn opening_images_and_text_converts_them_to_new_pdfs() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("photo.png", Some("/tmp/photo.png".into()), png()).unwrap();
|
||||
app.open_bytes("notes.txt", None, b"first line\nsecond line".to_vec()).unwrap();
|
||||
app.create_from_images(vec![("a.png".into(), png()), ("b.png".into(), png())]);
|
||||
|
|
@ -77,6 +78,7 @@ fn reduce_file_size_writes_a_compact_copy() {
|
|||
let out2 = out.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("notes.txt", None, "lorem ipsum ".repeat(500).into_bytes()).unwrap();
|
||||
app.save_override = Some(out2.to_string_lossy().into_owned());
|
||||
app
|
||||
|
|
@ -100,6 +102,7 @@ fn reduce_file_size_writes_a_compact_copy() {
|
|||
fn clipboard_images_and_text_become_new_pdfs() {
|
||||
use pdfcraft_ui_egui::Clip;
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.create_from_clip(Clip::Image { width: 40, height: 20, rgba: [10u8, 20, 30, 255].repeat(40 * 20) }).unwrap();
|
||||
app.create_from_clip(Clip::Text("Pasted\nlines".into())).unwrap();
|
||||
let docs = app.session.docs();
|
||||
|
|
@ -121,6 +124,7 @@ fn the_pdf_optimizer_dialog_saves_an_optimized_copy() {
|
|||
let out2 = out.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("notes.txt", None, "lorem ipsum ".repeat(500).into_bytes()).unwrap();
|
||||
app.save_override = Some(out2.to_string_lossy().into_owned());
|
||||
app
|
||||
|
|
@ -211,6 +215,7 @@ fn multiple_files_open_as_one_document_in_the_page_grid() {
|
|||
#[test]
|
||||
fn multiple_files_that_cannot_be_converted_open_nothing() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.use_files(pdfcraft_ui_egui::FilePurpose::CreateMultiple, vec![("report.docx".into(), b"PK\x03\x04".to_vec())]);
|
||||
assert!(app.views.is_empty());
|
||||
assert!(app.toast.is_some());
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ fn fixture() -> Vec<u8> {
|
|||
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("links.pdf", None, fixture()).unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "none").unwrap();
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ fn fixture(n: usize) -> Vec<u8> {
|
|||
fn harness(pages: usize, setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture(pages)).expect("fixture opens");
|
||||
setup(&mut app);
|
||||
app
|
||||
|
|
@ -395,6 +396,7 @@ fn save_prompt_stays_inside_the_screen_for_a_long_filename() {
|
|||
Vliek, Ed Sutherland, -- 5, 2024 -- McGraw-Hill Education (UK) Ltd -- isbn13 97815268.pdf";
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1365.0, 719.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes(name, None, fixture(1)).expect("fixture opens");
|
||||
app.close_request = Some(CloseRequest::Tab(app.views[0].id));
|
||||
app
|
||||
|
|
@ -429,6 +431,7 @@ fn save_prompt_fits_the_smallest_window_whatever_the_name() {
|
|||
let start: String = name.chars().take(10).collect();
|
||||
let mut h = Harness::builder().with_size(size).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes(&name, None, fixture(1)).expect("fixture opens");
|
||||
app.close_request = Some(CloseRequest::Tab(app.views[0].id));
|
||||
app
|
||||
|
|
@ -818,6 +821,7 @@ fn columns_resize_and_the_layout_is_kept_in_the_settings() {
|
|||
assert!(widths[size_index] > 120.0, "{widths:?}");
|
||||
let saved = h.state().persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
assert_eq!(fresh.combine_columns, h.state().combine_columns);
|
||||
// Malformed settings give the default layout.
|
||||
|
|
@ -1123,6 +1127,7 @@ fn save_pages_writes_what_the_grid_shows() {
|
|||
h.run_steps(4);
|
||||
assert!(!dirty(&h));
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("saved.pdf", None, std::fs::read(&path).unwrap()).unwrap();
|
||||
assert_eq!(texts_of(&app, 0), ["Page 1", "Page 3"]);
|
||||
}
|
||||
|
|
@ -1194,6 +1199,7 @@ fn protected_with(algorithm: pdfcraft_cos::Algorithm, user: &str, owner: &str, p
|
|||
fn password_prompt_opens_and_security_tab_reports_the_details() {
|
||||
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("secret.pdf", None, protected("pw", "owner", -1)).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
@ -1218,6 +1224,7 @@ fn password_prompt_opens_and_security_tab_reports_the_details() {
|
|||
fn restricted_documents_show_a_notice_and_block_page_changes() {
|
||||
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("locked.pdf", None, protected("", "owner", 0b0100)).unwrap(); // opens without a password
|
||||
app.set_option("organize", "on").unwrap();
|
||||
app
|
||||
|
|
@ -1240,6 +1247,7 @@ fn restricted_documents_show_a_notice_and_block_page_changes() {
|
|||
#[test]
|
||||
fn replace_pages_dialog_swaps_page_content() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture(3)).unwrap();
|
||||
app.views[0].select_pages(&[1]);
|
||||
app.start_replace("other.pdf".into(), fixture(5));
|
||||
|
|
@ -1365,6 +1373,7 @@ fn source_font_fixture() -> Vec<u8> {
|
|||
fn open_source_font_fixture() -> Harness<'static, PdfCraftApp> {
|
||||
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("fonts.pdf", None, source_font_fixture()).expect("font fixture opens");
|
||||
app
|
||||
})
|
||||
|
|
@ -1465,6 +1474,7 @@ fn double_drawn() -> Vec<u8> {
|
|||
fn editing_a_double_drawn_line_replaces_every_copy() {
|
||||
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("bold.pdf", None, double_drawn()).expect("opens");
|
||||
app
|
||||
});
|
||||
|
|
@ -1497,6 +1507,7 @@ fn editing_existing_images_on_the_page() {
|
|||
image::RgbImage::from_pixel(80, 40, image::Rgb([200, 40, 40])).write_to(&mut std::io::Cursor::new(&mut png), image::ImageFormat::Png).unwrap();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("picture.png", None, png.clone()).expect("opens");
|
||||
app
|
||||
});
|
||||
|
|
@ -1622,6 +1633,7 @@ fn dragging_a_paragraph_moves_it_and_its_edge_rewraps_it() {
|
|||
fn pages_panel(pages: usize) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 1900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture(pages)).expect("fixture opens");
|
||||
app.set_option("panel", "pages").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ fn export_dialogs_write_images_and_text() {
|
|||
let d = dir.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
app.export_dir_override = Some(d.to_string_lossy().into_owned());
|
||||
app
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ fn harness_bytes(fixture: &[u8]) -> Harness<'static, PdfCraftApp> {
|
|||
let fixture = fixture.to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("form.pdf", None, fixture.clone()).unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
|
|
@ -129,6 +130,7 @@ fn signing_draws_a_signature_once_and_places_it() {
|
|||
// The signature is remembered (persisted with the app's settings).
|
||||
let saved = h.state().persist();
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&saved);
|
||||
assert!(again.signature.is_some());
|
||||
}
|
||||
|
|
@ -160,6 +162,7 @@ fn typed_signatures_and_initials() {
|
|||
// Both are remembered.
|
||||
let saved = h.state().persist();
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&saved);
|
||||
assert_eq!(again.signature, h.state().signature);
|
||||
assert_eq!(again.initials, Some(pdfcraft_ui_egui::fill_sign::SavedSig::Typed("GH".into())));
|
||||
|
|
@ -214,6 +217,7 @@ fn changing_saved_signatures_and_initials_preserves_placed_marks() {
|
|||
click(&mut h, 40.0, 100.0);
|
||||
assert_eq!(items(&h).len(), 3);
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&h.state().persist());
|
||||
assert_eq!(again.signature, Some(SavedSig::Typed("Grace Hopper".into())));
|
||||
assert_eq!(again.initials, Some(SavedSig::Typed("GH".into())));
|
||||
|
|
@ -269,6 +273,7 @@ fn saved_signature_cards_remove_and_add_without_changing_the_document() {
|
|||
assert_eq!(h.state().signature, None);
|
||||
assert_eq!(h.state().initials, Some(SavedSig::Typed("AL".into())));
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&h.state().persist());
|
||||
assert_eq!(again.signature, None, "removal survives restart");
|
||||
h.get_by_label("Add signature").click();
|
||||
|
|
@ -366,6 +371,7 @@ fn image_signatures_and_initials_can_be_imported_placed_and_remembered() {
|
|||
let settings = state.persist();
|
||||
assert!(!settings.contains(&path.to_string_lossy().to_string()), "only the image is saved, never its source path");
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&settings);
|
||||
assert_eq!(again.signature, state.signature);
|
||||
assert_eq!(again.initials, state.initials);
|
||||
|
|
@ -800,6 +806,7 @@ fn image_import_cancel_clear_and_errors_preserve_saved_signatures() {
|
|||
assert!(h.state().signature_draft.image.is_none());
|
||||
// Malformed settings are ignored while legacy typed/drawn values still restore.
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(r#"{"signature_text":"Ada","signature_image":{"Image":"bm90IGFuIGltYWdl"},"initials":{"Image":"%%%"}}"#);
|
||||
assert_eq!(again.signature, Some(SavedSig::Typed("Ada".into())));
|
||||
assert!(again.initials.is_none());
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ impl Drop for TempFolder {
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 1400.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
// List folders on the frame that asks, not on a worker thread.
|
||||
app.run_inline = true;
|
||||
setup(&mut app);
|
||||
|
|
@ -144,8 +145,10 @@ fn pinned_folders_survive_a_restart() {
|
|||
let dir = TempFolder::new("restart");
|
||||
let folder = dir.path();
|
||||
let mut a = PdfCraftApp::new();
|
||||
a.set_option("language", "en").unwrap();
|
||||
assert!(a.pin_folder(&folder));
|
||||
let mut b = PdfCraftApp::new();
|
||||
b.set_option("language", "en").unwrap();
|
||||
b.restore(&a.persist());
|
||||
assert_eq!(b.pinned.folders, [folder]);
|
||||
b.restore("{\"pinned_folders\": [5, \"relative/path\"]}");
|
||||
|
|
@ -197,6 +200,7 @@ fn show_more_reveals_the_older_pdfs() {
|
|||
#[test]
|
||||
fn pinning_is_limited_and_never_duplicates() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
assert!(!app.pin_folder("relative/scans"), "a relative path is refused");
|
||||
let root = if cfg!(windows) { "C:\\" } else { "/" };
|
||||
let folders: Vec<String> = (0..MAX_PINNED).map(|i| Path::new(root).join(format!("pinned-{i}")).to_string_lossy().into_owned()).collect();
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use pdfcraft_ui_egui::PdfCraftApp;
|
|||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
// The whole 300×400 pt page on screen.
|
||||
|
|
@ -148,6 +149,7 @@ fn date_fields_offer_a_calendar() {
|
|||
/// The value of `name` in a saved PDF, read back by opening it in a fresh app.
|
||||
fn saved_value(path: &std::path::Path, name: &str) -> Vec<String> {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("saved.pdf", None, std::fs::read(path).unwrap()).unwrap();
|
||||
app.session.get(app.views[0].id).unwrap().form.iter().find(|f| f.name == name).unwrap().value.clone()
|
||||
}
|
||||
|
|
@ -310,6 +312,7 @@ fn a_rejected_value_keeps_the_typing_and_stops_the_save() {
|
|||
let out = dir.join("saved.pdf");
|
||||
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("order.pdf", None, validated_form()).unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
|
|
@ -356,6 +359,7 @@ fn a_value_refused_on_enter_keeps_save_in_the_same_frame_from_running() {
|
|||
let out = dir.join("saved.pdf");
|
||||
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("order.pdf", None, validated_form()).unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ trailer << /Root 1 0 R >>
|
|||
fn the_identity_name_signs_new_comments_and_is_remembered() {
|
||||
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, PDF.to_vec()).expect("opens");
|
||||
app.set_option("author", "Tester").unwrap();
|
||||
app.set_option("dialog", "preferences").unwrap();
|
||||
|
|
@ -62,6 +63,7 @@ fn the_identity_name_signs_new_comments_and_is_remembered() {
|
|||
assert_eq!(author(&h).as_deref(), Some("Grace Hopper"));
|
||||
// It survives a restart; an empty or missing name keeps the default, and a huge one is cut.
|
||||
let mut restored = PdfCraftApp::new();
|
||||
restored.set_option("language", "en").unwrap();
|
||||
restored.restore(&h.state().persist());
|
||||
assert_eq!(restored.comment_prefs.author, "Grace Hopper");
|
||||
restored.restore(r#"{"author": " "}"#);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ fn form() -> Vec<u8> {
|
|||
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("form.pdf", None, form()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
@ -98,6 +99,7 @@ fn document_scripts_and_preferences() {
|
|||
assert!(!h.state().session.javascript());
|
||||
let saved = h.state().persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
assert!(!fresh.session.javascript(), "the preference is remembered");
|
||||
}
|
||||
|
|
@ -108,6 +110,7 @@ fn merge_data_files_into_a_spreadsheet() {
|
|||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let out = dir.join("report.csv");
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.save_override = Some(out.to_string_lossy().into_owned());
|
||||
app.merge_data_files(vec![("form.pdf".into(), form())]);
|
||||
assert_eq!(std::fs::read_to_string(&out).unwrap(), "greeting\n\n");
|
||||
|
|
@ -121,6 +124,7 @@ fn prepare_a_form_detects_fields_on_a_paper_form() {
|
|||
let paper = pdfcraft_engine::Session::new().create_from_text("t", "Name: ____________________\n\nPhone: ____________________").unwrap().to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("paper.pdf", None, paper.clone()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ fn fixture() -> Vec<u8> {
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("layers.pdf", None, fixture()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
setup(&mut app);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use pdfcraft_ui_egui::{Dialog, PdfCraftApp};
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
setup(&mut app);
|
||||
app
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ trailer << /Root 1 0 R >>
|
|||
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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ fn scan() -> Vec<u8> {
|
|||
fn recognize_text_dialog_adds_searchable_text() {
|
||||
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("scan.pdf", None, scan()).unwrap();
|
||||
app.run_inline = true;
|
||||
app
|
||||
|
|
@ -52,6 +53,7 @@ fn recognize_text_in_multiple_files_writes_searchable_copies() {
|
|||
let _ = std::fs::remove_dir_all(&dir);
|
||||
std::fs::create_dir_all(&dir).unwrap();
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.run_inline = true;
|
||||
app.export_dir_override = Some(dir.to_string_lossy().into_owned());
|
||||
app.use_files(pdfcraft_ui_egui::FilePurpose::Ocr, vec![("one.pdf".into(), scan()), ("two.pdf".into(), scan())]);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ trailer << /Root 1 0 R >>
|
|||
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();
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ fn harness() -> Harness<'static, PdfCraftApp> {
|
|||
// 60 fps steps, so two clicks fall inside egui's double-click window.
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).with_step_dt(1.0 / 60.0).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ fn scrolling_a_500_page_document_stays_within_the_frame_budget() {
|
|||
let t0 = std::time::Instant::now();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("big.pdf", None, bytes).expect("opens");
|
||||
app
|
||||
});
|
||||
|
|
@ -124,6 +125,7 @@ fn panels_with_hundreds_of_items_stay_within_the_frame_budget() {
|
|||
let b = bytes.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("big.pdf", None, b).expect("opens");
|
||||
app.set_option("panel", panel).unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ fn harness(docs: &[usize]) -> Harness<'static, PdfCraftApp> {
|
|||
let docs = docs.to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
for (i, n) in docs.iter().enumerate() {
|
||||
app.open_bytes(&format!("doc{i}.pdf"), None, fixture(*n)).unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use pdfcraft_ui_egui::{PdfCraftApp, QuickTool};
|
|||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use pdfcraft_ui_egui::{Dialog, PdfCraftApp};
|
|||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ trailer << /Root 1 0 R >>
|
|||
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
|
||||
});
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ fn files_in(s: &RecoveryStore) -> usize {
|
|||
/// A session that edits a document, autosaves, and then "crashes" (is dropped).
|
||||
fn crashed_session(s: &RecoveryStore, bytes: Vec<u8>, password: Option<&str>, path: Option<&str>) {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.enable_recovery(s.clone());
|
||||
match password {
|
||||
Some(pw) => {
|
||||
|
|
@ -62,6 +63,7 @@ fn crashed_session(s: &RecoveryStore, bytes: Vec<u8>, password: Option<&str>, pa
|
|||
fn harness(s: RecoveryStore) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.enable_recovery(s);
|
||||
app
|
||||
});
|
||||
|
|
@ -103,6 +105,7 @@ fn discarding_removes_the_autosaves() {
|
|||
fn saving_or_closing_clears_the_entry_and_nothing_is_written_for_clean_documents() {
|
||||
let s = store("save");
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.enable_recovery(s.clone());
|
||||
app.open_bytes("a.pdf", None, fixture(2)).unwrap();
|
||||
app.autosave_now();
|
||||
|
|
@ -130,6 +133,7 @@ fn quitting_cleanly_leaves_nothing_behind() {
|
|||
let s = s.clone();
|
||||
move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.enable_recovery(s);
|
||||
app.open_bytes("q.pdf", None, fixture(2)).unwrap();
|
||||
app
|
||||
|
|
@ -206,6 +210,7 @@ fn control_click_effects_are_visible_when_the_reply_arrives() {
|
|||
let (slot2, s2) = (slot.clone(), s.clone());
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
*slot2.lock().unwrap() = Some(app.attach_control(&cc.egui_ctx));
|
||||
app.enable_recovery(s2);
|
||||
app
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use pdfcraft_ui_egui::{Dialog, PdfCraftApp};
|
|||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ fn dir() -> std::path::PathBuf {
|
|||
fn harness(dir: std::path::PathBuf) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("contract.pdf", None, FIXTURE.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.export_dir_override = Some(dir.to_string_lossy().into_owned());
|
||||
|
|
@ -155,6 +156,7 @@ fn drawing_a_signature_creating_an_id_signing_and_trusting() {
|
|||
// Trusted certificates and the ID list persist.
|
||||
let saved = s.persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
assert_eq!((fresh.digital_ids.len(), fresh.session.trusted_certificates().len()), (1, 1));
|
||||
}
|
||||
|
|
@ -248,6 +250,7 @@ fn clicking_an_empty_signature_field_signs_it() {
|
|||
#[test]
|
||||
fn os_store_identities_are_not_persisted() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
for path in ["windows:Store signer", "keychain:Store signer", "file-id.p12"] {
|
||||
app.digital_ids.push(pdfcraft_ui_egui::DigitalIdEntry {
|
||||
path: path.into(),
|
||||
|
|
@ -262,6 +265,7 @@ fn os_store_identities_are_not_persisted() {
|
|||
assert_eq!(settings["digital_ids"].as_array().unwrap().len(), 1);
|
||||
assert_eq!(settings["digital_ids"][0]["path"], "file-id.p12");
|
||||
let mut restored = PdfCraftApp::new();
|
||||
restored.set_option("language", "en").unwrap();
|
||||
restored.restore(&saved);
|
||||
assert_eq!(restored.digital_ids.len(), 1);
|
||||
assert_eq!(restored.digital_ids[0].path, "file-id.p12");
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use pdfcraft_ui_egui::{PdfCraftApp, QuickTool};
|
|||
fn choosing_and_placing_stamps() {
|
||||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
@ -47,6 +48,7 @@ fn choosing_and_placing_stamps() {
|
|||
fn creating_placing_and_keeping_custom_stamps() {
|
||||
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("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap();
|
||||
app.set_option("zoom", "150").unwrap();
|
||||
app
|
||||
|
|
@ -88,6 +90,7 @@ fn creating_placing_and_keeping_custom_stamps() {
|
|||
// The library is kept with the app's settings.
|
||||
let saved = s.persist();
|
||||
let mut again = PdfCraftApp::new();
|
||||
again.set_option("language", "en").unwrap();
|
||||
again.restore(&saved);
|
||||
assert_eq!(again.custom_stamps.len(), 1);
|
||||
assert_eq!((again.custom_stamps[0].category.as_str(), again.custom_stamps[0].name.as_str()), ("Company", "logo"));
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ trailer << /Root 1 0 R >>
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> (Harness<'static, PdfCraftApp>, Pos2) {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).with_step_dt(1.0 / 60.0).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("lines.pdf", None, two_lines()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("author", "Tester").unwrap();
|
||||
|
|
|
|||
|
|
@ -86,13 +86,16 @@ fn toolbar_and_view_menu_share_three_state_preferences() {
|
|||
fn saved_preferences_restore_with_legacy_light_dark_settings() {
|
||||
for (value, preference) in [("light", ThemePreference::Light), ("dark", ThemePreference::Dark), ("system", ThemePreference::System)] {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.set_option("theme", value).unwrap();
|
||||
let saved = app.persist();
|
||||
let mut restored = PdfCraftApp::new();
|
||||
restored.set_option("language", "en").unwrap();
|
||||
restored.restore(&saved);
|
||||
assert_eq!(restored.theme_preference, preference);
|
||||
}
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.restore(r#"{"theme":"Dark"}"#);
|
||||
assert_eq!(app.theme_preference, ThemePreference::Dark);
|
||||
assert_eq!(app.theme, ThemeKind::Dark);
|
||||
|
|
@ -107,6 +110,7 @@ fn saved_preferences_restore_with_legacy_light_dark_settings() {
|
|||
#[test]
|
||||
fn commands_and_options_apply_before_the_first_frame() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.run_command("view.theme.dark");
|
||||
assert_eq!(app.theme_preference, ThemePreference::Dark);
|
||||
assert_eq!(app.theme, ThemeKind::Dark);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ trailer << /Root 1 0 R >>
|
|||
fn harness(setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
setup(&mut app);
|
||||
app
|
||||
});
|
||||
|
|
@ -75,6 +76,7 @@ fn a_tab_with_an_arabic_file_name_keeps_its_logical_accessible_name() {
|
|||
#[test]
|
||||
fn garbage_input_is_rejected_without_panicking() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
assert!(app.open_bytes("junk.pdf", None, b"this is not a pdf".to_vec()).is_err());
|
||||
assert!(app.open_bytes("empty.pdf", None, Vec::new()).is_err());
|
||||
let mut truncated = FIXTURE.to_vec();
|
||||
|
|
@ -173,9 +175,11 @@ fn drag_selects_text_and_copy_returns_it() {
|
|||
#[test]
|
||||
fn persistence_round_trips_and_tolerates_garbage() {
|
||||
let mut a = PdfCraftApp::new();
|
||||
a.set_option("language", "en").unwrap();
|
||||
a.set_option("theme", "dark").unwrap();
|
||||
let json = a.persist();
|
||||
let mut b = PdfCraftApp::new();
|
||||
b.set_option("language", "en").unwrap();
|
||||
b.restore(&json);
|
||||
assert_eq!(b.theme, pdfcraft_ui_egui::theme::ThemeKind::Dark);
|
||||
b.restore("{not json");
|
||||
|
|
@ -246,7 +250,11 @@ impl egui::DroppedFile for Dropped {
|
|||
|
||||
#[test]
|
||||
fn dropping_a_pdf_on_the_window_opens_it() {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| PdfCraftApp::new());
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app
|
||||
});
|
||||
h.run_steps(3);
|
||||
assert!(h.state().views.is_empty());
|
||||
let file: egui::DroppedFileHandle = std::sync::Arc::new(Dropped { path: "dropped.pdf".into(), bytes: FIXTURE.to_vec() });
|
||||
|
|
@ -258,7 +266,11 @@ fn dropping_a_pdf_on_the_window_opens_it() {
|
|||
|
||||
#[test]
|
||||
fn pdfs_dropped_on_the_combine_tab_join_its_list() {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| PdfCraftApp::new());
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app
|
||||
});
|
||||
h.run_steps(3);
|
||||
h.state_mut().execute("page.combine");
|
||||
h.run_steps(2);
|
||||
|
|
@ -284,7 +296,11 @@ fn a_folder_dropped_on_the_combine_tab_adds_its_pdfs() {
|
|||
std::fs::create_dir_all(dir.join("inner")).unwrap();
|
||||
std::fs::write(dir.join("one.pdf"), FIXTURE).unwrap();
|
||||
std::fs::write(dir.join("inner").join("two.pdf"), FIXTURE).unwrap();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| PdfCraftApp::new());
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app
|
||||
});
|
||||
h.run_steps(3);
|
||||
h.state_mut().execute("page.combine");
|
||||
h.run_steps(2);
|
||||
|
|
@ -321,9 +337,11 @@ fn default_workspace_mode_persists_and_tolerates_invalid_settings() {
|
|||
use pdfcraft_ui_egui::Mode;
|
||||
for mode in [Mode::AllTools, Mode::Read, Mode::Edit, Mode::Convert, Mode::Sign] {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.default_mode = mode;
|
||||
app.set_option("mode", "sign").unwrap();
|
||||
let mut restored = PdfCraftApp::new();
|
||||
restored.set_option("language", "en").unwrap();
|
||||
restored.restore(&app.persist());
|
||||
assert_eq!(restored.default_mode, mode);
|
||||
restored.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
|
|
@ -331,6 +349,7 @@ fn default_workspace_mode_persists_and_tolerates_invalid_settings() {
|
|||
}
|
||||
for json in ["{}", "{not json", r#"{"default_mode": null}"#, r#"{"default_mode": 5}"#, r#"{"default_mode": "unknown"}"#] {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.restore(json);
|
||||
assert_eq!(app.default_mode, Mode::AllTools);
|
||||
app.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
|
|
@ -342,6 +361,7 @@ fn default_workspace_mode_persists_and_tolerates_invalid_settings() {
|
|||
fn newly_opened_pdfs_use_the_default_workspace() {
|
||||
use pdfcraft_ui_egui::{LeftPanel, Mode};
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.restore(r#"{"default_mode": "edit"}"#);
|
||||
app.open_bytes("first.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
assert_eq!(app.mode, Mode::Edit);
|
||||
|
|
@ -365,6 +385,7 @@ fn explicit_mode_overrides_default_before_and_after_open() {
|
|||
for before in [false, true] {
|
||||
for (value, mode) in [("all", Mode::AllTools), ("read", Mode::Read), ("edit", Mode::Edit), ("convert", Mode::Convert), ("sign", Mode::Sign)] {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.default_mode = Mode::Read;
|
||||
if before {
|
||||
app.set_option("mode", value).unwrap();
|
||||
|
|
@ -403,6 +424,7 @@ fn preferences_selects_default_workspace_for_next_open() {
|
|||
fn explicit_mode_preserves_independent_tool_and_panel_options() {
|
||||
use pdfcraft_ui_egui::LeftPanel;
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.set_option("tool", "export").unwrap();
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("mode", "edit").unwrap();
|
||||
|
|
@ -418,6 +440,7 @@ fn opening_a_pdf_keeps_a_closed_left_panel_and_the_chosen_tool() {
|
|||
use pdfcraft_ui_egui::{LeftPanel, Mode};
|
||||
// `--left closed` without `--mode`, default workspace Edit: the panel stays closed.
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.default_mode = Mode::Edit;
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
|
|
@ -425,6 +448,7 @@ fn opening_a_pdf_keeps_a_closed_left_panel_and_the_chosen_tool() {
|
|||
assert!(!app.left_open);
|
||||
// Default All Tools: opening another PDF leaves the tool panel the user picked.
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.set_option("tool", "export").unwrap();
|
||||
app.open_bytes("first.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
app.open_bytes("second.pdf", None, FIXTURE.to_vec()).unwrap();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ fn source(answer: Result<&str, &str>) -> UpdateSource {
|
|||
fn harness(answer: Result<&str, &str>) -> Harness<'static, PdfCraftApp> {
|
||||
Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.update_source = Some(source(answer));
|
||||
app
|
||||
})
|
||||
|
|
@ -78,6 +79,7 @@ fn nothing_is_asked_until_the_user_checks() {
|
|||
let counted = calls.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
// Settings from a build that had the startup option are ignored.
|
||||
app.restore(r#"{"check_updates_at_start": true}"#);
|
||||
let counted = counted.clone();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ fn harness(options: &'static [(&'static str, &'static str)]) -> Harness<'static,
|
|||
fn harness_stepping(step_dt: f32, options: &'static [(&'static str, &'static str)]) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).with_step_dt(step_dt).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("pages.pdf", None, PAGES.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "none").unwrap();
|
||||
|
|
@ -63,6 +64,7 @@ trailer << /Root 1 0 R >>
|
|||
fn mixed_harness(options: &'static [(&'static str, &'static str)]) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("mixed.pdf", None, MIXED.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "none").unwrap();
|
||||
|
|
@ -230,6 +232,7 @@ fn layout_option_rejects_typos() {
|
|||
#[test]
|
||||
fn view_options_without_a_document() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
assert!(app.set_option("default-layout", "single").is_ok(), "the default needs no document");
|
||||
assert_eq!(app.view_defaults.layout, pdfcraft_ui_egui::canvas::PageLayout::Single);
|
||||
assert!(app.set_option("cover", "on").is_err(), "cover needs an open document");
|
||||
|
|
@ -251,6 +254,7 @@ fn default_page_display_is_used_for_new_documents() {
|
|||
// Persisted preferences survive a restart.
|
||||
let saved = h.state().persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
assert_eq!(fresh.view_defaults.layout, PageLayout::Single);
|
||||
// Garbage keeps the previous default; casing is forgiven; legacy files lack the key.
|
||||
|
|
@ -259,6 +263,7 @@ fn default_page_display_is_used_for_new_documents() {
|
|||
fresh.restore(r#"{"default_layout":"TWO-UP"}"#);
|
||||
assert_eq!(fresh.view_defaults.layout, PageLayout::TwoUp);
|
||||
let mut legacy = PdfCraftApp::new();
|
||||
legacy.set_option("language", "en").unwrap();
|
||||
legacy.restore("{}");
|
||||
assert_eq!(legacy.view_defaults.layout, PageLayout::Continuous);
|
||||
}
|
||||
|
|
@ -287,6 +292,7 @@ fn default_zoom_is_used_for_new_documents() {
|
|||
// Saved settings keep it, and garbage leaves it alone.
|
||||
let saved = h.state().persist();
|
||||
let mut fresh = PdfCraftApp::new();
|
||||
fresh.set_option("language", "en").unwrap();
|
||||
fresh.restore(&saved);
|
||||
fresh.restore(r#"{"default_zoom":"bogus"}"#);
|
||||
fresh.open_bytes("again.pdf", None, PAGES.to_vec()).expect("opens");
|
||||
|
|
@ -463,6 +469,7 @@ trailer << /Root 1 0 R >>
|
|||
fn form_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("form.pdf", None, FORM.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app
|
||||
|
|
@ -531,6 +538,7 @@ fn required_radio_buttons_get_a_round_red_border() {
|
|||
let _gpu = gpu();
|
||||
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("radios.pdf", None, RADIOS.to_vec()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "none").unwrap();
|
||||
|
|
@ -575,6 +583,7 @@ fn field_highlighting_is_remembered() {
|
|||
assert!(h.state().views[1].highlight_fields, "the next document opens highlighted");
|
||||
let saved = h.state().persist();
|
||||
let mut next = PdfCraftApp::new();
|
||||
next.set_option("language", "en").unwrap();
|
||||
next.restore(&saved);
|
||||
next.open_bytes("form.pdf", None, FORM.to_vec()).expect("opens");
|
||||
assert!(next.views[0].highlight_fields, "and so does the next session");
|
||||
|
|
@ -666,6 +675,7 @@ trailer << /Root 1 0 R >>
|
|||
let bytes = pdf.clone();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1000.0, 800.0)).with_pixels_per_point(ppp).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("lines.pdf", None, bytes.clone()).expect("opens");
|
||||
app.set_option("left", "closed").unwrap();
|
||||
app.set_option("panel", "none").unwrap();
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ fn fixture(n: usize) -> Vec<u8> {
|
|||
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("a.pdf", None, fixture(5)).unwrap();
|
||||
app.open_bytes("b.pdf", None, fixture(2)).unwrap();
|
||||
app
|
||||
|
|
@ -213,6 +214,7 @@ trailer << /Root 1 0 R >>
|
|||
.to_vec();
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("damaged.pdf", None, damaged.clone()).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
@ -250,6 +252,7 @@ fn initial_view_is_edited_and_honoured_on_open() {
|
|||
// Opening the saved file follows it.
|
||||
let bytes = s.session.save_bytes(id).unwrap();
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("again.pdf", None, bytes.to_vec()).unwrap();
|
||||
let view = &app.views[0];
|
||||
assert_eq!((view.current, view.cover, app.right), (1, true, Some(pdfcraft_ui_egui::RightPanel::Bookmarks)));
|
||||
|
|
@ -559,6 +562,7 @@ fn page_down_steps_every_spread_when_several_fit_on_screen() {
|
|||
let bytes = sized_fixture(&sizes);
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("book.pdf", None, bytes).unwrap();
|
||||
app
|
||||
});
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const XFA_PACKET: &str = "<< /Length 52 >>\nstream\n<xdp:xdp xmlns:xdp=\"http://
|
|||
fn open(bytes: Vec<u8>) -> Harness<'static, PdfCraftApp> {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 800.0)).build_eframe(move |_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("form.pdf", None, bytes).expect("opens");
|
||||
app
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue