diff --git a/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/HTMLParserTests.xcscheme b/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/HTMLParserTests.xcscheme new file mode 100644 index 000000000..64ea056f7 --- /dev/null +++ b/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/HTMLParserTests.xcscheme @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/Parser-Package.xcscheme b/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/Parser-Package.xcscheme index 416ab7fe7..f37cf2377 100644 --- a/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/Parser-Package.xcscheme +++ b/Modules/Parser/.swiftpm/xcode/xcshareddata/xcschemes/Parser-Package.xcscheme @@ -126,6 +126,16 @@ ReferencedContainer = "container:"> + + + + [HTMLLink] { + public static func htmlLinks(with parserData: ParserData) -> [HTMLLink] { let parser = HTMLLinkParser(parserData) parser.parse() @@ -38,23 +38,23 @@ private extension HTMLLinkParser { } } -private extension HTMLLinkParser: SAXHTMLParserDelegate { +extension HTMLLinkParser: SAXHTMLParserDelegate { - var currentLink: HTMLLink? { + private var currentLink: HTMLLink? { links.last } - struct HTMLAttributeName { - let href = "href" - let title = "title" + private struct HTMLAttributeName { + static let href = "href" + static let title = "title" } - func title(_ attributesDictionary: HTMLAttributesDictionary) -> String? { + private func title(with attributesDictionary: SAXHTMLParser.HTMLAttributesDictionary) -> String? { - attributesDictionary.object(object(forCaseInsensitiveKey: HTMLAttributeName.title)) + attributesDictionary.object(forCaseInsensitiveKey: HTMLAttributeName.title) } - func urlString(_ attributesDictionary: HTMLAttributesDictionary) -> String? { + private func urlString(with attributesDictionary: SAXHTMLParser.HTMLAttributesDictionary) -> String? { guard let href = attributesDictionary.object(forCaseInsensitiveKey: HTMLAttributeName.href) else { return nil @@ -68,22 +68,22 @@ private extension HTMLLinkParser: SAXHTMLParserDelegate { return absoluteURL.absoluteString } - func handleLinkAttributes(_ attributesDictionary: HTMLAttributesDictionary) { + private func handleLinkAttributes(_ attributesDictionary: SAXHTMLParser.HTMLAttributesDictionary) { guard let currentLink else { assertionFailure("currentLink must not be nil") return } - link.urlString = urlString(attributesDictionary) - link.title = title(attributesDictionary) + currentLink.urlString = urlString(with: attributesDictionary) + currentLink.title = title(with: attributesDictionary) } - struct HTMLName { + private struct HTMLName { static let a = "a".utf8CString } - func saxHTMLParser(_ saxHTMLParser: SAXHTMLParser, startElement name: XMLPointer, attributes: UnsafePointer?) { + public func saxHTMLParser(_ saxHTMLParser: SAXHTMLParser, startElement name: XMLPointer, attributes: UnsafePointer?) { guard SAXEqualTags(name, HTMLName.a) else { return @@ -99,15 +99,20 @@ private extension HTMLLinkParser: SAXHTMLParserDelegate { saxHTMLParser.beginStoringCharacters() } - func saxHTMLParser(_ saxHTMLParser: SAXHTMLParser, endElement name: XMLPointer) { + public func saxHTMLParser(_ saxHTMLParser: SAXHTMLParser, endElement name: XMLPointer) { guard SAXEqualTags(name, HTMLName.a) else { return } + guard let currentLink else { + assertionFailure("currentLink must not be nil.") + return + } + currentLink.text = saxHTMLParser.currentStringWithTrimmedWhitespace } - func saxHTMLParser(_: SAXHTMLParser, charactersFound: XMLPointer, count: Int) { + public func saxHTMLParser(_: SAXHTMLParser, charactersFound: XMLPointer, count: Int) { // Nothing needed. } } diff --git a/Modules/Parser/Tests/FeedParserTests/HTMLLinkTests.swift b/Modules/Parser/Tests/FeedParserTests/HTMLLinkTests.swift deleted file mode 100644 index cd39f7847..000000000 --- a/Modules/Parser/Tests/FeedParserTests/HTMLLinkTests.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// HTMLLinkTests.swift -// RSParser -// -// Created by Brent Simmons on 6/25/17. -// Copyright © 2017 Ranchero Software, LLC. All rights reserved. -// - -import XCTest -import FeedParser - -//class HTMLLinkTests: XCTestCase { -// -// func testSixColorsPerformance() { -// -// // 0.003 sec on my 2012 iMac -// let d = parserData("sixcolors", "html", "http://sixcolors.com/") -// self.measure { -// let _ = RSHTMLLinkParser.htmlLinks(with: d) -// } -// } -// -// func testSixColorsLink() { -// -// let d = parserData("sixcolors", "html", "http://sixcolors.com/") -// let links = RSHTMLLinkParser.htmlLinks(with: d) -// -// let linkToFind = "https://www.theincomparable.com/theincomparable/290/index.php" -// let textToFind = "this week’s episode of The Incomparable" -// -// var found = false -// for oneLink in links { -// if let urlString = oneLink.urlString, let text = oneLink.text, urlString == linkToFind, text == textToFind { -// found = true -// } -// } -// -// XCTAssertTrue(found) -// XCTAssertEqual(links.count, 131) -// } -// -//} diff --git a/Modules/Parser/Tests/HTMLParserTests/HTMLLinkTests.swift b/Modules/Parser/Tests/HTMLParserTests/HTMLLinkTests.swift new file mode 100644 index 000000000..be1e03665 --- /dev/null +++ b/Modules/Parser/Tests/HTMLParserTests/HTMLLinkTests.swift @@ -0,0 +1,50 @@ +// +// HTMLLinkTests.swift +// RSParser +// +// Created by Brent Simmons on 6/25/17. +// Copyright © 2017 Ranchero Software, LLC. All rights reserved. +// + +import XCTest +import FeedParser +import HTMLParser +import SAX + +class HTMLLinkTests: XCTestCase { + + func testSixColorsPerformance() { + + // 0.003 sec on my 2012 iMac + let d = parserData("sixcolors", "html", "http://sixcolors.com/") + self.measure { + let _ = HTMLLinkParser.htmlLinks(with: d) + } + } + + func testSixColorsLink() { + + let d = parserData("sixcolors", "html", "http://sixcolors.com/") + let links = HTMLLinkParser.htmlLinks(with: d) + + let linkToFind = "https://www.theincomparable.com/theincomparable/290/index.php" + let textToFind = "this week’s episode of The Incomparable" + + var found = false + for oneLink in links { + if let urlString = oneLink.urlString, let text = oneLink.text, urlString == linkToFind, text == textToFind { + found = true + } + } + + XCTAssertTrue(found) + XCTAssertEqual(links.count, 131) + } +} + +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) +} diff --git a/Modules/Parser/Tests/FeedParserTests/HTMLMetadataTests.swift b/Modules/Parser/Tests/HTMLParserTests/HTMLMetadataTests.swift similarity index 100% rename from Modules/Parser/Tests/FeedParserTests/HTMLMetadataTests.swift rename to Modules/Parser/Tests/HTMLParserTests/HTMLMetadataTests.swift diff --git a/Modules/Parser/Tests/FeedParserTests/Resources/sixcolors.html b/Modules/Parser/Tests/HTMLParserTests/Resources/sixcolors.html similarity index 100% rename from Modules/Parser/Tests/FeedParserTests/Resources/sixcolors.html rename to Modules/Parser/Tests/HTMLParserTests/Resources/sixcolors.html