diff --git a/Compass.xcodeproj/project.pbxproj b/Compass.xcodeproj/project.pbxproj index 18160e5..eda1a68 100644 --- a/Compass.xcodeproj/project.pbxproj +++ b/Compass.xcodeproj/project.pbxproj @@ -7,6 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + D2F2C1901F443D790042D751 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F2C18F1F443D790042D751 /* Utilities.swift */; }; + D2F2C1911F443D790042D751 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F2C18F1F443D790042D751 /* Utilities.swift */; }; + D2F2C1921F443D790042D751 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F2C18F1F443D790042D751 /* Utilities.swift */; }; + D2F2C1941F443E1F0042D751 /* UtilitiesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F2C1931F443E1F0042D751 /* UtilitiesTests.swift */; }; + D2F2C1951F443E1F0042D751 /* UtilitiesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2F2C1931F443E1F0042D751 /* UtilitiesTests.swift */; }; D5361FF41D6C7133003C3EE8 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5361FEF1D6C7133003C3EE8 /* Router.swift */; }; D5361FF51D6C7133003C3EE8 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5361FEF1D6C7133003C3EE8 /* Router.swift */; }; D5361FF81D6C7133003C3EE8 /* TypeAlias.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5361FF11D6C7133003C3EE8 /* TypeAlias.swift */; }; @@ -50,6 +55,8 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + D2F2C18F1F443D790042D751 /* Utilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; + D2F2C1931F443E1F0042D751 /* UtilitiesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UtilitiesTests.swift; sourceTree = ""; }; D5361FEF1D6C7133003C3EE8 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; D5361FF11D6C7133003C3EE8 /* TypeAlias.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeAlias.swift; sourceTree = ""; }; D5361FF21D6C7133003C3EE8 /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; }; @@ -125,6 +132,7 @@ D536200F1D6C743A003C3EE8 /* CompassTests.swift */, D53620101D6C743A003C3EE8 /* Helpers.swift */, D53620111D6C743A003C3EE8 /* RouterTests.swift */, + D2F2C1931F443E1F0042D751 /* UtilitiesTests.swift */, ); path = Compass; sourceTree = ""; @@ -171,6 +179,7 @@ D5361FF21D6C7133003C3EE8 /* String+Extensions.swift */, D5361FF31D6C7133003C3EE8 /* Navigator.swift */, D536202B1D6C8532003C3EE8 /* Location.swift */, + D2F2C18F1F443D790042D751 /* Utilities.swift */, ); path = Sources; sourceTree = ""; @@ -382,6 +391,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D2F2C1901F443D790042D751 /* Utilities.swift in Sources */, D5361FFC1D6C7133003C3EE8 /* Navigator.swift in Sources */, D5361FFA1D6C7133003C3EE8 /* String+Extensions.swift in Sources */, D5361FF81D6C7133003C3EE8 /* TypeAlias.swift in Sources */, @@ -396,6 +406,7 @@ files = ( D53620251D6C749A003C3EE8 /* CompassTests.swift in Sources */, D53620271D6C749A003C3EE8 /* RouterTests.swift in Sources */, + D2F2C1941F443E1F0042D751 /* UtilitiesTests.swift in Sources */, D53620261D6C749A003C3EE8 /* Helpers.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -404,6 +415,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D2F2C1911F443D790042D751 /* Utilities.swift in Sources */, D5361FFD1D6C7133003C3EE8 /* Navigator.swift in Sources */, D5361FFB1D6C7133003C3EE8 /* String+Extensions.swift in Sources */, D5361FF91D6C7133003C3EE8 /* TypeAlias.swift in Sources */, @@ -418,6 +430,7 @@ files = ( D53620281D6C749B003C3EE8 /* CompassTests.swift in Sources */, D536202A1D6C749B003C3EE8 /* RouterTests.swift in Sources */, + D2F2C1951F443E1F0042D751 /* UtilitiesTests.swift in Sources */, D53620291D6C749B003C3EE8 /* Helpers.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -426,6 +439,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + D2F2C1921F443D790042D751 /* Utilities.swift in Sources */, FDD723361DCA20BC00D722E4 /* Navigator.swift in Sources */, FDD723371DCA20BC00D722E4 /* String+Extensions.swift in Sources */, FDD723381DCA20BC00D722E4 /* TypeAlias.swift in Sources */, diff --git a/Sources/Location.swift b/Sources/Location.swift index a85648f..69d77f9 100644 --- a/Sources/Location.swift +++ b/Sources/Location.swift @@ -18,7 +18,7 @@ public struct Location { var decodedArguments = [String: String]() arguments.forEach { (key, value) in - decodedArguments[key] = value.compass_decoded() + decodedArguments[key] = PercentEncoder.decode(string: value) } self.arguments = decodedArguments diff --git a/Sources/Navigator.swift b/Sources/Navigator.swift index da1391c..1b6c138 100644 --- a/Sources/Navigator.swift +++ b/Sources/Navigator.swift @@ -16,18 +16,6 @@ public struct Navigator { /// A list of route strings public static var routes = [String]() - /// Parse Location from urn - /// - /// - Parameter urn: Safely construct url from urn, perform percent encoding - /// - Returns: The Location that can be used - public static func parse(urn: String) -> Location? { - guard let url = URL(string: "\(scheme)\(urn.compass_encoded())") else { - return nil - } - - return parse(url: url) - } - /// Parse Location from url /// /// - Parameters: diff --git a/Sources/String+Extensions.swift b/Sources/String+Extensions.swift index 97c28cf..d144cbf 100644 --- a/Sources/String+Extensions.swift +++ b/Sources/String+Extensions.swift @@ -31,19 +31,4 @@ extension String { return parameters } - - /// Route string must be percent encoded to be registered in Compass route list - /// - /// - Returns: The percented encoded string - func compass_encoded() -> String { - return addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? self - } - - - /// Perform percent decoding to be in a user readable Location - /// - /// - Returns: The percented decoded string - func compass_decoded() -> String { - return removingPercentEncoding ?? self - } } diff --git a/Sources/TypeAlias.swift b/Sources/TypeAlias.swift index 0a65034..1621393 100644 --- a/Sources/TypeAlias.swift +++ b/Sources/TypeAlias.swift @@ -6,20 +6,6 @@ #if os(OSX) public typealias CurrentController = NSViewController - - /// Tell the application to open the url - /// - /// - Parameter url: The requested url - func open(url: URL) { - NSWorkspace.shared().open(url) - } #else public typealias CurrentController = UIViewController - - /// Tell the application to open the url - /// - /// - Parameter url: The requested url - func open(url: URL) { - UIApplication.shared.openURL(url) - } #endif diff --git a/Sources/Utilities.swift b/Sources/Utilities.swift new file mode 100644 index 0000000..916cb4d --- /dev/null +++ b/Sources/Utilities.swift @@ -0,0 +1,26 @@ +import Foundation + +struct PercentEncoder { + + /// Perform url encoding + /// + /// - Parameter allowedCharacters: Won't encode allowed characters + /// - Parameter string: The source string + /// - Returns: The encoded string + static func encode(string: String, allowedCharacters: String) -> String { + var set = CharacterSet.urlPathAllowed + allowedCharacters.unicodeScalars.forEach { + set.insert($0) + } + + return string.addingPercentEncoding(withAllowedCharacters: set) ?? string + } + + /// Perform url decoding + /// + /// - Parameter string: The encoded string + /// - Returns: The percented decoded string + static func decode(string: String) -> String { + return string.removingPercentEncoding ?? string + } +} diff --git a/Tests/Compass/CompassTests.swift b/Tests/Compass/CompassTests.swift index 7d3ac58..aa12092 100644 --- a/Tests/Compass/CompassTests.swift +++ b/Tests/Compass/CompassTests.swift @@ -264,16 +264,4 @@ class CompassTests: XCTestCase { XCTAssertEqual(location.arguments["expires_in"], "3600") XCTAssertEqual(location.arguments["token_type"], "Bearer") } - - func testEncodedURN() { - let urn = "organization:hyper oslo:simply awesome" - - guard let location = Navigator.parse(urn: urn) else { - XCTFail("Compass parsing failed") - return - } - - XCTAssertEqual(location.arguments["name"], "hyper oslo") - XCTAssertEqual(location.arguments["type"], "simply awesome") - } } diff --git a/Tests/Compass/UtilitiesTests.swift b/Tests/Compass/UtilitiesTests.swift new file mode 100644 index 0000000..7215b88 --- /dev/null +++ b/Tests/Compass/UtilitiesTests.swift @@ -0,0 +1,19 @@ +import Foundation +import XCTest +@testable import Compass + +class UtilitiesTests: XCTestCase { + func testEncode() { + let urn = "organization:hyper oslo:simply awesome" + let encodedUrn = PercentEncoder.encode(string: urn, allowedCharacters: ":") + + XCTAssertEqual(encodedUrn, "organization:hyper%20oslo:simply%20awesome") + } + + func testDecode() { + let urn = "organization:hyper oslo:simply awesome" + let encodedUrn = PercentEncoder.encode(string: urn, allowedCharacters: ":") + + XCTAssertEqual(PercentEncoder.decode(string: encodedUrn), urn) + } +}