use sitemap_xml_writer::{Changefreq, Lastmod, Loc, Priority, SitemapWriter, Url}; use std::io::Cursor; #[test] fn test_sitemap_writer_start_with_indent() -> anyhow::Result<()> { let mut writer = SitemapWriter::start_with_indent(Cursor::new(Vec::new()))?; writer.write("http://www.example.com/")?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = r#" http://www.example.com/ "#; assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_str() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write("http://www.example.com/")?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write( Url::loc("http://www.example.com/")? .lastmod("2005-01-01")? .changefreq("monthly")? .priority("0.8")?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=12&desc=vacation_hawaii")? .changefreq(Changefreq::Monthly)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=73&desc=vacation_new_zealand")? .lastmod("2004-12-23")? .changefreq(Changefreq::Weekly)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=74&desc=vacation_newfoundland")? .lastmod("2004-12-23T18:00:15+00:00")? .priority(0.3)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=83&desc=vacation_usa")? .lastmod("2004-11-23")?, )?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; // Sample XML Sitemap in let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#"monthly"#, r#"0.8"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=12&desc=vacation_hawaii"#, r#"monthly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=73&desc=vacation_new_zealand"#, r#"2004-12-23"#, r#"weekly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=74&desc=vacation_newfoundland"#, r#"2004-12-23T18:00:15+00:00"#, r#"0.3"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=83&desc=vacation_usa"#, r#"2004-11-23"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[cfg(feature = "url")] #[test] fn test_sitemap_writer_write_url_with_url_feature() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write( Url::loc("http://www.example.com/")? .lastmod("2005-01-01")? .changefreq("monthly")? .priority("0.8")?, )?; writer.write( // support // If you want to ensure that the URL is Valid, use `::url::Url`. // If you use &str, the URL is assumed to be valid and only the length check and XML entity escaping are performed. Url::loc(::url::Url::parse( "http://www.example.com/catalog?item=12&desc=vacation_hawaii", )?)? .changefreq(Changefreq::Monthly)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=73&desc=vacation_new_zealand")? .lastmod("2004-12-23")? .changefreq(Changefreq::Weekly)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=74&desc=vacation_newfoundland")? .lastmod("2004-12-23T18:00:15+00:00")? .priority(0.3)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=83&desc=vacation_usa")? .lastmod("2004-11-23")?, )?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; // Sample XML Sitemap in let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#"monthly"#, r#"0.8"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=12&desc=vacation_hawaii"#, r#"monthly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=73&desc=vacation_new_zealand"#, r#"2004-12-23"#, r#"weekly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=74&desc=vacation_newfoundland"#, r#"2004-12-23T18:00:15+00:00"#, r#"0.3"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=83&desc=vacation_usa"#, r#"2004-11-23"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[cfg(feature = "chrono")] #[test] fn test_sitemap_writer_write_url_with_chrono_feature() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write( Url::loc("http://www.example.com/")? .lastmod("2005-01-01")? .changefreq("monthly")? .priority("0.8")?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=12&desc=vacation_hawaii")? .changefreq(Changefreq::Monthly)?, )?; #[rustfmt::skip] writer.write( Url::loc("http://www.example.com/catalog?item=73&desc=vacation_new_zealand")? // `::chrono::NaiveDate` support .lastmod(::chrono::NaiveDate::parse_from_str("2004-12-23", "%Y-%m-%d")?)? .changefreq(Changefreq::Weekly)? )?; writer.write( Url::loc("http://www.example.com/catalog?item=74&desc=vacation_newfoundland")? // `::chrono::DateTime` support .lastmod(::chrono::DateTime::parse_from_rfc3339( "2004-12-23T18:00:15+00:00", )?)? .priority(0.3)?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=83&desc=vacation_usa")? .lastmod("2004-11-23")?, )?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; // Sample XML Sitemap in let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#"monthly"#, r#"0.8"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=12&desc=vacation_hawaii"#, r#"monthly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=73&desc=vacation_new_zealand"#, r#"2004-12-23"#, r#"weekly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=74&desc=vacation_newfoundland"#, r#"2004-12-23T18:00:15+00:00"#, r#"0.3"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=83&desc=vacation_usa"#, r#"2004-11-23"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[cfg(feature = "time")] #[test] fn test_sitemap_writer_write_url_with_time_feature() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write( Url::loc("http://www.example.com/")? .lastmod("2005-01-01")? .changefreq("monthly")? .priority("0.8")?, )?; writer.write( Url::loc("http://www.example.com/catalog?item=12&desc=vacation_hawaii")? .changefreq(Changefreq::Monthly)?, )?; #[rustfmt::skip] writer.write( Url::loc("http://www.example.com/catalog?item=73&desc=vacation_new_zealand")? // `::time::Date` support .lastmod(::time::macros::date!(2004-12-23))? .changefreq(Changefreq::Weekly)? )?; #[rustfmt::skip] writer.write( Url::loc("http://www.example.com/catalog?item=74&desc=vacation_newfoundland")? // `::time::OffsetDateTime` support .lastmod(::time::macros::datetime!(2004-12-23 18:00:15 +00:00))? .priority(0.3)? )?; writer.write( Url::loc("http://www.example.com/catalog?item=83&desc=vacation_usa")? .lastmod("2004-11-23")?, )?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; // Sample XML Sitemap in let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#"monthly"#, r#"0.8"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=12&desc=vacation_hawaii"#, r#"monthly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=73&desc=vacation_new_zealand"#, r#"2004-12-23"#, r#"weekly"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=74&desc=vacation_newfoundland"#, // r#"2004-12-23T18:00:15+00:00"#, r#"2004-12-23T18:00:15.000000000Z"#, r#"0.3"#, r#""#, r#""#, r#"http://www.example.com/catalog?item=83&desc=vacation_usa"#, r#"2004-11-23"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url_typed() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write( Url::loc(Loc::try_from("http://www.example.com/")?)? .lastmod(Lastmod::try_from("2005-01-01")?)? .changefreq(Changefreq::try_from("monthly")?)? .priority(Priority::try_from("0.8")?)?, )?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#"monthly"#, r#"0.8"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url_loc() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write(Url::loc("http://www.example.com/")?)?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url_lastmod() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write(Url::loc("http://www.example.com/")?.lastmod("2005-01-01")?)?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"2005-01-01"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url_changefreq() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write(Url::loc("http://www.example.com/")?.changefreq("monthly")?)?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"monthly"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_write_url_priority() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; writer.write(Url::loc("http://www.example.com/")?.priority("0.8")?)?; writer.end()?; let actual = String::from_utf8(writer.into_inner().into_inner())?; let expected = concat!( r#""#, r#""#, r#""#, r#"http://www.example.com/"#, r#"0.8"#, r#""#, r#""# ); assert_eq!(actual, expected); Ok(()) } #[test] fn test_sitemap_writer_max_byte_length() -> anyhow::Result<()> { let head_and_tail_length = concat!( r#""#, r#""#, r#""# ) .len(); let url = format!("http://www.example.com/{}", "x".repeat(1035)); let url_length = format!(r#"{}"#, url).len(); let url2 = format!("http://www.example.com/{}", "x".repeat(48)); let url2_length = format!(r#"{}"#, url2).len(); let url3 = format!("http://www.example.com/{}", "x".repeat(49)); let url3_length = format!(r#"{}"#, url3).len(); assert_eq!(head_and_tail_length, 107); assert_eq!(url_length, 1_080); assert_eq!(url2_length, 93); assert_eq!(url3_length, 94); // 107 + 1_080 * 48_545 = 52_428_707 // MAX_BYTE_LENGTH = 52_428_800 // 52_428_800 - 52_428_707 = 93 let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; for _ in 0..48_545 { writer.write(url.as_str())?; } writer.write(url2.as_str())?; writer.end()?; let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; for _ in 0..48_545 { writer.write(url.as_str())?; } writer.write(url3.as_str())?; assert!(writer.end().is_err()); Ok(()) } #[test] fn test_sitemap_writer_max_number_of_urls() -> anyhow::Result<()> { let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; for _ in 0..50_000 { writer.write("http://www.example.com/")?; } writer.end()?; let mut writer = SitemapWriter::start(Cursor::new(Vec::new()))?; for _ in 0..50_000 { writer.write("http://www.example.com/")?; } assert!(writer.write("http://www.example.com/").is_err()); writer.end()?; Ok(()) }