From 72ba1274a434fcee2fdc71601511c6a2b8cc9bb8 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 18 May 2024 19:02:36 -0700 Subject: [PATCH] Fix ParserTests. --- ...5AEA6FC6-AD2F-413E-9746-2017D27E25CE.plist | 42 ++++++++++++++ .../ParserTests.xcbaseline/Info.plist | 33 +++++++++++ Parser/Sources/Swift/Feeds/FeedParser.swift | 25 +++++++++ .../Tests/ParserTests/AtomParserTests.swift | 20 +++---- .../ParserTests/JSONFeedParserTests.swift | 34 +++++------ .../ParserTests/RSSInJSONParserTests.swift | 4 +- Parser/Tests/ParserTests/RSSParserTests.swift | 56 ++++++++++--------- 7 files changed, 159 insertions(+), 55 deletions(-) create mode 100644 Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/5AEA6FC6-AD2F-413E-9746-2017D27E25CE.plist create mode 100644 Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/Info.plist diff --git a/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/5AEA6FC6-AD2F-413E-9746-2017D27E25CE.plist b/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/5AEA6FC6-AD2F-413E-9746-2017D27E25CE.plist new file mode 100644 index 000000000..6f7946947 --- /dev/null +++ b/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/5AEA6FC6-AD2F-413E-9746-2017D27E25CE.plist @@ -0,0 +1,42 @@ + + + + + classNames + + RSSParserTests + + testEMarleyPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.000357 + baselineIntegrationDisplayName + Local Baseline + + + testKatieFloydPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.000964 + baselineIntegrationDisplayName + Local Baseline + + + testScriptingNewsPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.001750 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/Info.plist b/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/Info.plist new file mode 100644 index 000000000..762b35539 --- /dev/null +++ b/Parser/.swiftpm/xcode/xcshareddata/xcbaselines/ParserTests.xcbaseline/Info.plist @@ -0,0 +1,33 @@ + + + + + runDestinationsByUUID + + 5AEA6FC6-AD2F-413E-9746-2017D27E25CE + + localComputer + + busSpeedInMHz + 0 + cpuCount + 1 + cpuKind + Apple M1 Max + cpuSpeedInMHz + 0 + logicalCPUCoresPerPackage + 10 + modelCode + Mac13,1 + physicalCPUCoresPerPackage + 10 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + arm64e + + + + diff --git a/Parser/Sources/Swift/Feeds/FeedParser.swift b/Parser/Sources/Swift/Feeds/FeedParser.swift index adf859a26..4c5eb3338 100644 --- a/Parser/Sources/Swift/Feeds/FeedParser.swift +++ b/Parser/Sources/Swift/Feeds/FeedParser.swift @@ -48,4 +48,29 @@ public struct FeedParser { return nil } } + + /// For unit tests measuring performance. + public static func parseSync(_ parserData: ParserData) throws -> ParsedFeed? { + + let type = feedType(parserData) + + switch type { + + case .jsonFeed: + return try JSONFeedParser.parse(parserData) + + case .rssInJSON: + return try RSSInJSONParser.parse(parserData) + + case .rss: + return RSSParser.parse(parserData) + + case .atom: + return AtomParser.parse(parserData) + + case .unknown, .notAFeed: + return nil + } + } + } diff --git a/Parser/Tests/ParserTests/AtomParserTests.swift b/Parser/Tests/ParserTests/AtomParserTests.swift index 500f78c29..dc9fb89d9 100644 --- a/Parser/Tests/ParserTests/AtomParserTests.swift +++ b/Parser/Tests/ParserTests/AtomParserTests.swift @@ -16,7 +16,7 @@ class AtomParserTests: XCTestCase { // 0.009 sec on my 2012 iMac. let d = parserData("DaringFireball", "atom", "http://daringfireball.net/") //It’s actually an Atom feed self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } @@ -25,22 +25,22 @@ class AtomParserTests: XCTestCase { // 0.003 sec on my 2012 iMac. let d = parserData("allthis", "atom", "http://leancrew.com/all-this") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } - func testGettingHomePageLink() { + func testGettingHomePageLink() async { let d = parserData("allthis", "atom", "http://leancrew.com/all-this") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertTrue(parsedFeed.homePageURL == "http://leancrew.com/all-this") } - func testDaringFireball() { + func testDaringFireball() async { let d = parserData("DaringFireball", "atom", "http://daringfireball.net/") //It’s actually an Atom feed - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { @@ -65,12 +65,12 @@ class AtomParserTests: XCTestCase { } } - func test4fsodonlineAttachments() { + func test4fsodonlineAttachments() async { // Thanks to Marco for finding me some Atom podcast feeds. Apparently they’re super-rare. let d = parserData("4fsodonline", "atom", "http://4fsodonline.blogspot.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { @@ -83,12 +83,12 @@ class AtomParserTests: XCTestCase { } } - func testExpertOpinionENTAttachments() { + func testExpertOpinionENTAttachments() async { // Another from Marco. let d = parserData("expertopinionent", "atom", "http://expertopinionent.typepad.com/my-blog/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { diff --git a/Parser/Tests/ParserTests/JSONFeedParserTests.swift b/Parser/Tests/ParserTests/JSONFeedParserTests.swift index 547fe646c..fc3af8e5e 100644 --- a/Parser/Tests/ParserTests/JSONFeedParserTests.swift +++ b/Parser/Tests/ParserTests/JSONFeedParserTests.swift @@ -16,7 +16,7 @@ class JSONFeedParserTests: XCTestCase { // 0.001 sec on my 2012 iMac. let d = parserData("inessential", "json", "http://inessential.com/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } @@ -25,31 +25,31 @@ class JSONFeedParserTests: XCTestCase { // 0.009 sec on my 2012 iMac. let d = parserData("DaringFireball", "json", "http://daringfireball.net/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } - func testGettingFaviconAndIconURLs() { + func testGettingFaviconAndIconURLs() async { let d = parserData("DaringFireball", "json", "http://daringfireball.net/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssert(parsedFeed.faviconURL == "https://daringfireball.net/graphics/favicon-64.png") XCTAssert(parsedFeed.iconURL == "https://daringfireball.net/graphics/apple-touch-icon.png") } - func testAllThis() { + func testAllThis() async { let d = parserData("allthis", "json", "http://leancrew.com/allthis/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 12) } - func testCurt() { - + func testCurt() async { + let d = parserData("curt", "json", "http://curtclifton.net/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 26) @@ -64,23 +64,23 @@ class JSONFeedParserTests: XCTestCase { XCTAssertTrue(didFindTwitterQuitterArticle) } - func testPixelEnvy() { + func testPixelEnvy() async { let d = parserData("pxlnv", "json", "http://pxlnv.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 20) } - func testRose() { + func testRose() async { let d = parserData("rose", "json", "http://www.rosemaryorchard.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 84) } - func test3960() { + func test3960() async { let d = parserData("3960", "json", "http://journal.3960.org/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 20) XCTAssertEqual(parsedFeed.language, "de-DE") @@ -89,9 +89,9 @@ class JSONFeedParserTests: XCTestCase { } } - func testAuthors() { + func testAuthors() async { let d = parserData("authors", "json", "https://example.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 4) let rootAuthors = Set([ diff --git a/Parser/Tests/ParserTests/RSSInJSONParserTests.swift b/Parser/Tests/ParserTests/RSSInJSONParserTests.swift index c34fcd933..cbfce4d13 100644 --- a/Parser/Tests/ParserTests/RSSInJSONParserTests.swift +++ b/Parser/Tests/ParserTests/RSSInJSONParserTests.swift @@ -16,13 +16,13 @@ class RSSInJSONParserTests: XCTestCase { // 0.003 sec on my 2012 iMac. let d = parserData("ScriptingNews", "json", "http://scripting.com/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } func testFeedLanguage() { let d = parserData("ScriptingNews", "json", "http://scripting.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! FeedParser.parseSync(d)! XCTAssertEqual(parsedFeed.language, "en-us") } } diff --git a/Parser/Tests/ParserTests/RSSParserTests.swift b/Parser/Tests/ParserTests/RSSParserTests.swift index 48cfadc77..c60229ca3 100644 --- a/Parser/Tests/ParserTests/RSSParserTests.swift +++ b/Parser/Tests/ParserTests/RSSParserTests.swift @@ -14,50 +14,54 @@ class RSSParserTests: XCTestCase { func testScriptingNewsPerformance() { // 0.004 sec on my 2012 iMac. + // 0.002 2022 Mac Studio let d = parserData("scriptingNews", "rss", "http://scripting.com/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } func testKatieFloydPerformance() { // 0.004 sec on my 2012 iMac. + // 0.001 2022 Mac Studio let d = parserData("KatieFloyd", "rss", "http://katiefloyd.com/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } func testEMarleyPerformance() { // 0.001 sec on my 2012 iMac. + // 0.0004 2022 Mac Studio let d = parserData("EMarley", "rss", "https://medium.com/@emarley") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } func testMantonPerformance() { // 0.002 sec on my 2012 iMac. + // 0.0006 2022 Mac Studio let d = parserData("manton", "rss", "http://manton.org/") self.measure { - let _ = try! FeedParser.parse(d) + let _ = try! FeedParser.parseSync(d) } } - func testNatashaTheRobot() { + func testNatashaTheRobot() async { let d = parserData("natasha", "xml", "https://www.natashatherobot.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.items.count, 10) } - func testTheOmniShowAttachments() { + func testTheOmniShowAttachments() async { let d = parserData("theomnishow", "rss", "https://theomnishow.omnigroup.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotNil(article.attachments) @@ -71,10 +75,10 @@ class RSSParserTests: XCTestCase { } } - func testTheOmniShowUniqueIDs() { + func testTheOmniShowUniqueIDs() async { let d = parserData("theomnishow", "rss", "https://theomnishow.omnigroup.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotNil(article.uniqueID) @@ -82,12 +86,12 @@ class RSSParserTests: XCTestCase { } } - func testMacworldUniqueIDs() { + func testMacworldUniqueIDs() async { // Macworld’s feed doesn’t have guids, so they should be calculated unique IDs. let d = parserData("macworld", "rss", "https://www.macworld.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotNil(article.uniqueID) @@ -95,12 +99,12 @@ class RSSParserTests: XCTestCase { } } - func testMacworldAuthors() { + func testMacworldAuthors() async { // Macworld uses names instead of email addresses (despite the RSS spec saying they should be email addresses). let d = parserData("macworld", "rss", "https://www.macworld.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { @@ -111,7 +115,7 @@ class RSSParserTests: XCTestCase { } } - func testMonkeyDomGuids() { + func testMonkeyDomGuids() async { // https://coding.monkeydom.de/posts.rss has a bug in the feed (at this writing): // It has guids that are supposed to be permalinks, per the spec — @@ -119,7 +123,7 @@ class RSSParserTests: XCTestCase { // detect this situation, and every article in the feed should have a permalink. let d = parserData("monkeydom", "rss", "https://coding.monkeydom.de/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNil(article.url) @@ -127,31 +131,31 @@ class RSSParserTests: XCTestCase { } } - func testEmptyContentEncoded() { + func testEmptyContentEncoded() async { // The ATP feed (at the time of this writing) has some empty content:encoded elements. The parser should ignore those. // https://github.com/brentsimmons/NetNewsWire/issues/529 let d = parserData("atp", "rss", "http://atp.fm/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotNil(article.contentHTML) } } - func testFeedKnownToHaveGuidsThatArentPermalinks() { + func testFeedKnownToHaveGuidsThatArentPermalinks() async { let d = parserData("livemint", "xml", "https://www.livemint.com/rss/news") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNil(article.url) } } - func testAuthorsWithTitlesInside() { + func testAuthorsWithTitlesInside() async { // This feed uses atom authors, and we don’t want author/title to be used as item/title. // https://github.com/brentsimmons/NetNewsWire/issues/943 let d = parserData("cloudblog", "rss", "https://cloudblog.withgoogle.com/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotEqual(article.title, "Product Manager, Office of the CTO") XCTAssertNotEqual(article.title, "Developer Programs Engineer") @@ -159,19 +163,19 @@ class RSSParserTests: XCTestCase { } } - func testTitlesWithInvalidFeedWithImageStructures() { + func testTitlesWithInvalidFeedWithImageStructures() async { // This invalid feed has elements inside s. // 17 Jan 2021 bug report — we’re not parsing titles in this feed. let d = parserData("aktuality", "rss", "https://www.aktuality.sk/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! for article in parsedFeed.items { XCTAssertNotNil(article.title) } } - func testFeedLanguage() { + func testFeedLanguage() async { let d = parserData("manton", "rss", "http://manton.org/") - let parsedFeed = try! FeedParser.parse(d)! + let parsedFeed = try! await FeedParser.parse(d)! XCTAssertEqual(parsedFeed.language, "en-US") }