This commit is contained in:
thosakwe 2016-11-27 09:46:13 -05:00
parent 4e2176f393
commit 2420042d4d
2 changed files with 52 additions and 24 deletions

View file

@ -54,7 +54,7 @@ class Router {
final route = final route =
new Route(path, debug: debug, method: method, handlers: handlers); new Route(path, debug: debug, method: method, handlers: handlers);
_routes.add(route); _routes.add(route);
return route; return route.._path = _pathify(path);
} }
/// Returns a [Router] with a duplicated version of this tree. /// Returns a [Router] with a duplicated version of this tree.
@ -240,60 +240,62 @@ class Router {
/// Finds the first [Route] that matches the given path, /// Finds the first [Route] that matches the given path,
/// with the given method. /// with the given method.
RoutingResult resolve(String fullPath, String path, {String method: 'GET'}) { RoutingResult resolve(String absolute, String relative, {String method: 'GET'}) {
final cleanFullPath = fullPath.replaceAll(_straySlashes, ''); final cleanAbsolute = absolute.replaceAll(_straySlashes, '');
final cleanPath = path.replaceAll(_straySlashes, ''); final cleanRelative = relative.replaceAll(_straySlashes, '');
final segments = cleanRelative.split('/').where((str) => str.isNotEmpty);
_printDebug( _printDebug(
'Now resolving $method "/$cleanPath", fullPath: $cleanFullPath'); 'Now resolving $method "/$cleanRelative", absolute: $cleanAbsolute');
_printDebug('Path segments: ${segments.toList()}');
for (Route route in routes) { for (Route route in routes) {
if (route is SymlinkRoute && route._head != null) { if (route is SymlinkRoute && route._head != null && segments.isNotEmpty) {
final match = route._head.firstMatch(cleanPath); final match = route._head.firstMatch(segments.first);
if (match != null) { if (match != null) {
final tail = cleanPath final tail = cleanRelative
.replaceAll(route._head, '') .replaceAll(route._head, '')
.replaceAll(_straySlashes, ''); .replaceAll(_straySlashes, '');
_printDebug('Matched head "${match[0]}" to $route. Tail: "$tail"'); _printDebug('Matched head "${match[0]}" to $route. Tail: "$tail"');
route.router.debug = route.router.debug || debug; route.router.debug = route.router.debug || debug;
final nested = final nested =
route.router.resolve(cleanFullPath, tail, method: method); route.router.resolve(cleanAbsolute, tail, method: method);
return _dumpResult( return _dumpResult(
cleanPath, cleanRelative,
new RoutingResult( new RoutingResult(
match: match, match: match,
nested: nested, nested: nested,
params: route.parseParameters(cleanPath), params: route.parseParameters(cleanRelative),
sourceRoute: route, sourceRoute: route,
sourceRouter: this, sourceRouter: this,
tail: tail)); tail: tail));
} }
} else if (route.method == '*' || route.method == method) { } else if (route.method == '*' || route.method == method) {
final match = route.match(cleanPath); final match = route.match(cleanRelative);
if (match != null) { if (match != null) {
return _dumpResult( return _dumpResult(
cleanPath, cleanRelative,
new RoutingResult( new RoutingResult(
match: match, match: match,
params: route.parseParameters(cleanPath), params: route.parseParameters(cleanRelative),
sourceRoute: route, sourceRoute: route,
sourceRouter: this)); sourceRouter: this));
} }
} }
} }
_printDebug('Could not resolve path "/$cleanPath".'); _printDebug('Could not resolve path "/$cleanRelative".');
return null; return null;
} }
/// Finds every possible [Route] that matches the given path, /// Finds every possible [Route] that matches the given path,
/// with the given method. /// with the given method.
Iterable<RoutingResult> resolveAll(String fullPath, String path, Iterable<RoutingResult> resolveAll(String absolute, String relative,
{String method: 'GET'}) { {String method: 'GET'}) {
final router = clone(); final router = clone();
final List<RoutingResult> results = []; final List<RoutingResult> results = [];
var result = router.resolve(fullPath, path, method: method); var result = router.resolve(absolute, relative, method: method);
while (result != null) { while (result != null) {
if (!results.contains(result)) if (!results.contains(result))
@ -302,18 +304,14 @@ class Router {
break; break;
result.deepestRouter._routes.remove(result.deepestRoute); result.deepestRouter._routes.remove(result.deepestRoute);
result = router.resolve(fullPath, path, method: method); result = router.resolve(absolute, relative, method: method);
} }
_printDebug( _printDebug(
'Results of $method "/${fullPath.replaceAll(_straySlashes, '')}": ${results.map((r) => r.deepestRoute).toList()}'); 'Results of $method "/${absolute.replaceAll(_straySlashes, '')}": ${results.map((r) => r.deepestRoute).toList()}');
return results; return results;
} }
_validHead(RegExp rgx) {
return !rgx.hasMatch('');
}
/// Incorporates another [Router]'s routes into this one's. /// Incorporates another [Router]'s routes into this one's.
/// ///
/// If `hooked` is set to `true` and a [Service] is provided, /// If `hooked` is set to `true` and a [Service] is provided,

View file

@ -149,10 +149,40 @@ main() {
group('mount', () { group('mount', () {
group('path', () { group('path', () {
test('top-level', () async { test('top-level', () async {
final res = await client.get('$url/beatles/spinal_clacker'); final res = await client.post('$url/beatles/spinal_clacker');
print('Response: ${res.body}'); print('Response: ${res.body}');
expect(res.body, equals('come together')); expect(res.body, equals('come together'));
}); });
test('fallback', () async {
final res = await client.patch('$url/beatles/muddy_water');
print('Response: ${res.body}');
expect(res.body, equals('together'));
}); });
}); });
test('deep nested', () async {
final res = await client.get('$url/beatles/big/yellow/submarine');
print('Response: ${res.body}');
expect(res.body, equals('we all live in a'));
});
group('fallback', () {});
});
group('404', () {
expect404(r) => r.then((res) {
print('Response (${res.statusCode}): ${res.body}');
expect(res.statusCode, equals(404));
});
test('path', () async {
await expect404(client.get('$url/foo'));
await expect404(client.get('$url/bye'));
await expect404(client.get('$url/people/0/age'));
await expect404(client.get('$url/beatles2'));
});
test('method', () async {});
});
} }