mod common; use crate::common::assert_linked_with; use linkify::{LinkFinder, LinkKind}; #[test] fn no_links() { assert_not_linked(""); assert_not_linked("foo"); assert_not_linked(":"); assert_not_linked("://"); assert_not_linked(":::"); } #[test] fn schemes() { assert_not_linked("://foo"); assert_not_linked("1://foo"); assert_not_linked("123://foo"); assert_not_linked("+://foo"); assert_not_linked("-://foo"); assert_not_linked(".://foo"); assert_not_linked("1abc://foo"); assert_linked("a://foo", "|a://foo|"); assert_linked("a123://foo", "|a123://foo|"); assert_linked("a123b://foo", "|a123b://foo|"); assert_linked("a+b://foo", "|a+b://foo|"); assert_linked("a-b://foo", "|a-b://foo|"); assert_linked("a.b://foo", "|a.b://foo|"); assert_linked("ABC://foo", "|ABC://foo|"); assert_linked(".http://example.org/", ".|http://example.org/|"); assert_linked("1.http://example.org/", "1.|http://example.org/|"); } #[test] fn authority() { assert_not_linked("ab://"); assert_not_linked("file://"); assert_not_linked("file:// "); assert_not_linked("\"file://\""); assert_not_linked("\"file://...\", "); assert_linked("file://somefile", "|file://somefile|"); assert_linked("file://../relative", "|file://../relative|"); assert_linked("http://a.", "|http://a|."); } #[test] fn local_links() { assert_linked("http://127.0.0.1", "|http://127.0.0.1|"); assert_linked("http://127.0.0.1/", "|http://127.0.0.1/|"); } #[test] fn single_links() { assert_linked("ab://c", "|ab://c|"); assert_linked("http://example.org/", "|http://example.org/|"); assert_linked("http://example.org/123", "|http://example.org/123|"); assert_linked( "http://example.org/?foo=test&bar=123", "|http://example.org/?foo=test&bar=123|", ); assert_linked( "http://example.org/?foo=%20", "|http://example.org/?foo=%20|", ); assert_linked("http://example.org/%3C", "|http://example.org/%3C|"); } #[test] fn single_links_without_protocol() { assert_urls_without_protocol("example.org/", "|example.org/|"); assert_urls_without_protocol("example.org/123", "|example.org/123|"); assert_urls_without_protocol( "example.org/?foo=test&bar=123", "|example.org/?foo=test&bar=123|", ); assert_urls_without_protocol("example.org/?foo=%20", "|example.org/?foo=%20|"); assert_urls_without_protocol("example.org/%3C", "|example.org/%3C|"); } #[test] fn space_characters_stop_url() { assert_linked("foo http://example.org/", "foo |http://example.org/|"); assert_linked("http://example.org/ bar", "|http://example.org/| bar"); assert_linked("http://example.org/\tbar", "|http://example.org/|\tbar"); assert_linked("http://example.org/\nbar", "|http://example.org/|\nbar"); assert_linked( "http://example.org/\u{0B}bar", "|http://example.org/|\u{0B}bar", ); assert_linked( "http://example.org/\u{0C}bar", "|http://example.org/|\u{0C}bar", ); assert_linked("http://example.org/\rbar", "|http://example.org/|\rbar"); } #[test] fn space_characters_stop_url_without_protocol() { assert_urls_without_protocol("foo example.org/", "foo |example.org/|"); assert_urls_without_protocol("example.org/ bar", "|example.org/| bar"); assert_urls_without_protocol("example.org/\tbar", "|example.org/|\tbar"); assert_urls_without_protocol("example.org/\nbar", "|example.org/|\nbar"); assert_urls_without_protocol("example.org/\u{0B}bar", "|example.org/|\u{0B}bar"); assert_urls_without_protocol("example.org/\u{0C}bar", "|example.org/|\u{0C}bar"); assert_urls_without_protocol("example.org/\rbar", "|example.org/|\rbar"); } #[test] fn illegal_characters_stop_url() { assert_linked("http://example.org/<", "|http://example.org/|<"); assert_linked("http://example.org/>", "|http://example.org/|>"); assert_linked("http://example.org/<>", "|http://example.org/|<>"); assert_linked("http://example.org/\u{00}", "|http://example.org/|\u{00}"); assert_linked("http://example.org/\u{0E}", "|http://example.org/|\u{0E}"); assert_linked("http://example.org/\u{7F}", "|http://example.org/|\u{7F}"); assert_linked("http://example.org/\u{9F}", "|http://example.org/|\u{9F}"); assert_linked("http://example.org/foo|bar", "|http://example.org/foo||bar"); } #[test] fn illegal_characters_stop_url_without_protocol() { assert_urls_without_protocol("example.org/<", "|example.org/|<"); assert_urls_without_protocol("example.org/>", "|example.org/|>"); assert_urls_without_protocol("example.org/<>", "|example.org/|<>"); assert_urls_without_protocol("example.org/\u{00}", "|example.org/|\u{00}"); assert_urls_without_protocol("example.org/\u{0E}", "|example.org/|\u{0E}"); assert_urls_without_protocol("example.org/\u{7F}", "|example.org/|\u{7F}"); assert_urls_without_protocol("example.org/\u{9F}", "|example.org/|\u{9F}"); } #[test] fn delimiter_at_end() { assert_linked("http://example.org/.", "|http://example.org/|."); assert_linked("http://example.org/..", "|http://example.org/|.."); assert_linked("http://example.org/,", "|http://example.org/|,"); assert_linked("http://example.org/:", "|http://example.org/|:"); assert_linked("http://example.org/?", "|http://example.org/|?"); assert_linked("http://example.org/!", "|http://example.org/|!"); assert_linked("http://example.org/;", "|http://example.org/|;"); } #[test] fn delimiter_at_end_no_protocol() { assert_urls_without_protocol("example.org/.", "|example.org/|."); assert_urls_without_protocol("example.org/..", "|example.org/|.."); assert_urls_without_protocol("example.org/,", "|example.org/|,"); assert_urls_without_protocol("example.org/:", "|example.org/|:"); assert_urls_without_protocol("example.org/?", "|example.org/|?"); assert_urls_without_protocol("example.org/!", "|example.org/|!"); assert_urls_without_protocol("example.org/;", "|example.org/|;"); } #[test] fn matching_punctuation() { assert_linked("http://example.org/a(b)", "|http://example.org/a(b)|"); assert_linked("http://example.org/a[b]", "|http://example.org/a[b]|"); assert_linked("http://example.org/a{b}", "|http://example.org/a{b}|"); assert_linked("http://example.org/a'b'", "|http://example.org/a'b'|"); assert_linked("(http://example.org/)", "(|http://example.org/|)"); assert_linked("[http://example.org/]", "[|http://example.org/|]"); assert_linked("{http://example.org/}", "{|http://example.org/|}"); assert_linked("\"http://example.org/\"", "\"|http://example.org/|\""); assert_linked("'http://example.org/'", "'|http://example.org/|'"); } #[test] fn matching_punctuation_without_protocol() { assert_urls_without_protocol("example.org/a(b)", "|example.org/a(b)|"); assert_urls_without_protocol("example.org/a[b]", "|example.org/a[b]|"); assert_urls_without_protocol("example.org/a{b}", "|example.org/a{b}|"); assert_urls_without_protocol("example.org/a'b'", "|example.org/a'b'|"); assert_urls_without_protocol("(example.org/)", "(|example.org/|)"); assert_urls_without_protocol("[example.org/]", "[|example.org/|]"); assert_urls_without_protocol("{example.org/}", "{|example.org/|}"); assert_urls_without_protocol("\"example.org/\"", "\"|example.org/|\""); assert_urls_without_protocol("'example.org/'", "'|example.org/|'"); } #[test] fn matching_punctuation_tricky() { assert_linked("((http://example.org/))", "((|http://example.org/|))"); assert_linked( "((http://example.org/a(b)))", "((|http://example.org/a(b)|))", ); assert_linked("[(http://example.org/)]", "[(|http://example.org/|)]"); assert_linked("(http://example.org/).", "(|http://example.org/|)."); assert_linked("(http://example.org/.)", "(|http://example.org/|.)"); assert_linked("http://example.org/>", "|http://example.org/|>"); // not sure about these assert_linked("http://example.org/(", "|http://example.org/|("); assert_linked("http://example.org/(.", "|http://example.org/|(."); assert_linked("http://example.org/]()", "|http://example.org/|]()"); } #[test] fn matching_punctuation_tricky_without_protocol() { assert_urls_without_protocol("((example.org/))", "((|example.org/|))"); assert_urls_without_protocol("((example.org/a(b)))", "((|example.org/a(b)|))"); assert_urls_without_protocol("[(example.org/)]", "[(|example.org/|)]"); assert_urls_without_protocol("(example.org/).", "(|example.org/|)."); assert_urls_without_protocol("(example.org/.)", "(|example.org/|.)"); assert_urls_without_protocol("example.org/>", "|example.org/|>"); // not sure about these assert_urls_without_protocol("example.org/(", "|example.org/|("); assert_urls_without_protocol("example.org/(.", "|example.org/|(."); assert_urls_without_protocol("example.org/]()", "|example.org/|]()"); } #[test] fn single_quote() { assert_linked("'https://example.org'", "'|https://example.org|'"); assert_linked("\"https://example.org\"", "\"|https://example.org|\""); assert_linked("''https://example.org''", "''|https://example.org|''"); assert_linked("'https://example.org''", "'|https://example.org|''"); assert_linked("'https://example.org", "'|https://example.org|"); assert_linked( "http://example.org/\'_(foo)", "|http://example.org/\'_(foo)|", ); assert_linked( "http://example.org/\'_(foo)\'", "|http://example.org/\'_(foo)\'|", ); assert_linked("http://example.org/\'\'", "|http://example.org/\'\'|"); assert_linked("http://example.org/\'\'\'", "|http://example.org/\'\'|\'"); assert_linked("http://example.org/\'.", "|http://example.org/|\'."); assert_linked("http://example.org/\'a", "|http://example.org/\'a|"); assert_linked("http://example.org/it's", "|http://example.org/it's|"); } #[test] fn single_quote_without_protocol() { assert_urls_without_protocol("example.org/\'_(foo)", "|example.org/\'_(foo)|"); assert_urls_without_protocol("example.org/\'_(foo)\'", "|example.org/\'_(foo)\'|"); assert_urls_without_protocol("example.org/\'\'", "|example.org/\'\'|"); assert_urls_without_protocol("example.org/\'\'\'", "|example.org/\'\'|\'"); assert_urls_without_protocol("example.org/\'.", "|example.org/|\'."); assert_urls_without_protocol("example.org/\'a", "|example.org/\'a|"); assert_urls_without_protocol("example.org/it's", "|example.org/it's|"); } #[test] fn double_quote() { // " not allowed in URLs assert_linked("http://example.org/\"a", "|http://example.org/|\"a"); assert_linked("http://example.org/\"a\"", "|http://example.org/|\"a\""); } #[test] fn grave_quote() { // ` not allowed in URLs assert_linked("http://example.org/`a", "|http://example.org/|`a"); assert_linked("http://example.org/`a`", "|http://example.org/|`a`"); } #[test] fn asterisk() { assert_linked("https://example.org*", "|https://example.org|*"); assert_linked("https://example.org/*", "|https://example.org/|*"); assert_linked("https://example.org/**", "|https://example.org/|**"); assert_linked("https://example.org/*/a", "|https://example.org/*/a|"); } #[test] fn grave_quote_without_protocol() { // ` not allowed in URLs assert_urls_without_protocol("example.org/`a", "|example.org/|`a"); assert_urls_without_protocol("example.org/`a`", "|example.org/|`a`"); } #[test] fn html() { assert_linked("http://example.org\">", "|http://example.org|\">"); assert_linked("http://example.org'>", "|http://example.org|'>"); assert_linked("http://example.org\"/>", "|http://example.org|\"/>"); assert_linked("http://example.org'/>", "|http://example.org|'/>"); assert_linked("http://example.org
", "|http://example.org|
"); assert_linked("http://example.org
", "|http://example.org|"); } #[test] fn html_no_protocol() { assert_urls_without_protocol("example.org\">", "|example.org|\">"); assert_urls_without_protocol("example.org'>", "|example.org|'>"); assert_urls_without_protocol("example.org\"/>", "|example.org|\"/>"); assert_urls_without_protocol("example.org'/>", "|example.org|'/>"); assert_urls_without_protocol("example.org", "|example.org|
"); assert_urls_without_protocol("example.org
", "|example.org|"); } #[test] fn css() { assert_linked("http://example.org\");", "|http://example.org|\");"); assert_linked("http://example.org');", "|http://example.org|');"); } #[test] fn images() { assert_linked( r#""#, r#""#, ); } #[test] fn complex_html() { assert_linked( r#""#, r#""#, ); assert_linked( r#""#, r#""#, ); assert_linked( r#"