From 642534ba9e727137f22bc1a92f6b2eb91d6e1c2b Mon Sep 17 00:00:00 2001 From: Vithanco Date: Sun, 23 Jul 2023 06:28:27 +0200 Subject: [PATCH 1/9] Update and rename Attribute.swift to OPMLAttribute.swift need to change name to OPML Attribute to avoid name clash --- Sources/OPML/Models/{Attribute.swift => OPMLAttribute.swift} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename Sources/OPML/Models/{Attribute.swift => OPMLAttribute.swift} (74%) diff --git a/Sources/OPML/Models/Attribute.swift b/Sources/OPML/Models/OPMLAttribute.swift similarity index 74% rename from Sources/OPML/Models/Attribute.swift rename to Sources/OPML/Models/OPMLAttribute.swift index 4e46b12..aaedcda 100644 --- a/Sources/OPML/Models/Attribute.swift +++ b/Sources/OPML/Models/OPMLAttribute.swift @@ -1,4 +1,4 @@ -public struct Attribute: Codable, Hashable { +public struct OPMLAttribute: Codable, Hashable { public let name: String public let value: String From 8b80cb136ce91037a1f7c67217cab1c4a3886cf0 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Sun, 23 Jul 2023 06:29:52 +0200 Subject: [PATCH 2/9] Update OPMLEntry.swift need to change name to avoid clashes --- Sources/OPML/Models/OPMLEntry.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/OPML/Models/OPMLEntry.swift b/Sources/OPML/Models/OPMLEntry.swift index f267179..d7f2208 100644 --- a/Sources/OPML/Models/OPMLEntry.swift +++ b/Sources/OPML/Models/OPMLEntry.swift @@ -4,7 +4,7 @@ public struct OPMLEntry: Codable, Hashable { /// What is displayed when an outliner opens the OPML file. public let text: String - public let attributes: [Attribute]? + public let attributes: [OPMLAttribute]? public let children: [OPMLEntry]? public var title: String? { @@ -21,7 +21,7 @@ public struct OPMLEntry: Codable, Hashable { public init( text: String, - attributes: [Attribute]?, + attributes: [OPMLAttribute]?, children: [OPMLEntry]? = nil ) { self.text = text @@ -33,14 +33,14 @@ public struct OPMLEntry: Codable, Hashable { rss feedURL: URL, siteURL: URL?, title: String, - attributes: [Attribute]? = nil + attributes: [OPMLAttribute]? = nil ) { text = title self.attributes = [ - Attribute(name: "title", value: title), - Attribute(name: "type", value: "rss"), - Attribute(name: "xmlUrl", value: feedURL.absoluteString), - Attribute(name: "htmlUrl", value: siteURL?.absoluteString ?? ""), + OPMLAttribute(name: "title", value: title), + OPMLAttribute(name: "type", value: "rss"), + OPMLAttribute(name: "xmlUrl", value: feedURL.absoluteString), + OPMLAttribute(name: "htmlUrl", value: siteURL?.absoluteString ?? ""), ] + (attributes ?? []) children = nil } From c74cbc52ced259bb662f825df6b22e4d668ba8a5 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Sun, 23 Jul 2023 06:33:41 +0200 Subject: [PATCH 3/9] Update OPMLEntryBuilder.swift changed Attribute to OPMLAttribute --- Sources/OPML/Parser/OPMLEntryBuilder.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/OPML/Parser/OPMLEntryBuilder.swift b/Sources/OPML/Parser/OPMLEntryBuilder.swift index 1c0a2b3..689db1e 100644 --- a/Sources/OPML/Parser/OPMLEntryBuilder.swift +++ b/Sources/OPML/Parser/OPMLEntryBuilder.swift @@ -2,7 +2,7 @@ final class OPMLEntryBuilder { /// What is displayed when an outliner opens the OPML file. var text: String? - var attributes: [Attribute]? + var attributes: [OPMLAttribute]? var children: [OPMLEntryBuilder]? var entry: OPMLEntry? { @@ -10,7 +10,7 @@ final class OPMLEntryBuilder { return OPMLEntry(text: text, attributes: attributes, children: children?.compactMap { $0.entry }) } - init(text: String? = nil, attributes: [Attribute]? = nil, children: [OPMLEntryBuilder]? = nil) { + init(text: String? = nil, attributes: [OPMLAttribute]? = nil, children: [OPMLEntryBuilder]? = nil) { self.text = text self.attributes = attributes self.children = children From c53959726d23aeee0e8d238be18b06226cde2497 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Sun, 23 Jul 2023 06:35:23 +0200 Subject: [PATCH 4/9] Update OPMLParser.swift changed Attribute to OPMLAttribute --- Sources/OPML/Parser/OPMLParser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OPML/Parser/OPMLParser.swift b/Sources/OPML/Parser/OPMLParser.swift index 317813d..c9de39d 100644 --- a/Sources/OPML/Parser/OPMLParser.swift +++ b/Sources/OPML/Parser/OPMLParser.swift @@ -96,7 +96,7 @@ extension OPMLParser: XMLParserDelegate { guard let text = attributes.first(where: { $0.key.lowercased() == "text" })?.value else { return } - let entry = OPMLEntryBuilder(text: text, attributes: attributes.map { Attribute(name: $0.key, value: $0.value) }) + let entry = OPMLEntryBuilder(text: text, attributes: attributes.map { OPMLAttribute(name: $0.key, value: $0.value) }) if let parentEntry = currentOPMLEntry { if parentEntry.children == nil { parentEntry.children = [entry] From 800da4a42764d3aae6c1b28413b435b6e2c8277b Mon Sep 17 00:00:00 2001 From: Vithanco Date: Mon, 24 Jul 2023 00:21:23 +0200 Subject: [PATCH 5/9] making OPMLParser public --- Sources/OPML/Parser/OPMLParser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OPML/Parser/OPMLParser.swift b/Sources/OPML/Parser/OPMLParser.swift index c9de39d..c97633c 100644 --- a/Sources/OPML/Parser/OPMLParser.swift +++ b/Sources/OPML/Parser/OPMLParser.swift @@ -3,7 +3,7 @@ import Foundation import FoundationXML #endif -final class OPMLParser: NSObject { +final public class OPMLParser: NSObject { private let xmlParser: XMLParser From c1d84eacd015ff855e5d2c8893cff3356f0b9fce Mon Sep 17 00:00:00 2001 From: Vithanco Date: Mon, 24 Jul 2023 00:22:59 +0200 Subject: [PATCH 6/9] make OPMLParser public --- Sources/OPML/Parser/OPMLParser.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/OPML/Parser/OPMLParser.swift b/Sources/OPML/Parser/OPMLParser.swift index c97633c..327a23d 100644 --- a/Sources/OPML/Parser/OPMLParser.swift +++ b/Sources/OPML/Parser/OPMLParser.swift @@ -41,7 +41,7 @@ final public class OPMLParser: NSObject { extension OPMLParser: XMLParserDelegate { - func parser( + public func parser( _ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, @@ -61,7 +61,7 @@ extension OPMLParser: XMLParserDelegate { } } - func parser( + public func parser( _ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, @@ -79,7 +79,7 @@ extension OPMLParser: XMLParserDelegate { } } - func parser(_ parser: XMLParser, foundCharacters string: String) { + public func parser(_ parser: XMLParser, foundCharacters string: String) { switch currentXMLDOMPath.lastPathComponent { case "title": opmlBuilder.title = string From 2c007f98294d1d61e86f76e8636f9d36cca29fb7 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Mon, 24 Jul 2023 00:24:45 +0200 Subject: [PATCH 7/9] making OPMLParser public --- Sources/OPML/Parser/OPMLParser.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/OPML/Parser/OPMLParser.swift b/Sources/OPML/Parser/OPMLParser.swift index 327a23d..b0a4880 100644 --- a/Sources/OPML/Parser/OPMLParser.swift +++ b/Sources/OPML/Parser/OPMLParser.swift @@ -13,7 +13,7 @@ final public class OPMLParser: NSObject { fileprivate let opmlBuilder = OPMLBuilder() - func parse() throws -> OPML { + public func parse() throws -> OPML { xmlParser.delegate = self let success = xmlParser.parse() if !success { @@ -26,12 +26,12 @@ final public class OPMLParser: NSObject { return try opmlBuilder.opml() } - init(_ data: Data) { + public init(_ data: Data) { xmlParser = XMLParser(data: data) super.init() } - init(file url: URL) throws { + public init(file url: URL) throws { guard let xmlParser = XMLParser(contentsOf: url) else { throw Error.unableToOpenURL(url) } self.xmlParser = xmlParser super.init() @@ -108,7 +108,7 @@ extension OPMLParser: XMLParserDelegate { } } - enum Error: LocalizedError { + public enum Error: LocalizedError { var errorDescription: String? { switch self { case .invalidDocument: return "Invalid or missing XML document" From 458e3af437eb59c6109c0c764462cde7ff53f9e5 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Mon, 24 Jul 2023 00:26:13 +0200 Subject: [PATCH 8/9] making OPMLParser public --- Sources/OPML/Parser/OPMLParser.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/OPML/Parser/OPMLParser.swift b/Sources/OPML/Parser/OPMLParser.swift index b0a4880..990944e 100644 --- a/Sources/OPML/Parser/OPMLParser.swift +++ b/Sources/OPML/Parser/OPMLParser.swift @@ -109,7 +109,7 @@ extension OPMLParser: XMLParserDelegate { } public enum Error: LocalizedError { - var errorDescription: String? { + public var errorDescription: String? { switch self { case .invalidDocument: return "Invalid or missing XML document" case .parseError(let error): return "XML parsing error: \(error.localizedDescription)" From 7e9f4a55e04f383d5aefb89cf1d98c891e0d8321 Mon Sep 17 00:00:00 2001 From: Vithanco Date: Fri, 28 Jul 2023 12:39:31 +0200 Subject: [PATCH 9/9] changed structure a bit --- Package.swift | 37 +++++++++++-------- .../OPMLTests}/Resources/feedly.opml | 0 .../OPMLTests}/Resources/rsparser.opml | 0 .../Tests => Tests/OPMLTests}/Tests.swift | 15 +++++++- .../OPMLTests}/XCTestManifests.swift | 0 5 files changed, 36 insertions(+), 16 deletions(-) rename {Sources/Tests => Tests/OPMLTests}/Resources/feedly.opml (100%) rename {Sources/Tests => Tests/OPMLTests}/Resources/rsparser.opml (100%) rename {Sources/Tests => Tests/OPMLTests}/Tests.swift (67%) rename {Sources/Tests => Tests/OPMLTests}/XCTestManifests.swift (100%) diff --git a/Package.swift b/Package.swift index fc38728..b56b8b3 100644 --- a/Package.swift +++ b/Package.swift @@ -1,19 +1,26 @@ -// swift-tools-version:5.2 +// swift-tools-version:5.5 import PackageDescription let package = Package( - name: "OPML", - products: [ - .library(name: "OPML", targets: ["OPML"]) - ], - dependencies: [ - .package(name: "Html", url: "https://github.com/hallee/swift-html.git", from: "0.3.0") - ], - targets: [ - .target(name: "OPML", dependencies: ["Html"]), - .testTarget( - name: "Tests", - dependencies: ["OPML"] - ) - ] + name: "OPML", + products: [ + .library(name: "OPML", targets: ["OPML"]) + ], + dependencies: [ + .package(name: "Html", url: "https://github.com/hallee/swift-html.git", from: "0.3.0") + ], + targets: [ + .target(name: "OPML", dependencies: ["Html"]), + .testTarget( + name: "OPMLTests", + dependencies: ["OPML"], + resources: [ + // Copy Tests/ExampleTests/Resources directories as-is. + // Use to retain directory structure. + // Will be at top level in bundle. + .copy("Resources/rsparser.opml"), + .copy("Resources/feedly.opml") + ] + ) + ] ) diff --git a/Sources/Tests/Resources/feedly.opml b/Tests/OPMLTests/Resources/feedly.opml similarity index 100% rename from Sources/Tests/Resources/feedly.opml rename to Tests/OPMLTests/Resources/feedly.opml diff --git a/Sources/Tests/Resources/rsparser.opml b/Tests/OPMLTests/Resources/rsparser.opml similarity index 100% rename from Sources/Tests/Resources/rsparser.opml rename to Tests/OPMLTests/Resources/rsparser.opml diff --git a/Sources/Tests/Tests.swift b/Tests/OPMLTests/Tests.swift similarity index 67% rename from Sources/Tests/Tests.swift rename to Tests/OPMLTests/Tests.swift index 67c96b3..f559760 100644 --- a/Sources/Tests/Tests.swift +++ b/Tests/OPMLTests/Tests.swift @@ -1,10 +1,21 @@ import XCTest @testable import OPML +extension Bundle { + static func locateFirst(forResource: String, withExtension: String) -> URL? { + for b in Bundle.allBundles { + if let u = b.url(forResource: forResource, withExtension: withExtension) { + return u + } + } + return nil + } +} + class Tests: XCTestCase { func testOPMLNested() { - guard let file = Bundle.module.url(forResource: "rsparser", withExtension: "opml") else { + guard let file = Bundle.module.url(forResource: "rsparser", withExtension: "opml") else { XCTFail("Missing opml file") return } @@ -13,6 +24,8 @@ class Tests: XCTestCase { let parser = try OPMLParser(file: file) let opml = try parser.parse() XCTAssertEqual(opml.entries.flatMap { $0.children ?? [] }.count, 138) + XCTAssertEqual(opml.entries.count, 73) + let programmingEntries = opml.entries.first(where: { $0.text == "Programming" })?.children XCTAssertEqual(programmingEntries?.count ?? 0, 33) diff --git a/Sources/Tests/XCTestManifests.swift b/Tests/OPMLTests/XCTestManifests.swift similarity index 100% rename from Sources/Tests/XCTestManifests.swift rename to Tests/OPMLTests/XCTestManifests.swift