From 68662b149e277a4675e017e035062a32c383a195 Mon Sep 17 00:00:00 2001 From: thosakwe Date: Sun, 27 Nov 2016 18:39:03 -0500 Subject: [PATCH] Params work --- .idea/angel_route.iml | 5 -- .idea/runConfigurations/Params_Tests.xml | 6 +++ README.md | 6 +-- lib/src/route.dart | 13 +++-- lib/src/router.dart | 61 +++++++++++++----------- lib/src/routing_result.dart | 12 +++++ pubspec.yaml | 2 +- test/params_test.dart | 43 +++++++++++++++++ 8 files changed, 102 insertions(+), 46 deletions(-) create mode 100644 .idea/runConfigurations/Params_Tests.xml create mode 100644 test/params_test.dart diff --git a/.idea/angel_route.iml b/.idea/angel_route.iml index 03b4c25b..6b79991a 100644 --- a/.idea/angel_route.iml +++ b/.idea/angel_route.iml @@ -7,12 +7,7 @@ - - - - - diff --git a/.idea/runConfigurations/Params_Tests.xml b/.idea/runConfigurations/Params_Tests.xml new file mode 100644 index 00000000..dbb5cceb --- /dev/null +++ b/.idea/runConfigurations/Params_Tests.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index 27e78111..b31a6d62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # angel_route -![version 1.0.0-dev+14](https://img.shields.io/badge/version-1.0.0--dev+14-red.svg) +![version 1.0.0-dev+15](https://img.shields.io/badge/version-1.0.0--dev+15-red.svg) ![build status](https://travis-ci.org/angel-dart/route.svg) A powerful, isomorphic routing library for Dart. @@ -42,10 +42,8 @@ main() { router.post('/users/:id/timeline', (String id) {}); - // Numbers automatically parsed - router.get('/square_root/:id([0-9]+)', (n) { - return { 'result': pow(n, 0.5) }; + return { 'result': pow(int.parse(n), 0.5) }; }); router.group('/show/:id', (router) { diff --git a/lib/src/route.dart b/lib/src/route.dart index ccc5bf3f..303325b5 100644 --- a/lib/src/route.dart +++ b/lib/src/route.dart @@ -304,7 +304,7 @@ class Route { } Route clone() { - final Route route = new Route(''); + final Route route = new Route('', debug: debug); return route .._children.addAll(children) @@ -315,6 +315,7 @@ class Route { .._name = name .._parent = _parent .._parentResolver = _parentResolver + .._path = _path .._pathified = _pathified .._resolver = _resolver .._stub = _stub @@ -347,21 +348,19 @@ class Route { _printDebug( 'Searched request path $requestPath and found these values: $values'); + _printDebug('This route\'s path is "$path".'); final pathString = _pathify(path).replaceAll(new RegExp('\/'), r'\/'); Iterable matches = _param.allMatches(pathString); _printDebug( - 'All param names parsed in "$pathString": ${matches.map((m) => m.group(0))}'); + 'All param names parsed in "$pathString": ${matches.map((m) => m[1])}'); for (int i = 0; i < matches.length && i < values.length; i++) { Match match = matches.elementAt(i); String paramName = match.group(1); String value = values.elementAt(i); - num numValue = num.parse(value, (_) => double.NAN); - if (!numValue.isNaN) - result[paramName] = numValue; - else - result[paramName] = value; + _printDebug('Setting param "$paramName" to "$value"...'); + result[paramName] = value; } return result; diff --git a/lib/src/router.dart b/lib/src/router.dart index 1158c267..233aa279 100644 --- a/lib/src/router.dart +++ b/lib/src/router.dart @@ -138,8 +138,8 @@ class Router extends Extensible { {Iterable middleware: const [], String name: null, String namespace: null}) { - final router = new Router(debug: debug).._middleware.addAll(middleware); - callback(router); + final router = new Router().._middleware.addAll(middleware); + callback(router..debug = debug); return mount(path, router, namespace: namespace).._name = name; } @@ -257,29 +257,35 @@ class Router extends Extensible { for (Route route in routes) { if (route is SymlinkRoute && route._head != null && segments.isNotEmpty) { - final match = route._head.firstMatch(segments.first); + final s = []; - if (match != null) { - final cleaned = segments.first.replaceFirst(match[0], ''); - final tail = cleanRelative - .replaceAll(route._head, '') - .replaceAll(_straySlashes, ''); + for (String seg in segments) { + s.add(seg); + final match = route._head.firstMatch(s.join('/')); - if (cleaned.isEmpty) { - _printDebug('Matched relative "$cleanRelative" to head ${route._head - .pattern} on $route. Tail: "$tail"'); - route.router.debug = route.router.debug || debug; - final nested = - route.router.resolve(cleanAbsolute, tail, method: method); - return _dumpResult( - cleanRelative, - new RoutingResult( - match: match, - nested: nested, - params: route.parseParameters(cleanRelative), - shallowRoute: route, - shallowRouter: this, - tail: tail)); + if (match != null) { + final cleaned = s.join('/').replaceFirst(match[0], ''); + final tail = cleanRelative + .replaceAll(route._head, '') + .replaceAll(_straySlashes, ''); + + if (cleaned.isEmpty) { + _printDebug( + 'Matched relative "$cleanRelative" to head ${route._head + .pattern} on $route. Tail: "$tail"'); + route.router.debug = route.router.debug || debug; + final nested = + route.router.resolve(cleanAbsolute, tail, method: method); + return _dumpResult( + cleanRelative, + new RoutingResult( + match: match, + nested: nested, + params: route.parseParameters(match[0]), + shallowRoute: route, + shallowRouter: this, + tail: tail)); + } } } } @@ -317,11 +323,7 @@ class Router extends Extensible { var result = router.resolve(absolute, relative, method: method); while (result != null) { - if (!results.contains(result)) - results.add(result); - else - break; - + results.add(result); result.router._routes.remove(result.route); result = router.resolve(absolute, relative, method: method); } @@ -352,7 +354,8 @@ class Router extends Extensible { copiedMiddleware[middlewareName]; } - final route = new SymlinkRoute(path, path, router); + final route = + new SymlinkRoute(path, path, router..debug = debug || router.debug); _mounted[route.path] = router; _routes.add(route); route._head = new RegExp(route.matcher.pattern.replaceAll(_rgxEnd, '')); diff --git a/lib/src/routing_result.dart b/lib/src/routing_result.dart index ba252d58..aa604677 100644 --- a/lib/src/routing_result.dart +++ b/lib/src/routing_result.dart @@ -35,6 +35,18 @@ class RoutingResult { return handlers; } + Map get allParams { + final params = {}; + var search = this; + + while (search != null) { + params.addAll(search.params); + search = search.nested; + } + + return params; + } + RoutingResult( {this.match, Map params: const {}, diff --git a/pubspec.yaml b/pubspec.yaml index f492c7c4..c665fd6e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: angel_route description: A powerful, isomorphic routing library for Dart. -version: 1.0.0-dev+14 +version: 1.0.0-dev+15 author: Tobe O homepage: https://github.com/angel-dart/angel_route dev_dependencies: diff --git a/test/params_test.dart b/test/params_test.dart new file mode 100644 index 00000000..a1161345 --- /dev/null +++ b/test/params_test.dart @@ -0,0 +1,43 @@ +import 'package:angel_route/angel_route.dart'; +import 'package:test/test.dart'; + +main() { + final router = new Router(debug: true) + ..get('/hello', '') + ..get('/user/:id', ''); + + router.group('/book/:id', (router) { + router.get('/reviews', ''); + router.get('/readers/:readerId', ''); + }); + + router.mount('/color', new Router(debug: true)..get('/:name/shades', '')); + + setUp(router.dumpTree); + + void expectParams(String path, Map params) { + final p = {}; + final resolved = router.resolveAll(path, path); + print('Resolved $path => ${resolved.map((r) => r.allParams).toList()}'); + for (final result in resolved) p.addAll(result.allParams); + expect(p, equals(params)); + } + + group('top-level', () { + test('no params', () => expectParams('/hello', {})); + + test('one param', () => expectParams('/user/0', {'id': '0'})); + }); + + group('group', () { + test('root', () => expectParams('/book/1337', {'id': '1337'})); + test('path', () => expectParams('/book/1337/reviews', {'id': '1337'})); + test( + 'two params', + () => expectParams( + '/book/1337/readers/foo', {'id': '1337', 'readerId': 'foo'})); + }); + + test('mount', + () => expectParams('/color/chartreuse/shades', {'name': 'chartreuse'})); +}