Skip to content

Commit 5897840

Browse files
authored
Merge pull request #34 from hyperoslo/feature/payload
Feature: location payload
2 parents b061d66 + 28dbc2d commit 5897840

File tree

6 files changed

+73
-16
lines changed

6 files changed

+73
-16
lines changed

Sources/Compass.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ public struct Compass {
1818

1919
public static var routes = [String]()
2020

21-
public static func parse(url: NSURL, fragments: [String : AnyObject] = [:]) -> Location? {
21+
public static func parse(url: NSURL, payload: Any? = nil) -> Location? {
2222
let path = url.absoluteString.substringFromIndex(scheme.endIndex)
2323

2424
guard !(path.containsString("?") || path.containsString("#")) else {
25-
return parseAsURL(url, fragments: fragments)
25+
return parseAsURL(url, payload: payload)
2626
}
2727

2828
let results: [Result] = routes.flatMap {
@@ -36,13 +36,13 @@ public struct Compass {
3636
}
3737

3838
if let result = results.first {
39-
return Location(path: result.route, arguments: result.arguments, fragments: fragments)
39+
return Location(path: result.route, arguments: result.arguments, payload: payload)
4040
}
4141

4242
return nil
4343
}
4444

45-
static func parseAsURL(url: NSURL, fragments: [String : AnyObject] = [:]) -> Location? {
45+
static func parseAsURL(url: NSURL, payload: Any? = nil) -> Location? {
4646
guard let route = url.host else { return nil }
4747

4848
let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
@@ -56,7 +56,7 @@ public struct Compass {
5656
arguments = fragment.queryParameters()
5757
}
5858

59-
return Location(path: route, arguments: arguments, fragments: fragments)
59+
return Location(path: route, arguments: arguments, payload: payload)
6060
}
6161

6262
static func findMatch(routeString: String, pathString: String) -> Result? {

Sources/Location.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ public struct Location {
22

33
public let path: String
44
public let arguments: [String: String]
5-
public let fragments: [String: AnyObject]
5+
public let payload: Any?
66

77
public var scheme: String {
88
return Compass.scheme
99
}
1010

11-
public init(path: String, arguments: [String: String] = [:], fragments: [String: AnyObject] = [:]) {
11+
public init(path: String, arguments: [String: String] = [:], payload: Any? = nil) {
1212
self.path = path
1313
self.arguments = arguments
14-
self.fragments = fragments
14+
self.payload = payload
1515
}
1616
}

Sources/Router.swift

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
1+
public enum RouteError: ErrorType {
2+
case NotFound
3+
case InvalidArguments(Location)
4+
case InvalidPayload(Location)
5+
}
6+
17
public protocol Routable {
28

3-
func navigate(to location: Location, from currentController: Controller)
9+
func navigate(to location: Location, from currentController: Controller) throws
10+
}
11+
12+
public protocol ErrorRoutable {
13+
14+
func handle(routeError: ErrorType, from currentController: Controller)
415
}
516

617
public struct Router: Routable {
718

819
public var routes = [String: Routable]()
20+
public var errorRoute: ErrorRoutable?
921

1022
public init() {}
1123

1224
public func navigate(to location: Location, from currentController: Controller) {
13-
guard let route = routes[location.path] else { return }
14-
route.navigate(to: location, from: currentController)
25+
guard let route = routes[location.path] else {
26+
errorRoute?.handle(RouteError.NotFound, from: currentController)
27+
return
28+
}
29+
30+
do {
31+
try route.navigate(to: location, from: currentController)
32+
} catch {
33+
errorRoute?.handle(error, from: currentController)
34+
}
1535
}
1636
}

Tests/Compass/CompassTests.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,20 @@ class CompassTests: XCTestCase {
3838
XCTAssertEqual(location.arguments["user"], "testUser")
3939
}
4040

41-
func testParseFragments() {
41+
func testParsePayload() {
4242
let url = NSURL(string: "compassTests://profile:testUser")!
4343

44-
guard let location = Compass.parse(url, fragments: ["meta" : "foo"]) else {
44+
typealias Payload = (firstName: String, lastName: String)
45+
46+
guard let location = Compass.parse(url, payload: Payload(firstName: "foo", lastName: "bar")) else {
4547
XCTFail("Compass parsing failed")
4648
return
4749
}
4850

4951
XCTAssertEqual("profile:{user}", location.path)
5052
XCTAssertEqual(location.arguments["user"], "testUser")
51-
XCTAssertEqual("foo" , location.fragments["meta"] as? String)
53+
XCTAssertEqual("foo" , (location.payload as? Payload)?.firstName)
54+
XCTAssertEqual("bar" , (location.payload as? Payload)?.lastName)
5255
}
5356

5457
func testParseRouteConcreateMatchCount() {

Tests/Compass/Helpers.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,31 @@ class TestRoute: Routable {
77

88
var resolved = false
99

10-
func navigate(to location: Location, from currentController: Controller) {
10+
func navigate(to location: Location, from currentController: Controller) throws {
1111
resolved = true
1212
}
1313
}
1414

15+
class ThrowableRoute: Routable {
16+
17+
enum Error: ErrorType {
18+
case Unknown
19+
}
20+
21+
func navigate(to location: Location, from currentController: Controller) throws {
22+
throw Error.Unknown
23+
}
24+
}
25+
26+
class ErrorRoute: ErrorRoutable {
27+
28+
var error: ErrorType?
29+
30+
func handle(routeError: ErrorType, from currentController: Controller) {
31+
error = routeError
32+
}
33+
}
34+
1535
// MARK: - Shuffle
1636

1737
extension CollectionType {

Tests/Compass/RouterTests.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,38 @@ import XCTest
55
class RouterTests: XCTestCase {
66

77
var router: Router!
8-
var controller = Controller()
98
var route: TestRoute!
9+
var controller: Controller!
10+
var errorRoute: ErrorRoute!
1011

1112
override func setUp() {
1213
router = Router()
1314
route = TestRoute()
15+
controller = Controller()
16+
errorRoute = ErrorRoute()
17+
18+
router.errorRoute = errorRoute
1419
}
1520

1621
func testNavigateIfRouteRegistered() {
1722
router.routes["test"] = route
1823
router.navigate(to: Location(path: "test"), from: controller)
1924

2025
XCTAssertTrue(route.resolved)
26+
XCTAssertNil(errorRoute.error)
2127
}
2228

2329
func testNavigateIfRouteNotRegistered() {
2430
router.navigate(to: Location(path: "test"), from: controller)
2531

2632
XCTAssertFalse(route.resolved)
33+
XCTAssertTrue(errorRoute.error is RouteError)
34+
}
35+
36+
func testNavigateIfRouteThrowsError() {
37+
router.routes["throw"] = ThrowableRoute()
38+
router.navigate(to: Location(path: "throw"), from: controller)
39+
40+
XCTAssertTrue(errorRoute.error is ThrowableRoute.Error)
2741
}
2842
}

0 commit comments

Comments
 (0)