Almost
This commit is contained in:
parent
4e2176f393
commit
2420042d4d
2 changed files with 52 additions and 24 deletions
|
@ -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,
|
||||||
|
|
|
@ -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 {});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue