use super::sitemap::parse_sitemap;
type Want = (&'static [&'static str], &'static [&'static str]);
#[test]
fn table_parse_sitemap() {
const CASES: &[(&[u8], Want)] = &[
(
br#"<?xml version="1.0"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://example.com/a</loc><lastmod>2026-01-01</lastmod></url>
<url><loc><![CDATA[https://example.com/b?x=1&y=2]]></loc></url>
<url><loc>https://example.com/c?p=1&q=2</loc></url></urlset>"#,
(
&[
"https://example.com/a",
"https://example.com/b?x=1&y=2",
"https://example.com/c?p=1&q=2",
],
&[],
),
),
(
br#"<sitemapindex><sitemap><loc>https://example.com/s1.xml.gz</loc></sitemap></sitemapindex>"#,
(&[], &["https://example.com/s1.xml.gz"]),
),
(b"not xml <<<", (&[], &[])),
(
br#"<?xml version="1.0"?><rss version="2.0"><channel><link>https://example.com/</link>
<item><title>A</title><link>https://example.com/a?x=1&y=2</link></item>
<item><link><![CDATA[https://example.com/b]]></link></item></channel></rss>"#,
(&["https://example.com/a?x=1&y=2", "https://example.com/b"], &[]),
),
(
br#"<feed xmlns="http://www.w3.org/2005/Atom"><link href="https://example.com/"/>
<entry><link rel="alternate" href="https://example.com/c"/><link rel="edit" href="https://example.com/edit/c"/></entry>
<entry><link href="https://example.com/d"></link></entry></feed>"#,
(&["https://example.com/c", "https://example.com/d"], &[]),
),
(
b"\xef\xbb\xbfhttps://example.com/e\r\n\n http://example.com/f \nnot a url\n",
(&["https://example.com/e", "http://example.com/f"], &[]),
),
(
br#"<sm:urlset xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9"><sm:url><sm:loc>https://example.com/p</sm:loc></sm:url></sm:urlset>"#,
(&["https://example.com/p"], &[]),
),
(
br#"<sitemapindex><sitemap><loc>
https://example.com/s1.xml
</loc><lastmod>2024-01-01</lastmod></sitemap><sitemap><loc>https://example.com/s2.xml</loc></sitemap></sitemapindex>"#,
(&[], &["https://example.com/s1.xml", "https://example.com/s2.xml"]),
),
(
br#"<urlset><url><loc> </loc></url><url><loc></loc></url><url><loc>https://example.com/x</loc></url></urlset>"#,
(&["https://example.com/x"], &[]),
),
(
br#"<urlset><url><loc>https://example.com/?a=1&b=2 </loc></url></urlset>"#,
(&["https://example.com/?a=1&b=2"], &[]),
),
(
br#"<urlset xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
<url><loc>https://example.com/en</loc><xhtml:link rel="alternate" hreflang="de" href="https://example.com/de"/></url>
<url><loc>https://example.com/v</loc><video:video><video:content_loc>https://example.com/v.mp4</video:content_loc><video:player_loc>https://example.com/player</video:player_loc></video:video></url>
<url><loc>https://example.com/n</loc><news:news><news:title>T</news:title></news:news></url></urlset>"#,
(
&[
"https://example.com/en",
"https://example.com/v",
"https://example.com/n",
],
&[],
),
),
(
br#"<urlset xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"><url><loc>https://example.com/page</loc><image:image><image:loc>https://example.com/img.jpg</image:loc></image:image></url></urlset>"#,
(&["https://example.com/page"], &[]),
),
(
br#"<sm:urlset xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"><sm:url><image:image><image:loc>https://example.com/a.png</image:loc></image:image><sm:loc>https://example.com/p</sm:loc></sm:url></sm:urlset>"#,
(&["https://example.com/p"], &[]),
),
(
br#"<urlset><loc>https://example.com/bare</loc></urlset>"#,
(&["https://example.com/bare"], &[]),
),
(
b"\xef\xbb\xbf<urlset><url><loc>https://example.com/bom</loc></url></urlset>",
(&["https://example.com/bom"], &[]),
),
(
b"\n <?xml version=\"1.0\"?>\n<urlset><url><loc>https://example.com/ws</loc></url></urlset>",
(&["https://example.com/ws"], &[]),
),
(
br#"<urlset><url><loc>https://example.com/1</loc></url><url><loc>https://example.com/2</loc></bad></urlset>"#,
(&["https://example.com/1", "https://example.com/2"], &[]),
),
(
br#"<urlset><url><loc>https://example.com/1</loc></url><url><loc>https://exam"#,
(&["https://example.com/1"], &[]),
),
(
br#"<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/"><channel><link>https://example.com/</link></channel><item rdf:about="https://example.com/r1"><title>R</title><link>https://example.com/r1</link></item></rdf:RDF>"#,
(&["https://example.com/r1"], &[]),
),
(
br#"<feed><entry><link rel="self" href="https://example.com/self"/></entry></feed>"#,
(&[], &[]),
),
(
br#"<feed><entry><link href="https://example.com/q?a=1&b=2"/></entry></feed>"#,
(&["https://example.com/q?a=1&b=2"], &[]),
),
(
br#"<rss><channel><link>https://example.com/</link></channel></rss>"#,
(&[], &[]),
),
(
b"ftp://example.com/x\n# comment\nhttps://example.com/1\n\twww.example.com/2\n",
(&["https://example.com/1"], &[]),
),
(b"", (&[], &[])),
];
let mut failures = Vec::new();
for (i, (input, (pages, children))) in CASES.iter().enumerate() {
let got = parse_sitemap(input);
if got.0 != *pages || got.1 != *children {
failures.push(format!(
" #{i} 输入 = {:?}\n 期望 = ({pages:?}, {children:?})\n 实际 = {got:?}",
String::from_utf8_lossy(input)
));
}
}
assert!(
failures.is_empty(),
"parse_sitemap:{} / {} 条用例失败\n{}",
failures.len(),
CASES.len(),
failures.join("\n")
);
}