+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_headings() {
+ assert_eq!(parse_line("### Heading"), GeminiLine::Heading(3, " Heading".to_string()));
+ assert_eq!(parse_line("## Heading"), GeminiLine::Heading(2, " Heading".to_string()));
+ assert_eq!(parse_line("# Heading"), GeminiLine::Heading(1, " Heading".to_string()));
+ assert_eq!(parse_line("###"), GeminiLine::Heading(3, "".to_string()));
+ assert_eq!(parse_line("#####"), GeminiLine::Heading(3, "##".to_string()));
+ assert_eq!(parse_line("# "), GeminiLine::Heading(1, " ".to_string()));
+
+ assert_eq!(parse_preformatted_line("### Heading"), GeminiLine::Text("### Heading".to_string(), true));
+ assert_eq!(parse_preformatted_line("## Heading"), GeminiLine::Text("## Heading".to_string(), true));
+ assert_eq!(parse_preformatted_line("# Heading"), GeminiLine::Text("# Heading".to_string(), true));
+ }
+
+ #[test]
+ fn test_links() {
+ assert_eq!(
+ parse_line("=> https://example.com Link text"),
+ GeminiLine::Link("https://example.com".to_string(), "Link text".to_string())
+ );
+ assert_eq!(
+ parse_line("=> /local/path"),
+ GeminiLine::Link("/local/path".to_string(), "".to_string())
+ );
+
+ assert_eq!(
+ parse_line("=>"),
+ GeminiLine::Link("".to_string(), "".to_string())
+ );
+ assert_eq!(
+ parse_line("=> "),
+ GeminiLine::Link("".to_string(), "".to_string())
+ );
+ assert_eq!(
+ parse_line("=> multiple spaces in text"),
+ GeminiLine::Link("multiple".to_string(), "spaces in text".to_string())
+ );
+
+ assert_eq!(
+ parse_preformatted_line("=> https://example.com Link text"),
+ GeminiLine::Text("=> https://example.com Link text".to_string(), true)
+ );
+ }
+
+ #[test]
+ fn test_list_items() {
+ assert_eq!(
+ parse_line("* List item"),
+ GeminiLine::ListItem("List item".to_string())
+ );
+
+ assert_eq!(parse_line("* "), GeminiLine::ListItem("".to_string()));
+ assert_eq!(parse_line("*"), GeminiLine::Text("*".to_string(), false));
+ assert_eq!(parse_line("*WithText"), GeminiLine::Text("*WithText".to_string(), false));
+ assert_eq!(parse_line("* Multiple spaces"), GeminiLine::ListItem(" Multiple spaces".to_string()));
+ }
+
+ #[test]
+ fn test_quotes() {
+ assert_eq!(
+ parse_line(">Quote text"),
+ GeminiLine::Quote("Quote text".to_string())
+ );
+
+ assert_eq!(parse_line(">"), GeminiLine::Quote("".to_string()));
+ assert_eq!(parse_line("> "), GeminiLine::Quote(" ".to_string()));
+ assert_eq!(parse_line(">>Nested"), GeminiLine::Quote(">Nested".to_string()));
+ }
+
+ #[test]
+ fn test_preformatted() {
+ assert_eq!(
+ parse_line("```alt-text"),
+ GeminiLine::PreformattedToggle(true, "alt-text".to_string())
+ );
+
+ assert_eq!(parse_line("```"), GeminiLine::PreformattedToggle(true, "".to_string()));
+ assert_eq!(parse_line("``` "), GeminiLine::PreformattedToggle(true, " ".to_string()));
+ assert_eq!(parse_line("````"), GeminiLine::PreformattedToggle(true, "`".to_string()));
+
+ assert_eq!(
+ parse_preformatted_line("```alt-text"),
+ GeminiLine::PreformattedToggle(false, "".to_string())
+ );
+ assert_eq!(
+ parse_preformatted_line("```"),
+ GeminiLine::PreformattedToggle(false, "".to_string())
+ );
+
+ }
+
+ #[test]
+ fn test_text() {
+ // Normal case
+ assert_eq!(
+ parse_line("Regular text"),
+ GeminiLine::Text("Regular text".to_string(), false)
+ );
+
+ // Edge cases
+ assert_eq!(parse_line(""), GeminiLine::Text("".to_string(), false));
+ assert_eq!(parse_line(" "), GeminiLine::Text(" ".to_string(), false));
+ assert_eq!(parse_line(" "), GeminiLine::Text(" ".to_string(), false));
+ }
+
+ #[test]
+ fn test_malformed_input() {
+ assert_eq!(parse_line("= >Not a link"), GeminiLine::Text("= >Not a link".to_string(), false));
+ assert_eq!(parse_line("``Not preformatted"), GeminiLine::Text("``Not preformatted".to_string(), false));
+ assert_eq!(parse_line("** Not a list"), GeminiLine::Text("** Not a list".to_string(), false));
+ }
+
+ #[test]
+ fn test_full_document() {
+ let input = "\
+# Heading 1
+## Heading 2
+### Heading 3
+Regular text
+=> https://example.com Link text
+* List item
+>Quote
+```alt
+code
+# Heading 1
+## Heading 2
+### Heading 3
+=> https://example.com Link text
+* List item
+>Quote
+```trailing alt";
+ let result = parse(input);
+ assert_eq!(result, vec![
+ GeminiLine::Heading(1, " Heading 1".to_string()),
+ GeminiLine::Heading(2, " Heading 2".to_string()),
+ GeminiLine::Heading(3, " Heading 3".to_string()),
+ GeminiLine::Text("Regular text".to_string(), false),
+ GeminiLine::Link("https://example.com".to_string(), "Link text".to_string()),
+ GeminiLine::ListItem("List item".to_string()),
+ GeminiLine::Quote("Quote".to_string()),
+ GeminiLine::PreformattedToggle(true, "alt".to_string()),
+ GeminiLine::Text("code".to_string(), true),
+ GeminiLine::Text("# Heading 1".to_string(), true),
+ GeminiLine::Text("## Heading 2".to_string(), true),
+ GeminiLine::Text("### Heading 3".to_string(), true),
+ GeminiLine::Text("=> https://example.com Link text".to_string(), true),
+ GeminiLine::Text("* List item".to_string(), true),
+ GeminiLine::Text(">Quote".to_string(), true),
+ GeminiLine::PreformattedToggle(false, "".to_string()),
+ ]);