From 6b3b02cee72bbad8ccbff4307668d7b8f0547bf6 Mon Sep 17 00:00:00 2001 From: Vojta Bartos Date: Tue, 10 Feb 2015 14:29:49 +0100 Subject: [PATCH] Saving regex route matches to route parameters dictionary --- DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m | 49 ++++++++++++++++------ Tests/RouteMatcher/DPLRouteMatcherSpec.m | 37 ++++++++++++++++ 2 files changed, 73 insertions(+), 13 deletions(-) diff --git a/DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m b/DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m index 9db7671..33cefd1 100644 --- a/DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m +++ b/DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m @@ -2,6 +2,7 @@ #import "DPLDeepLink_Private.h" #import "NSString+DPLTrim.h" +static NSString * const DPLComponentPattern = @":[a-zA-Z0-9-_][^/]+"; static NSString * const DPLRouteParameterPattern = @":[a-zA-Z0-9-_]+"; static NSString * const DPLURLParameterPattern = @"([a-zA-Z0-9-_]+)"; @@ -34,27 +35,49 @@ - (instancetype)initWithRoute:(NSString *)route { } +- (NSMutableArray *)routeParamaterNames { + if (!_routeParamaterNames) { + _routeParamaterNames = [NSMutableArray array]; + } + return _routeParamaterNames; +} + - (NSRegularExpression *)regex { if (!_regex) { - _routeParamaterNames = [NSMutableArray array]; + NSString *modifiedRoute = [self.route copy]; + NSRegularExpression *componentRegex = [NSRegularExpression regularExpressionWithPattern:DPLComponentPattern + options:0 + error:nil]; NSRegularExpression *parameterRegex = [NSRegularExpression regularExpressionWithPattern:DPLRouteParameterPattern options:0 error:nil]; - - __block NSString *modifiedRoute = [self.route copy]; - NSArray *matches = [parameterRegex matchesInString:self.route - options:0 - range:NSMakeRange(0, self.route.length)]; - + NSArray *matches = [componentRegex matchesInString:self.route + options:0 + range:NSMakeRange(0, self.route.length)]; for (NSTextCheckingResult *result in matches) { + NSString *component = [self.route substringWithRange:result.range]; + NSString *modifiedComponent = [component copy]; + NSArray *componentMatches = [parameterRegex matchesInString:component + options:0 + range:NSMakeRange(0, component.length)]; + NSTextCheckingResult *componentResult = [componentMatches firstObject]; + if (componentResult) { + NSString *stringToReplace = [component substringWithRange:componentResult.range]; + NSString *variableName = [stringToReplace stringByReplacingOccurrencesOfString:@":" + withString:@""]; + + [self.routeParamaterNames addObject:variableName]; + + modifiedComponent = [modifiedComponent stringByReplacingOccurrencesOfString:stringToReplace + withString:@""]; + } - NSString *stringToReplace = [self.route substringWithRange:result.range]; - NSString *variableName = [stringToReplace stringByReplacingOccurrencesOfString:@":" - withString:@""]; - [self.routeParamaterNames addObject:variableName]; + if (modifiedComponent.length == 0) { + modifiedComponent = DPLURLParameterPattern; + } - modifiedRoute = [modifiedRoute stringByReplacingOccurrencesOfString:stringToReplace - withString:DPLURLParameterPattern]; + modifiedRoute = [modifiedRoute stringByReplacingOccurrencesOfString:component + withString:modifiedComponent]; } modifiedRoute = [modifiedRoute stringByAppendingString:@"$"]; diff --git a/Tests/RouteMatcher/DPLRouteMatcherSpec.m b/Tests/RouteMatcher/DPLRouteMatcherSpec.m index bfeaa9e..4358328 100644 --- a/Tests/RouteMatcher/DPLRouteMatcherSpec.m +++ b/Tests/RouteMatcher/DPLRouteMatcherSpec.m @@ -16,6 +16,7 @@ NSURL *url = URLWithPath(@"/table/book"); DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; expect(deepLink).toNot.beNil(); + expect(deepLink.routeParameters).to.equal(@{}); }); it(@"returns a deep link when a URL matches a host", ^{ @@ -23,6 +24,7 @@ NSURL *url = URLWithPath(@""); DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; expect(deepLink).toNot.beNil(); + expect(deepLink.routeParameters).to.equal(@{}); }); it(@"does NOT return a deep link when a host does NOT match the URL host", ^{ @@ -108,10 +110,45 @@ NSURL *url2 = URLWithPath(@"/abc123"); DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; expect(deepLink).notTo.beNil(); + expect(deepLink.routeParameters).to.equal(@{}); DPLDeepLink *deepLink2 = [matcher deepLinkWithURL:url2]; expect(deepLink2).notTo.beNil(); + expect(deepLink2.routeParameters).to.equal(@{}); }); + + + it(@"returns a deep link with route parameters when a URL matches a parameterized regex route", ^{ + DPLRouteMatcher *matcher = [DPLRouteMatcher matcherWithRoute:@"/table/:table([a-zA-Z]+)/:id([0-9]+)"]; + NSURL *url = URLWithPath(@"/table/randomTableName/109"); + DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; + expect(deepLink).notTo.beNil(); + expect(deepLink.routeParameters).to.equal(@{@"table": @"randomTableName", + @"id": @"109" }); + }); + + it(@"does NOT return a deep link when the URL path does not match regex table parameter", ^{ + DPLRouteMatcher *matcher = [DPLRouteMatcher matcherWithRoute:@"/table/:table([a-zA-Z]+)/:id([0-9])"]; + NSURL *url = URLWithPath(@"/table/table_name/109"); + DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; + expect(deepLink).to.beNil(); + }); + + it(@"does NOT return a deep link when the URL path does not match regex id parameter", ^{ + DPLRouteMatcher *matcher = [DPLRouteMatcher matcherWithRoute:@"/table/:table([a-zA-Z]+)/:id([0-9])"]; + NSURL *url = URLWithPath(@"/table/tableName/1a9"); + DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; + expect(deepLink).to.beNil(); + }); + + it(@"matches a wildcard deeplink to route parameters", ^{ + DPLRouteMatcher *matcher = [DPLRouteMatcher matcherWithRoute:@"/table/:path(.*)"]; + NSURL *url = URLWithPath(@"/table/some/path/which/should/be/in/route/parameters"); + DPLDeepLink *deepLink = [matcher deepLinkWithURL:url]; + expect(deepLink).notTo.beNil(); + expect(deepLink.routeParameters).to.equal(@{@"path": @"some/path/which/should/be/in/route/parameters"}); + }); + }); SpecEnd