use oxidize_pdf::document::Document;
use oxidize_pdf::forms::{
CheckBox, ComboBox, FieldFlags, FieldOptions, FormManager, ListBox, PushButton, RadioButton,
TextField, Widget,
};
use oxidize_pdf::geometry::{Point, Rectangle};
use oxidize_pdf::parser::PdfReader;
use oxidize_pdf::Page;
use std::fs;
use std::io::Cursor;
use tempfile::TempDir;
#[test]
fn test_form_document_catalog_integration() {
let mut doc = Document::new();
doc.set_title("Form Integration Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let text_field = TextField::new("username").with_value("test_user");
let widget = Widget::new(Rectangle::new(
Point::new(100.0, 700.0),
Point::new(300.0, 720.0),
));
let field_ref = form_manager
.add_text_field(text_field, widget, None)
.unwrap();
assert_eq!(field_ref.number(), 1);
let acro_form = form_manager.get_acro_form();
assert_eq!(acro_form.fields.len(), 1);
assert!(acro_form.need_appearances);
assert!(acro_form.da.is_some());
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("form_test.pdf");
let save_result = doc.save(&pdf_path);
match save_result {
Ok(_) => {
assert!(pdf_path.exists());
let file_size = fs::metadata(&pdf_path).unwrap().len();
println!("PDF file created with {file_size} bytes");
if file_size > 1000 {
println!("PDF appears to have substantial content - forms may be integrated");
} else {
println!("PDF is small - forms likely not integrated (expected gap)");
}
}
Err(e) => {
println!("Form document save failed (expected for now): {e}");
}
}
}
#[test]
fn test_multiple_field_types_document_integration() {
let mut doc = Document::new();
doc.set_title("Multi-Field Form Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let text_field = TextField::new("full_name").with_max_length(100);
let text_widget = Widget::new(Rectangle::new(
Point::new(50.0, 650.0),
Point::new(400.0, 670.0),
));
form_manager
.add_text_field(text_field, text_widget, None)
.unwrap();
let checkbox = CheckBox::new("agree_terms").checked();
let check_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(70.0, 620.0),
));
form_manager
.add_checkbox(checkbox, check_widget, None)
.unwrap();
let button = PushButton::new("submit").with_caption("Submit Form");
let button_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(150.0, 580.0),
));
form_manager
.add_push_button(button, button_widget, None)
.unwrap();
let radio = RadioButton::new("payment_method")
.add_option("CC", "Credit Card")
.add_option("PP", "PayPal")
.with_selected(0);
let radio_widgets = vec![
Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(70.0, 520.0),
)),
Widget::new(Rectangle::new(
Point::new(200.0, 500.0),
Point::new(220.0, 520.0),
)),
];
form_manager
.add_radio_buttons(radio, radio_widgets, None)
.unwrap();
let listbox = ListBox::new("countries")
.add_option("US", "United States")
.add_option("CA", "Canada")
.add_option("MX", "Mexico")
.with_selected(vec![0]);
let list_widget = Widget::new(Rectangle::new(
Point::new(50.0, 400.0),
Point::new(200.0, 480.0),
));
form_manager
.add_list_box(listbox, list_widget, None)
.unwrap();
let combo = ComboBox::new("state")
.add_option("CA", "California")
.add_option("NY", "New York")
.editable()
.with_value("CA");
let combo_widget = Widget::new(Rectangle::new(
Point::new(250.0, 450.0),
Point::new(400.0, 470.0),
));
form_manager
.add_combo_box(combo, combo_widget, None)
.unwrap();
assert_eq!(form_manager.field_count(), 6);
let acro_form = form_manager.get_acro_form();
assert_eq!(acro_form.fields.len(), 6);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("multi_field_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
assert!(pdf_path.exists());
let file_size = fs::metadata(&pdf_path).unwrap().len();
assert!(file_size > 500, "Complex form PDF should be substantial");
println!("Multi-field form document created successfully: {file_size} bytes");
}
Err(e) => {
println!("Multi-field form save failed (documenting gap): {e}");
}
}
}
#[test]
fn test_form_field_options_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let options = FieldOptions {
flags: FieldFlags {
read_only: false,
required: true,
no_export: false,
},
default_appearance: Some("/Helvetica 12 Tf 0 g".to_string()),
quadding: Some(1), };
let field = TextField::new("styled_field")
.with_value("Styled Text")
.with_max_length(50);
let appearance = Widget::new(Rectangle::new(
Point::new(100.0, 400.0),
Point::new(400.0, 430.0),
));
form_manager
.add_text_field(field, appearance, Some(options))
.unwrap();
form_manager.set_default_appearance("/Times-Roman 14 Tf 0.5 g");
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("styled_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Styled form document created successfully");
if let Ok(pdf_data) = fs::read(&pdf_path) {
let cursor = Cursor::new(pdf_data);
match PdfReader::new(cursor) {
Ok(_pdf_reader) => {
println!("Form document successfully parsed back");
}
Err(e) => {
println!("Form document parsing failed: {e}");
}
}
}
}
Err(e) => {
println!("Styled form save failed: {e}");
}
}
}
#[test]
fn test_form_document_roundtrip() {
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("roundtrip_form.pdf");
{
let mut doc = Document::new();
doc.set_title("Roundtrip Test Form");
let page = Page::a4();
let mut form_manager = FormManager::new();
let field = TextField::new("roundtrip_field").with_value("original_value");
let widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(300.0, 520.0),
));
form_manager.add_text_field(field, widget, None).unwrap();
doc.add_page(page);
match doc.save(&pdf_path) {
Ok(_) => println!("Roundtrip form saved successfully"),
Err(e) => {
println!("Save failed in roundtrip test: {e}");
return; }
}
}
if pdf_path.exists() {
match fs::read(&pdf_path) {
Ok(pdf_data) => {
let cursor = Cursor::new(pdf_data);
match PdfReader::new(cursor) {
Ok(_pdf_doc) => {
println!("Roundtrip document loaded successfully");
println!(
"Document parsing successful - form integration needs verification"
);
}
Err(e) => {
println!("Roundtrip document parsing failed: {e}");
panic!("Critical: Document with forms cannot be parsed back");
}
}
}
Err(e) => {
println!("Failed to read roundtrip file: {e}");
}
}
} else {
println!("Roundtrip file was not created - save failed silently");
}
}
#[test]
fn test_large_form_document_integration() {
let mut doc = Document::new();
doc.set_title("Large Form Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let fields_count = 50;
for i in 0..fields_count {
let field_name = format!("field_{i}");
let field_value = format!("value_{i}");
let field = TextField::new(field_name)
.with_value(field_value)
.with_max_length(100);
let y_pos = 700.0 - (i as f64 * 15.0);
let widget = Widget::new(Rectangle::new(
Point::new(50.0, y_pos),
Point::new(200.0, y_pos + 12.0),
));
form_manager.add_text_field(field, widget, None).unwrap();
}
assert_eq!(form_manager.field_count(), fields_count);
let acro_form = form_manager.get_acro_form();
assert_eq!(acro_form.fields.len(), fields_count);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("large_form.pdf");
let start_time = std::time::Instant::now();
match doc.save(&pdf_path) {
Ok(_) => {
let save_time = start_time.elapsed();
println!("Large form ({fields_count} fields) saved in {save_time:?}");
assert!(
save_time.as_secs() < 5,
"Large form save took too long: {save_time:?}"
);
let file_size = fs::metadata(&pdf_path).unwrap().len();
println!("Large form file size: {file_size} bytes");
assert!(
file_size > 800,
"Large form should have substantial content"
);
assert!(
file_size < 1_000_000,
"Large form shouldn't be excessive: {file_size} bytes"
);
}
Err(e) => {
println!("Large form save failed: {e}");
}
}
}
#[test]
fn test_form_appearance_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let red_field = TextField::new("red_field").with_value("Red Border");
let red_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(250.0, 620.0),
));
form_manager
.add_text_field(red_field, red_widget, None)
.unwrap();
let blue_checkbox = CheckBox::new("blue_check").checked();
let blue_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
));
form_manager
.add_checkbox(blue_checkbox, blue_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("appearance_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Appearance form created successfully");
let file_size = fs::metadata(&pdf_path).unwrap().len();
assert!(file_size > 500, "Appearance form should have content");
}
Err(e) => {
println!("Appearance form save failed: {e}");
}
}
}
#[test]
fn test_form_validation_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let required_options = FieldOptions {
flags: FieldFlags {
read_only: false,
required: true,
no_export: false,
},
default_appearance: Some("/Helvetica 10 Tf 0 g".to_string()),
quadding: Some(0),
};
let required_field = TextField::new("required_field")
.with_value("")
.with_max_length(50);
let required_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(300.0, 520.0),
));
form_manager
.add_text_field(required_field, required_widget, Some(required_options))
.unwrap();
let readonly_options = FieldOptions {
flags: FieldFlags {
read_only: true,
required: false,
no_export: false,
},
default_appearance: Some("/Helvetica 10 Tf 0.5 g".to_string()),
quadding: Some(0),
};
let readonly_field = TextField::new("readonly_field")
.with_value("Cannot edit this")
.with_max_length(100);
let readonly_widget = Widget::new(Rectangle::new(
Point::new(50.0, 450.0),
Point::new(300.0, 470.0),
));
form_manager
.add_text_field(readonly_field, readonly_widget, Some(readonly_options))
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("validation_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Validation form created successfully");
}
Err(e) => {
println!("Validation form save failed: {e}");
}
}
}
#[test]
fn test_form_calculation_order_document() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let price_field = TextField::new("price").with_value("100.00");
let price_widget = Widget::new(Rectangle::new(
Point::new(50.0, 400.0),
Point::new(150.0, 420.0),
));
form_manager
.add_text_field(price_field, price_widget, None)
.unwrap();
let quantity_field = TextField::new("quantity").with_value("2");
let quantity_widget = Widget::new(Rectangle::new(
Point::new(50.0, 370.0),
Point::new(150.0, 390.0),
));
form_manager
.add_text_field(quantity_field, quantity_widget, None)
.unwrap();
let total_field = TextField::new("total").with_value("200.00");
let total_widget = Widget::new(Rectangle::new(
Point::new(50.0, 340.0),
Point::new(150.0, 360.0),
));
form_manager
.add_text_field(total_field, total_widget, None)
.unwrap();
assert_eq!(form_manager.field_count(), 3);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("calculation_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Calculation form created successfully");
}
Err(e) => {
println!("Calculation form save failed: {e}");
}
}
}
#[test]
fn test_form_javascript_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let js_button = PushButton::new("calculate_button").with_caption("Calculate Total");
let js_widget = Widget::new(Rectangle::new(
Point::new(50.0, 300.0),
Point::new(180.0, 330.0),
));
form_manager
.add_push_button(js_button, js_widget, None)
.unwrap();
let result_field = TextField::new("result_field").with_value("0.00");
let result_widget = Widget::new(Rectangle::new(
Point::new(50.0, 250.0),
Point::new(200.0, 270.0),
));
form_manager
.add_text_field(result_field, result_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("javascript_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("JavaScript form placeholder created successfully");
}
Err(e) => {
println!("JavaScript form save failed: {e}");
}
}
}
#[test]
fn test_multi_page_form_document() {
let mut doc = Document::new();
doc.set_title("Multi-Page Form");
let mut form_manager = FormManager::new();
let page1 = Page::a4();
let name_field = TextField::new("full_name").with_max_length(100);
let name_widget = Widget::new(Rectangle::new(
Point::new(50.0, 700.0),
Point::new(300.0, 720.0),
));
form_manager
.add_text_field(name_field, name_widget, None)
.unwrap();
let email_field = TextField::new("email").with_max_length(200);
let email_widget = Widget::new(Rectangle::new(
Point::new(50.0, 650.0),
Point::new(300.0, 670.0),
));
form_manager
.add_text_field(email_field, email_widget, None)
.unwrap();
doc.add_page(page1);
let page2 = Page::a4();
let newsletter_check = CheckBox::new("newsletter").checked();
let newsletter_widget = Widget::new(Rectangle::new(
Point::new(50.0, 700.0),
Point::new(70.0, 720.0),
));
form_manager
.add_checkbox(newsletter_check, newsletter_widget, None)
.unwrap();
let category_combo = ComboBox::new("category")
.add_option("tech", "Technology")
.add_option("business", "Business")
.add_option("personal", "Personal")
.with_value("tech");
let category_widget = Widget::new(Rectangle::new(
Point::new(50.0, 650.0),
Point::new(200.0, 670.0),
));
form_manager
.add_combo_box(category_combo, category_widget, None)
.unwrap();
doc.add_page(page2);
assert_eq!(form_manager.field_count(), 4);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("multi_page_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Multi-page form created successfully");
let file_size = fs::metadata(&pdf_path).unwrap().len();
assert!(file_size > 700, "Multi-page form should be substantial");
}
Err(e) => {
println!("Multi-page form save failed: {e}");
}
}
}
#[test]
fn test_form_submission_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let form_field = TextField::new("user_input").with_value("test data");
let form_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(300.0, 520.0),
));
form_manager
.add_text_field(form_field, form_widget, None)
.unwrap();
let submit_button = PushButton::new("submit_form").with_caption("Submit");
let submit_widget = Widget::new(Rectangle::new(
Point::new(50.0, 450.0),
Point::new(150.0, 480.0),
));
form_manager
.add_push_button(submit_button, submit_widget, None)
.unwrap();
form_manager.set_default_appearance("/Helvetica 12 Tf 0 g");
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("submission_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Submission form created successfully");
}
Err(e) => {
println!("Submission form save failed: {e}");
}
}
}
#[test]
fn test_form_tab_order_document() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let field_data = [
("first_name", 50.0, 600.0),
("last_name", 250.0, 600.0),
("email", 50.0, 550.0),
("phone", 250.0, 550.0),
("address", 50.0, 500.0),
];
for (i, (name, x, y)) in field_data.iter().enumerate() {
let field = TextField::new(*name).with_max_length(100);
let widget = Widget::new(Rectangle::new(
Point::new(*x, *y),
Point::new(x + 180.0, y + 20.0),
));
let field_ref = form_manager.add_text_field(field, widget, None).unwrap();
assert_eq!(field_ref.number(), (i + 1) as u32);
}
assert_eq!(form_manager.field_count(), 5);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("tab_order_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Tab order form created successfully");
}
Err(e) => {
println!("Tab order form save failed: {e}");
}
}
}
#[test]
fn test_form_encrypted_document_integration() {
let mut doc = Document::new();
doc.set_title("Encrypted Form Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let sensitive_field = TextField::new("ssn")
.with_value("***-**-****")
.with_max_length(11);
let sensitive_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(200.0, 520.0),
));
form_manager
.add_text_field(sensitive_field, sensitive_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("encrypted_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Encrypted form base created successfully");
}
Err(e) => {
println!("Encrypted form save failed: {e}");
}
}
}
#[test]
fn test_form_reset_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let name_field = TextField::new("name")
.with_default_value("Enter your name")
.with_value("User input");
let name_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(300.0, 620.0),
));
form_manager
.add_text_field(name_field, name_widget, None)
.unwrap();
let agree_check = CheckBox::new("agree").checked();
let agree_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
));
form_manager
.add_checkbox(agree_check, agree_widget, None)
.unwrap();
let reset_button = PushButton::new("reset_form").with_caption("Reset");
let reset_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(120.0, 530.0),
));
form_manager
.add_push_button(reset_button, reset_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("reset_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Reset form created successfully");
}
Err(e) => {
println!("Reset form save failed: {e}");
}
}
}
#[test]
fn test_complex_form_layout_document() {
let mut doc = Document::new();
doc.set_title("Complex Layout Form");
let page = Page::a4();
let mut form_manager = FormManager::new();
let title_field = TextField::new("form_title")
.with_value("Registration Form")
.with_max_length(100);
let title_widget = Widget::new(Rectangle::new(
Point::new(50.0, 750.0),
Point::new(550.0, 770.0),
));
form_manager
.add_text_field(title_field, title_widget, None)
.unwrap();
let first_name = TextField::new("first_name").with_max_length(50);
let first_name_widget = Widget::new(Rectangle::new(
Point::new(50.0, 700.0),
Point::new(250.0, 720.0),
));
form_manager
.add_text_field(first_name, first_name_widget, None)
.unwrap();
let address1 = TextField::new("address1").with_max_length(100);
let address1_widget = Widget::new(Rectangle::new(
Point::new(50.0, 650.0),
Point::new(250.0, 670.0),
));
form_manager
.add_text_field(address1, address1_widget, None)
.unwrap();
let last_name = TextField::new("last_name").with_max_length(50);
let last_name_widget = Widget::new(Rectangle::new(
Point::new(300.0, 700.0),
Point::new(500.0, 720.0),
));
form_manager
.add_text_field(last_name, last_name_widget, None)
.unwrap();
let address2 = TextField::new("address2").with_max_length(100);
let address2_widget = Widget::new(Rectangle::new(
Point::new(300.0, 650.0),
Point::new(500.0, 670.0),
));
form_manager
.add_text_field(address2, address2_widget, None)
.unwrap();
let email = TextField::new("email").with_max_length(200);
let email_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(500.0, 620.0),
));
form_manager
.add_text_field(email, email_widget, None)
.unwrap();
let terms_check = CheckBox::new("terms").checked();
let terms_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
));
form_manager
.add_checkbox(terms_check, terms_widget, None)
.unwrap();
let privacy_check = CheckBox::new("privacy");
let privacy_widget = Widget::new(Rectangle::new(
Point::new(50.0, 520.0),
Point::new(70.0, 540.0),
));
form_manager
.add_checkbox(privacy_check, privacy_widget, None)
.unwrap();
let submit = PushButton::new("submit").with_caption("Submit Registration");
let submit_widget = Widget::new(Rectangle::new(
Point::new(200.0, 450.0),
Point::new(350.0, 480.0),
));
form_manager
.add_push_button(submit, submit_widget, None)
.unwrap();
assert_eq!(form_manager.field_count(), 9);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("complex_layout_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Complex layout form created successfully");
let file_size = fs::metadata(&pdf_path).unwrap().len();
assert!(file_size > 800, "Complex form should be substantial");
}
Err(e) => {
println!("Complex layout form save failed: {e}");
}
}
}
#[test]
fn test_form_tooltips_document_integration() {
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let help_field = TextField::new("password")
.with_value("")
.password()
.with_max_length(50);
let help_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(300.0, 520.0),
));
form_manager
.add_text_field(help_field, help_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("tooltip_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Tooltip form created successfully");
}
Err(e) => {
println!("Tooltip form save failed: {e}");
}
}
}
#[test]
fn test_form_data_extraction_integration() {
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("extraction_test.pdf");
{
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let test_field = TextField::new("extraction_test")
.with_value("test_data_123")
.with_max_length(50);
let test_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(200.0, 520.0),
));
form_manager
.add_text_field(test_field, test_widget, None)
.unwrap();
doc.add_page(page);
match doc.save(&pdf_path) {
Ok(_) => println!("Extraction test form saved"),
Err(e) => {
println!("Save failed: {e}");
return;
}
}
}
if pdf_path.exists() {
if let Ok(pdf_data) = fs::read(&pdf_path) {
let cursor = Cursor::new(pdf_data);
match PdfReader::new(cursor) {
Ok(_pdf_reader) => {
println!("Form document loaded for extraction");
println!("Form data extraction needs implementation");
}
Err(e) => {
println!("Failed to load form document for extraction: {e}");
}
}
}
}
}
#[test]
fn test_form_different_page_sizes() {
let mut doc = Document::new();
let a4_page = Page::a4();
let mut form_manager = FormManager::new();
let a4_field = TextField::new("a4_field").with_value("A4 Page Field");
let a4_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(300.0, 520.0),
));
form_manager
.add_text_field(a4_field, a4_widget, None)
.unwrap();
doc.add_page(a4_page);
let letter_page = Page::letter();
let letter_field = TextField::new("letter_field").with_value("Letter Page Field");
let letter_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(350.0, 620.0),
));
form_manager
.add_text_field(letter_field, letter_widget, None)
.unwrap();
doc.add_page(letter_page);
assert_eq!(form_manager.field_count(), 2);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("mixed_sizes_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Mixed page sizes form created successfully");
}
Err(e) => {
println!("Mixed page sizes form save failed: {e}");
}
}
}
#[test]
fn test_form_creation_performance() {
let start_time = std::time::Instant::now();
let mut doc = Document::new();
let page = Page::a4();
let mut form_manager = FormManager::new();
let field_count = 100;
for i in 0..field_count {
let field_name = format!("perf_field_{i}");
let field = TextField::new(field_name)
.with_value(format!("Value {i}"))
.with_max_length(50);
let y_pos = 750.0 - (i as f64 * 7.0);
let widget = Widget::new(Rectangle::new(
Point::new(50.0, y_pos),
Point::new(200.0, y_pos + 5.0),
));
form_manager.add_text_field(field, widget, None).unwrap();
}
let creation_time = start_time.elapsed();
println!("Created {field_count} fields in {creation_time:?}");
assert!(
creation_time.as_millis() < 1000,
"Field creation too slow: {creation_time:?}"
);
assert_eq!(form_manager.field_count(), field_count);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("performance_form.pdf");
let save_start = std::time::Instant::now();
match doc.save(&pdf_path) {
Ok(_) => {
let save_time = save_start.elapsed();
println!("Saved performance form in {save_time:?}");
assert!(
save_time.as_secs() < 10,
"Save took too long: {save_time:?}"
);
}
Err(e) => {
println!("Performance form save failed: {e}");
}
}
}
#[test]
fn test_form_memory_usage() {
let initial_field_count = 10;
let mut form_managers = Vec::new();
for i in 0..10 {
let mut form_manager = FormManager::new();
for j in 0..initial_field_count {
let field_name = format!("mem_test_{i}_{j}");
let field = TextField::new(field_name)
.with_value(format!("Memory test value {i} {j}"))
.with_max_length(100);
let widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0 - j as f64 * 20.0),
Point::new(300.0, 520.0 - j as f64 * 20.0),
));
form_manager.add_text_field(field, widget, None).unwrap();
}
assert_eq!(form_manager.field_count(), initial_field_count);
form_managers.push(form_manager);
}
assert_eq!(form_managers.len(), 10);
for (i, manager) in form_managers.iter().enumerate() {
assert_eq!(manager.field_count(), initial_field_count);
println!("Form manager {} has {} fields", i, manager.field_count());
}
drop(form_managers);
println!("Memory usage test completed successfully");
}
#[test]
fn test_document_catalog_acroform_integration() {
let mut doc = Document::new();
doc.set_title("Catalog Integration Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let catalog_field = TextField::new("catalog_test").with_value("Testing catalog");
let catalog_widget = Widget::new(Rectangle::new(
Point::new(100.0, 500.0),
Point::new(400.0, 520.0),
));
form_manager
.add_text_field(catalog_field, catalog_widget, None)
.unwrap();
let acro_form = form_manager.get_acro_form();
let acro_dict = acro_form.to_dict();
assert!(
acro_dict.get("Fields").is_some(),
"AcroForm must have Fields array"
);
assert!(
acro_dict.get("NeedAppearances").is_some(),
"AcroForm must have NeedAppearances"
);
if let Some(fields_obj) = acro_dict.get("Fields") {
match fields_obj {
oxidize_pdf::objects::Object::Array(fields_array) => {
assert_eq!(fields_array.len(), 1, "Should have one field reference");
}
_ => panic!("Fields should be an array"),
}
}
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("catalog_integration.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Catalog integration test saved successfully");
}
Err(e) => {
println!("Catalog integration save failed: {e}");
}
}
}
#[test]
fn test_cross_browser_form_compatibility() {
let mut doc = Document::new();
doc.set_title("Cross-Browser Compatibility Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let standard_field = TextField::new("standard_text")
.with_value("Standard text field")
.with_max_length(100);
let standard_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(350.0, 620.0),
));
form_manager
.add_text_field(standard_field, standard_widget, None)
.unwrap();
let standard_check = CheckBox::new("standard_check").checked();
let check_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
));
form_manager
.add_checkbox(standard_check, check_widget, None)
.unwrap();
let standard_button = PushButton::new("standard_button").with_caption("Click Me");
let button_widget = Widget::new(Rectangle::new(
Point::new(50.0, 500.0),
Point::new(150.0, 530.0),
));
form_manager
.add_push_button(standard_button, button_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("compatibility_test.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Cross-browser compatibility form created");
}
Err(e) => {
println!("Compatibility form save failed: {e}");
}
}
}
#[test]
fn test_international_form_support() {
let mut doc = Document::new();
doc.set_title("International Form Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let international_texts = vec![
("chinese", "你好世界"),
("arabic", "مرحبا بالعالم"),
("spanish", "Hola Mundo ñáéíóú"),
("french", "Bonjour le monde àèéêë"),
("german", "Hallo Welt äöüß"),
("russian", "Привет мир"),
("japanese", "こんにちは世界"),
];
for (i, (lang, text)) in international_texts.iter().enumerate() {
let field_name = format!("international_{lang}");
let field = TextField::new(field_name)
.with_value(*text)
.with_max_length(100);
let y_pos = 700.0 - (i as f64 * 30.0);
let widget = Widget::new(Rectangle::new(
Point::new(50.0, y_pos),
Point::new(400.0, y_pos + 20.0),
));
form_manager.add_text_field(field, widget, None).unwrap();
}
assert_eq!(form_manager.field_count(), international_texts.len());
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("international_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("International form created successfully");
let file_size = fs::metadata(&pdf_path).unwrap().len();
assert!(
file_size > 600,
"International form should have substantial content"
);
}
Err(e) => {
println!("International form save failed: {e}");
}
}
}
#[test]
fn test_form_accessibility_features() {
let mut doc = Document::new();
doc.set_title("Accessibility Form Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let required_options = FieldOptions {
flags: FieldFlags {
read_only: false,
required: true,
no_export: false,
},
default_appearance: Some("/Helvetica 12 Tf 0 g".to_string()),
quadding: Some(0),
};
let accessible_field = TextField::new("accessible_name")
.with_value("")
.with_max_length(100);
let accessible_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(350.0, 620.0),
));
form_manager
.add_text_field(accessible_field, accessible_widget, Some(required_options))
.unwrap();
let accessible_check = CheckBox::new("accessibility_consent").with_export_value("I_agree");
let check_widget = Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
));
form_manager
.add_checkbox(accessible_check, check_widget, None)
.unwrap();
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("accessibility_form.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Accessibility form created successfully");
}
Err(e) => {
println!("Accessibility form save failed: {e}");
}
}
}
#[test]
fn test_comprehensive_form_validation() {
let mut doc = Document::new();
doc.set_title("Comprehensive Validation Test");
let page = Page::a4();
let mut form_manager = FormManager::new();
let empty_required = TextField::new("empty_required")
.with_value("") .with_max_length(50);
let empty_widget = Widget::new(Rectangle::new(
Point::new(50.0, 650.0),
Point::new(300.0, 670.0),
));
let required_flags = FieldOptions {
flags: FieldFlags {
read_only: false,
required: true,
no_export: false,
},
default_appearance: None,
quadding: None,
};
form_manager
.add_text_field(empty_required, empty_widget, Some(required_flags))
.unwrap();
let long_value = "a".repeat(200); let long_field = TextField::new("long_value_field")
.with_value(&long_value)
.with_max_length(50);
let long_widget = Widget::new(Rectangle::new(
Point::new(50.0, 600.0),
Point::new(300.0, 620.0),
));
form_manager
.add_text_field(long_field, long_widget, None)
.unwrap();
let invalid_radio = RadioButton::new("invalid_selection")
.add_option("A", "Option A")
.add_option("B", "Option B")
.with_selected(5); let radio_widgets = vec![
Widget::new(Rectangle::new(
Point::new(50.0, 550.0),
Point::new(70.0, 570.0),
)),
Widget::new(Rectangle::new(
Point::new(100.0, 550.0),
Point::new(120.0, 570.0),
)),
];
form_manager
.add_radio_buttons(invalid_radio, radio_widgets, None)
.unwrap();
let invalid_list = ListBox::new("invalid_list")
.add_option("X", "Option X")
.add_option("Y", "Option Y")
.with_selected(vec![0, 1, 10]); let list_widget = Widget::new(Rectangle::new(
Point::new(50.0, 450.0),
Point::new(200.0, 500.0),
));
form_manager
.add_list_box(invalid_list, list_widget, None)
.unwrap();
let empty_combo = ComboBox::new("empty_options").with_value("NonExistentValue"); let combo_widget = Widget::new(Rectangle::new(
Point::new(250.0, 450.0),
Point::new(400.0, 470.0),
));
form_manager
.add_combo_box(empty_combo, combo_widget, None)
.unwrap();
assert_eq!(form_manager.field_count(), 5);
doc.add_page(page);
let temp_dir = TempDir::new().unwrap();
let pdf_path = temp_dir.path().join("validation_edge_cases.pdf");
match doc.save(&pdf_path) {
Ok(_) => {
println!("Comprehensive validation test created");
println!("Edge case validation needs implementation");
}
Err(e) => {
println!("Validation test save failed: {e}");
}
}
}