Skip to content

Commit 89c719e

Browse files
committed
test: improve test coverage to 83.78%
Add comprehensive unit tests for Atom and RSS parsers to improve overall test coverage from 62.28% to 83.78%. Atom parser tests (parser/atom.rs): - Categories and tags parsing - Generator metadata with URI and version - Icon and logo URLs - Rights/copyright information - Contributors (multiple authors) - Entry summaries and published dates - Source feeds - Multiple links with different rel types - XHTML content type - Entry limits enforcement - Malformed XML tolerance (bozo flag) - Empty/self-closing elements RSS parser tests (parser/rss.rs): - Image metadata (URL, title, dimensions) - Author information - Comments URL - GUID with permalink attribute - TTL (time to live) - Language codes - Generator field - Entry limits - Multiple categories at feed level - Source feeds with title and URL - Empty elements handling - Nesting depth limits - Skipping unsupported elements Coverage improvements: - parser/atom.rs: 56.67% → 78.31% (+21.64%) - parser/rss.rs: 54.67% → 67.46% (+12.79%) - Overall: 62.28% → 83.78% (+21.5%)
1 parent fd5db4f commit 89c719e

File tree

2 files changed

+413
-0
lines changed

2 files changed

+413
-0
lines changed

crates/feedparser-rs-core/src/parser/atom.rs

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,4 +736,208 @@ mod tests {
736736
assert_eq!(feed.entries[0].content.len(), 1);
737737
assert!(feed.entries[0].content[0].value.contains("Content"));
738738
}
739+
740+
#[test]
741+
fn test_parse_atom_with_categories() {
742+
let xml = br#"<?xml version="1.0"?>
743+
<feed xmlns="http://www.w3.org/2005/Atom">
744+
<title>Test</title>
745+
<category term="technology" scheme="http://example.com/categories" label="Tech"/>
746+
<category term="news"/>
747+
</feed>"#;
748+
749+
let feed = parse_atom10(xml).unwrap();
750+
assert_eq!(feed.feed.tags.len(), 2);
751+
assert_eq!(feed.feed.tags[0].term, "technology");
752+
assert_eq!(feed.feed.tags[0].label.as_deref(), Some("Tech"));
753+
}
754+
755+
#[test]
756+
fn test_parse_atom_with_generator() {
757+
let xml = br#"<?xml version="1.0"?>
758+
<feed xmlns="http://www.w3.org/2005/Atom">
759+
<title>Test</title>
760+
<generator uri="http://example.com/" version="1.0">Example CMS</generator>
761+
</feed>"#;
762+
763+
let feed = parse_atom10(xml).unwrap();
764+
assert!(feed.feed.generator_detail.is_some());
765+
let generator_detail = feed.feed.generator_detail.as_ref().unwrap();
766+
assert_eq!(generator_detail.uri.as_deref(), Some("http://example.com/"));
767+
assert_eq!(generator_detail.version.as_deref(), Some("1.0"));
768+
}
769+
770+
#[test]
771+
fn test_parse_atom_with_icon_and_logo() {
772+
let xml = br#"<?xml version="1.0"?>
773+
<feed xmlns="http://www.w3.org/2005/Atom">
774+
<icon>http://example.com/icon.png</icon>
775+
<logo>http://example.com/logo.png</logo>
776+
</feed>"#;
777+
778+
let feed = parse_atom10(xml).unwrap();
779+
assert_eq!(feed.feed.icon.as_deref(), Some("http://example.com/icon.png"));
780+
assert_eq!(feed.feed.logo.as_deref(), Some("http://example.com/logo.png"));
781+
}
782+
783+
#[test]
784+
fn test_parse_atom_with_rights() {
785+
let xml = br#"<?xml version="1.0"?>
786+
<feed xmlns="http://www.w3.org/2005/Atom">
787+
<rights type="html">&lt;p&gt;Copyright 2024&lt;/p&gt;</rights>
788+
</feed>"#;
789+
790+
let feed = parse_atom10(xml).unwrap();
791+
assert!(feed.feed.rights.is_some());
792+
assert!(feed.feed.rights_detail.is_some());
793+
}
794+
795+
#[test]
796+
fn test_parse_atom_with_contributors() {
797+
let xml = br#"<?xml version="1.0"?>
798+
<feed xmlns="http://www.w3.org/2005/Atom">
799+
<contributor>
800+
<name>Jane Doe</name>
801+
<email>[email protected]</email>
802+
</contributor>
803+
<contributor>
804+
<name>Bob Smith</name>
805+
</contributor>
806+
</feed>"#;
807+
808+
let feed = parse_atom10(xml).unwrap();
809+
assert_eq!(feed.feed.contributors.len(), 2);
810+
assert_eq!(feed.feed.contributors[0].name.as_deref(), Some("Jane Doe"));
811+
}
812+
813+
#[test]
814+
fn test_parse_atom_entry_with_summary() {
815+
let xml = br#"<?xml version="1.0"?>
816+
<feed xmlns="http://www.w3.org/2005/Atom">
817+
<entry>
818+
<title>Entry</title>
819+
<id>test</id>
820+
<updated>2024-12-14T09:00:00Z</updated>
821+
<summary type="text">This is a summary</summary>
822+
</entry>
823+
</feed>"#;
824+
825+
let feed = parse_atom10(xml).unwrap();
826+
assert_eq!(feed.entries[0].summary.as_deref(), Some("This is a summary"));
827+
assert!(feed.entries[0].summary_detail.is_some());
828+
}
829+
830+
#[test]
831+
fn test_parse_atom_entry_with_published() {
832+
let xml = br#"<?xml version="1.0"?>
833+
<feed xmlns="http://www.w3.org/2005/Atom">
834+
<entry>
835+
<title>Entry</title>
836+
<id>test</id>
837+
<updated>2024-12-14T09:00:00Z</updated>
838+
<published>2024-12-13T09:00:00Z</published>
839+
</entry>
840+
</feed>"#;
841+
842+
let feed = parse_atom10(xml).unwrap();
843+
assert!(feed.entries[0].published.is_some());
844+
assert!(feed.entries[0].updated.is_some());
845+
}
846+
847+
#[test]
848+
fn test_parse_atom_entry_with_source() {
849+
let xml = br#"<?xml version="1.0"?>
850+
<feed xmlns="http://www.w3.org/2005/Atom">
851+
<entry>
852+
<title>Entry</title>
853+
<id>test</id>
854+
<updated>2024-12-14T09:00:00Z</updated>
855+
<source>
856+
<title>Source Feed</title>
857+
<id>source-id</id>
858+
<link href="http://source.example.com"/>
859+
</source>
860+
</entry>
861+
</feed>"#;
862+
863+
let feed = parse_atom10(xml).unwrap();
864+
assert!(feed.entries[0].source.is_some());
865+
let source = feed.entries[0].source.as_ref().unwrap();
866+
assert_eq!(source.title.as_deref(), Some("Source Feed"));
867+
assert_eq!(source.id.as_deref(), Some("source-id"));
868+
}
869+
870+
#[test]
871+
fn test_parse_atom_multiple_links() {
872+
let xml = br#"<?xml version="1.0"?>
873+
<feed xmlns="http://www.w3.org/2005/Atom">
874+
<link href="http://example.com/" rel="alternate"/>
875+
<link href="http://example.com/feed" rel="self"/>
876+
<link href="http://example.com/related" rel="related"/>
877+
</feed>"#;
878+
879+
let feed = parse_atom10(xml).unwrap();
880+
assert_eq!(feed.feed.links.len(), 3);
881+
assert_eq!(feed.feed.link.as_deref(), Some("http://example.com/"));
882+
}
883+
884+
#[test]
885+
fn test_parse_atom_xhtml_content() {
886+
let xml = br#"<?xml version="1.0"?>
887+
<feed xmlns="http://www.w3.org/2005/Atom">
888+
<title type="xhtml">
889+
<div xmlns="http://www.w3.org/1999/xhtml">XHTML Title</div>
890+
</title>
891+
</feed>"#;
892+
893+
let feed = parse_atom10(xml).unwrap();
894+
assert_eq!(
895+
feed.feed.title_detail.as_ref().unwrap().content_type,
896+
TextType::Xhtml
897+
);
898+
}
899+
900+
#[test]
901+
fn test_parse_atom_with_limits_exceeded() {
902+
let xml = br#"<?xml version="1.0"?>
903+
<feed xmlns="http://www.w3.org/2005/Atom">
904+
<entry><title>E1</title><id>1</id><updated>2024-01-01T00:00:00Z</updated></entry>
905+
<entry><title>E2</title><id>2</id><updated>2024-01-01T00:00:00Z</updated></entry>
906+
<entry><title>E3</title><id>3</id><updated>2024-01-01T00:00:00Z</updated></entry>
907+
</feed>"#;
908+
909+
let limits = ParserLimits {
910+
max_entries: 2,
911+
..Default::default()
912+
};
913+
let feed = parse_atom10_with_limits(xml, limits).unwrap();
914+
assert_eq!(feed.entries.len(), 2);
915+
}
916+
917+
#[test]
918+
fn test_parse_atom_malformed_continues() {
919+
let xml = br#"<?xml version="1.0"?>
920+
<feed xmlns="http://www.w3.org/2005/Atom">
921+
<title>Valid Title</title>
922+
<invalid_tag>
923+
<nested>broken
924+
</feed>"#;
925+
926+
let feed = parse_atom10(xml).unwrap();
927+
assert!(feed.bozo);
928+
assert!(feed.feed.title.is_some());
929+
}
930+
931+
#[test]
932+
fn test_parse_atom_empty_elements() {
933+
let xml = br#"<?xml version="1.0"?>
934+
<feed xmlns="http://www.w3.org/2005/Atom">
935+
<link href="http://example.com/"/>
936+
<category term="test"/>
937+
</feed>"#;
938+
939+
let feed = parse_atom10(xml).unwrap();
940+
assert_eq!(feed.feed.links.len(), 1);
941+
assert_eq!(feed.feed.tags.len(), 1);
942+
}
739943
}

0 commit comments

Comments
 (0)