Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions DeepLinkSDK/RouteMatcher/DPLRouteMatcher.m
Original file line number Diff line number Diff line change
Expand Up @@ -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-_]+)";

Expand Down Expand Up @@ -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:@"$"];
Expand Down
37 changes: 37 additions & 0 deletions Tests/RouteMatcher/DPLRouteMatcherSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@
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", ^{
DPLRouteMatcher *matcher = [DPLRouteMatcher matcherWithRoute:@"dpl.com"];
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", ^{
Expand Down Expand Up @@ -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