use pter::convert; #[test] fn simple_email() { let html = r#" Email

Meeting Tomorrow

Hi Max,

Just confirming our meeting tomorrow at 2pm.

Best,
Alice

"#; let md = convert(html); assert!(md.contains("# Meeting Tomorrow")); assert!(md.contains("Hi Max,")); assert!(md.contains("**2pm**")); assert!(md.contains("Best,\nAlice")); } #[test] fn email_with_links() { let html = r#"

Please review the document.

Direct link: https://example.com

"#; let md = convert(html); assert!(md.contains("[document](https://example.com/doc)")); // Link text matches URL — no markdown link syntax assert!(md.contains("Direct link: https://example.com")); } #[test] fn email_with_tracking_pixels() { let html = r#"

Content here

A real photo "#; let md = convert(html); assert!(md.contains("Content here")); assert!(!md.contains("tracker")); assert!(!md.contains("data:image")); assert!(md.contains("![A real photo](real-image.jpg)")); } #[test] fn email_with_quoted_reply() { let html = r#"

Thanks, that works for me.

Can we meet at 3pm instead?

"#; let md = convert(html); assert!(md.contains("Thanks, that works for me.")); assert!(md.contains("> Can we meet at 3pm instead?")); } #[test] fn email_with_signature_line() { let html = r#"

See you then.


Alice Smith

Engineering Lead

"#; let md = convert(html); assert!(md.contains("See you then.")); assert!(md.contains("---")); assert!(md.contains("Alice Smith")); } #[test] fn deeply_nested_blockquotes() { let html = r#"

Got it.

Sounds good.

Can we reschedule?

Original message here.

"#; let md = convert(html); assert!(md.contains("Got it.")); assert!(md.contains("> Sounds good.")); assert!(md.contains("> > Can we reschedule?")); assert!(md.contains("> > > Original message here.")); } #[test] fn complex_list_structure() { let html = r#"

Action items:

  1. Review the PR
  2. Deploy to staging
"#; let md = convert(html); assert!(md.contains("Action items:")); assert!(md.contains("1. Review the PR")); assert!(md.contains(" - Check tests")); assert!(md.contains("2. Deploy to staging")); } #[test] fn pre_block_preserves_formatting() { let html = r#"

Here's the code:

fn main() {
    println!("hello");
}
"#; let md = convert(html); assert!(md.contains("Here's the code:")); assert!(md.contains("```\nfn main()")); assert!(md.contains(" println!")); } #[test] fn hidden_content_stripped() { let html = r#"

Visible content

This should not appear

Also hidden

More visible

"#; let md = convert(html); assert!(md.contains("Visible content")); assert!(!md.contains("should not appear")); assert!(!md.contains("Also hidden")); assert!(md.contains("More visible")); } #[test] fn script_and_style_fully_removed() { let html = r#"

Safe content

"#; let md = convert(html); assert_eq!(md, "Safe content"); } #[test] fn newsletter_table_layout() { // Typical email newsletter wrapped in layout tables let html = r#"

Weekly Digest

Here are your updates for this week.

  • New release v2.0
  • Bug fixes

Thanks for reading!

"#; let md = convert(html); assert!(md.contains("## Weekly Digest")); assert!(md.contains("Here are your updates for this week.")); assert!(md.contains("- New release v2.0")); assert!(md.contains("- Bug fixes")); assert!(md.contains("Thanks for reading!")); assert!(!md.contains("track.example.com")); // No table markup in output assert!(!md.contains("| ")); } #[test] fn data_table_preserved() { let html = r#"

Order summary:

ItemQtyPrice
Widget3$15.00
Gadget1$29.99
"#; let md = convert(html); assert!(md.contains("Order summary:")); assert!(md.contains("| Item | Qty | Price |")); assert!(md.contains("| --- | --- | --- |")); assert!(md.contains("| Widget | 3 | $15.00 |")); assert!(md.contains("| Gadget | 1 | $29.99 |")); } #[test] fn spacer_and_tracking_stripped() { let html = r#"

Real content

 
invisible

More content

"#; let md = convert(html); assert!(md.contains("Real content")); assert!(md.contains("More content")); assert!(!md.contains("invisible")); assert!(!md.contains("pixel.gif")); } // -- Reply chain tests -- #[test] fn gmail_reply_chain() { let html = r#"

Thanks, that works for me.

On Mon, Jan 5, 2026 at 3:00 PM Alice <alice@example.com> wrote:

Can we meet at 3pm instead of 2pm?

"#; let md = convert(html); assert!(md.contains("Thanks, that works for me.")); // The gmail_quote div should be rendered as a quote block assert!(md.contains("> ")); assert!(md.contains("3pm instead of 2pm")); } #[test] fn apple_mail_reply() { let html = r#"
Sounds good, see you then.

Hey, are we still on for lunch?
"#; let md = convert(html); assert!(md.contains("Sounds good, see you then.")); assert!(md.contains("> ")); assert!(md.contains("still on for lunch")); } #[test] fn outlook_reply_with_separator() { let html = r#"

I'll handle it.


From: Alice Smith
Sent: Monday, January 5, 2026
To: Bob Jones
Subject: Action needed

Can you take a look at the report?

"#; let md = convert(html); assert!(md.contains("I'll handle it.")); assert!(md.contains("---")); // hr separator assert!(md.contains("From: Alice Smith")); assert!(md.contains("take a look at the report")); } #[test] fn nested_gmail_reply_chain() { let html = r#"

Got it, thanks!

On Tue, Jan 6, Bob wrote:

Here's the update.

On Mon, Jan 5, Alice wrote:

What's the status?

"#; let md = convert(html); assert!(md.contains("Got it, thanks!")); // Should have nested quoting assert!(md.contains("> ")); assert!(md.contains("Here's the update.")); assert!(md.contains("What's the status?")); } #[test] fn forwarded_message() { let html = r#"

FYI, see below.

---------- Forwarded message ----------

From: Alice

The deadline has been moved to Friday.

"#; let md = convert(html); assert!(md.contains("FYI, see below.")); assert!(md.contains("Forwarded message")); assert!(md.contains("deadline has been moved")); } #[test] fn protonmail_reply() { let html = r#"
Will do, thanks.
Please send me the files by EOD.
"#; let md = convert(html); assert!(md.contains("Will do, thanks.")); assert!(md.contains("> ")); assert!(md.contains("send me the files")); } #[test] fn attribution_preserved_above_quote() { let html = r#"

Agreed.

On Wed, Jan 7, 2026 at 10:00 AM Carol wrote:

Let's go with option B.

"#; let md = convert(html); assert!(md.contains("Agreed.")); // Attribution should appear assert!(md.contains("Carol wrote:")); assert!(md.contains("option B")); }