// // OPMLTests.swift // RSParser // // Created by Brent Simmons on 6/25/17. // Copyright © 2017 Ranchero Software, LLC. All rights reserved. // import XCTest import SAX @testable import OPMLParser class OPMLTests: XCTestCase { let subsData = parserData("Subs", "opml", "http://example.org/") func testOPMLParsingPerformance() { // 0.003 sec on my M1 Mac Studio 2022 self.measure { let _ = OPMLParser.document(with: self.subsData) } } func testNotOPML() { let d = parserData("DaringFireball", "rss", "http://daringfireball.net/") XCTAssertNil(OPMLParser.document(with: d)) } func testSubsStructure() { let opmlDocument = OPMLParser.document(with: subsData) XCTAssertNotNil(opmlDocument) XCTAssertEqual("Subs", opmlDocument!.title) XCTAssertEqual("http://example.org/", opmlDocument!.url) recursivelyCheckOPMLStructure(opmlDocument!) } func testFindingTitles() { // https://github.com/brentsimmons/NetNewsWire/issues/527 // Fix a bug where titles aren’t found when there’s no title attribute in the OPML, // which appears to be true with OPML generated by The Old Reader. let d = parserData("SubsNoTitleAttributes", "opml", "http://example.org/") let opmlDocument = OPMLParser.document(with: d) recursivelyCheckOPMLStructure(opmlDocument!) } } private extension OPMLTests { func recursivelyCheckOPMLStructure(_ item: OPMLItem) { let feedSpecifier = item.feedSpecifier if !(item is OPMLDocument) { XCTAssertNotNil(item.attributes!.opml_text) } // If it has no children, it should have a feed specifier. The converse is also true. var isFolder = item.items != nil && item.items!.count > 0 if !isFolder && item.attributes?.opml_title == "Skip" { isFolder = true } if !isFolder { XCTAssertNotNil(feedSpecifier!.title) XCTAssertNotNil(feedSpecifier!.feedURL) } else { XCTAssertNil(feedSpecifier) } if item.items != nil && item.items!.count > 0 { for oneItem in item.items! { recursivelyCheckOPMLStructure(oneItem) } } } } func parserData(_ filename: String, _ fileExtension: String, _ url: String) -> ParserData { let filename = "Resources/\(filename)" let path = Bundle.module.path(forResource: filename, ofType: fileExtension)! let data = try! Data(contentsOf: URL(fileURLWithPath: path)) return ParserData(url: url, data: data) }