From ceb66dd5208a0a95f846bc8f256fee34ee3456ac Mon Sep 17 00:00:00 2001 From: thosakwe Date: Thu, 13 Oct 2016 16:50:27 -0400 Subject: [PATCH] Params will be fixed :) --- .idea/runConfigurations/All_Route_Tests.xml | 6 ++ .idea/runConfigurations/All_Router_Tests.xml | 6 ++ .idea/runConfigurations/Fallback.xml | 6 ++ .idea/runConfigurations/No_Params.xml | 6 ++ .idea/runConfigurations/Parse_Params.xml | 6 ++ .idea/runConfigurations/With_Params.xml | 6 ++ README.md | 4 +- lib/src/extensible.dart | 6 +- lib/src/route.dart | 22 ++++--- test/index.html | 11 ++++ test/route/with_params.dart | 65 +++++++++++++++++++- test/router/all_tests.dart | 7 ++- test/router/fallback.dart | 20 ++++++ 13 files changed, 154 insertions(+), 17 deletions(-) create mode 100644 .idea/runConfigurations/All_Route_Tests.xml create mode 100644 .idea/runConfigurations/All_Router_Tests.xml create mode 100644 .idea/runConfigurations/Fallback.xml create mode 100644 .idea/runConfigurations/No_Params.xml create mode 100644 .idea/runConfigurations/Parse_Params.xml create mode 100644 .idea/runConfigurations/With_Params.xml create mode 100644 test/index.html create mode 100644 test/router/fallback.dart diff --git a/.idea/runConfigurations/All_Route_Tests.xml b/.idea/runConfigurations/All_Route_Tests.xml new file mode 100644 index 00000000..cc751b12 --- /dev/null +++ b/.idea/runConfigurations/All_Route_Tests.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/All_Router_Tests.xml b/.idea/runConfigurations/All_Router_Tests.xml new file mode 100644 index 00000000..a1920311 --- /dev/null +++ b/.idea/runConfigurations/All_Router_Tests.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Fallback.xml b/.idea/runConfigurations/Fallback.xml new file mode 100644 index 00000000..4e88d8db --- /dev/null +++ b/.idea/runConfigurations/Fallback.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/No_Params.xml b/.idea/runConfigurations/No_Params.xml new file mode 100644 index 00000000..b1e8cfdf --- /dev/null +++ b/.idea/runConfigurations/No_Params.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Parse_Params.xml b/.idea/runConfigurations/Parse_Params.xml new file mode 100644 index 00000000..b5ef0380 --- /dev/null +++ b/.idea/runConfigurations/Parse_Params.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/With_Params.xml b/.idea/runConfigurations/With_Params.xml new file mode 100644 index 00000000..1d95c2c7 --- /dev/null +++ b/.idea/runConfigurations/With_Params.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/README.md b/README.md index c5ca5c37..95659a0f 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,6 @@ To prevent this for a given anchor, do any of the following: * Set `rel="external"` # Route State -Routes can have state via the `Extensible` class, which is a simple proxy over a `Map`. -This does not require reflection, and can be used in all Dart environments. ```dart main() { @@ -122,7 +120,7 @@ main() { router.onRoute.listen((route) { if (route == null) throw 404; - else route.state.foo = 'bar'; + else route.state['foo'] = 'bar'; }); } ``` diff --git a/lib/src/extensible.dart b/lib/src/extensible.dart index a96ec806..1dd58a26 100644 --- a/lib/src/extensible.dart +++ b/lib/src/extensible.dart @@ -11,6 +11,9 @@ class Extensible { /// Useful for configuration and extension. Map properties = {}; + operator [](key) => properties[key]; + operator []=(key, value) => properties[key] = value; + noSuchMethod(Invocation invocation) { if (invocation.memberName != null) { String name = _sym.firstMatch(invocation.memberName.toString()).group(1); @@ -20,9 +23,6 @@ class Extensible { invocation.namedArguments); } else if (invocation.isGetter) { return properties[name]; - } else if (invocation.isSetter) { - return properties[name.replaceAll(_equ, '')] = - invocation.positionalArguments.first; } } diff --git a/lib/src/route.dart b/lib/src/route.dart index 4287a8a8..38301c8d 100644 --- a/lib/src/route.dart +++ b/lib/src/route.dart @@ -185,9 +185,10 @@ class Route { Map parseParameters(String requestPath) { Map result = {}; - Iterable values = _parseParameters(requestPath.replaceAll(_straySlashes, '')); - Iterable matches = _param.allMatches( - _pathified.replaceAll(new RegExp('\/'), r'\/')); + Iterable values = + _parseParameters(requestPath.replaceAll(_straySlashes, '')); + Iterable matches = + _param.allMatches(_pathified.replaceAll(new RegExp('\/'), r'\/')); for (int i = 0; i < matches.length; i++) { Match match = matches.elementAt(i); String paramName = match.group(1); @@ -204,14 +205,13 @@ class Route { _parseParameters(String requestPath) sync* { Match routeMatch = matcher.firstMatch(requestPath); - for (int i = 1; i <= routeMatch.groupCount; i++) - yield routeMatch.group(i); + for (int i = 1; i <= routeMatch.groupCount; i++) yield routeMatch.group(i); } Route resolve(String path, [bool filter(Route route)]) { final _filter = filter ?? (_) => true; - if (path.isEmpty || path == '.' && _filter(this)) { + if ((path.isEmpty || path == '.') && _filter(this)) { return this; } else if (path.replaceAll(_straySlashes, '').isEmpty) { for (Route route in children) { @@ -234,18 +234,24 @@ class Route { path[1] != '/' && absoluteParent != null) { return absoluteParent.resolve(path.substring(1), _filter); + } else if (matcher.hasMatch(path.replaceAll(_straySlashes, '')) || + _resolver.hasMatch(path.replaceAll(_straySlashes, ''))) { + return this; } else { - final segments = path.split('/'); + final segments = path.split('/').where((str) => str.isNotEmpty).toList(); if (segments[0] == '..') { if (parent != null) return parent.resolve(segments.skip(1).join('/'), _filter); else throw new RoutingException.orphan(); + } else if (segments[0] == '.') { + return resolve(segments.skip(1).join('/'), _filter); } for (Route route in children) { final subPath = '${this.path}/${segments[0]}'; + print('Subpath for $path on ${this.path} = $subPath'); if (route.match(subPath) != null || route._resolver.firstMatch(subPath) != null) { @@ -259,6 +265,8 @@ class Route { // Try to match the whole route, if nothing else works for (Route route in children) { + print( + 'Full path is $path, path is ${route.path}, matcher: ${route.matcher.pattern}, resolver: ${route._resolver.pattern}'); if ((route.match(path) != null || route._resolver.firstMatch(path) != null) && _filter(route)) diff --git a/test/index.html b/test/index.html new file mode 100644 index 00000000..d1cbd0f0 --- /dev/null +++ b/test/index.html @@ -0,0 +1,11 @@ + + + + + Tests + + + + + + \ No newline at end of file diff --git a/test/route/with_params.dart b/test/route/with_params.dart index 603f7714..1a8d0609 100644 --- a/test/route/with_params.dart +++ b/test/route/with_params.dart @@ -1,3 +1,64 @@ -main() { +import 'package:angel_route/angel_route.dart'; +import 'package:test/test.dart'; -} \ No newline at end of file +main() { + final base = new Route('foo'); + final foo = base.child(':id([0-9]+)', handlers: ['bar']); + final bar = foo.child('/bar'); + final baz = bar.child('//////baz//////', handlers: ['hello', 'world']); + + test('matching', () { + expect(foo.children.length, equals(1)); + expect(foo.handlers.length, equals(1)); + expect(foo.handlerSequence.length, equals(1)); + expect(foo.path, equals('foo/:id')); + expect(foo.match('/foo/2'), isNotNull); + expect(foo.match('/foo/aaa'), isNull); + expect(foo.match('/bar'), isNull); + expect(foo.match('/foolish'), isNull); + expect(foo.parent, equals(base)); + expect(foo.absoluteParent, equals(base)); + + expect(bar.path, equals('foo/:id/bar')); + expect(bar.children.length, equals(1)); + expect(bar.handlers, isEmpty); + expect(bar.handlerSequence.length, equals(1)); + expect(bar.match('/foo/2/bar'), isNotNull); + expect(bar.match('/bar'), isNull); + expect(bar.match('/foo/a/bar'), isNull); + expect(bar.parent, equals(foo)); + expect(baz.absoluteParent, equals(base)); + + expect(baz.children, isEmpty); + expect(baz.handlers.length, equals(2)); + expect(baz.handlerSequence.length, equals(3)); + expect(baz.path, equals('foo/:id/bar/baz')); + expect(baz.match('/foo/2A/bar/baz'), isNull); + expect(baz.match('/foo/2/bar/baz'), isNotNull); + expect(baz.match('/foo/1337/bar/baz'), isNotNull); + expect(baz.match('/foo/bat/baz'), isNull); + expect(baz.match('/foo/bar/baz/1'), isNull); + expect(baz.parent, equals(bar)); + expect(baz.absoluteParent, equals(base)); + }); + + test('hierarchy', () { + expect(foo.resolve('/foo/2'), equals(foo)); + + expect(foo.resolve('/foo/2/bar'), equals(bar)); + expect(foo.resolve('/foo/bar'), isNull); + expect(foo.resolve('foo/1337/bar/baz'), equals(baz)); + + expect(bar.resolve('..'), equals(foo)); + expect(bar.resolve('/bar/baz'), equals(baz)); + expect(bar.resolve('../bar'), equals(bar)); + + expect(baz.resolve('..'), equals(bar)); + expect(baz.resolve('../..'), equals(foo)); + expect(baz.resolve('../baz'), equals(baz)); + expect(baz.resolve('../../bar'), equals(bar)); + expect(baz.resolve('../../bar/baz'), equals(baz)); + expect(baz.resolve('/bar'), equals(bar)); + expect(baz.resolve('/bar/baz'), equals(baz)); + }); +} diff --git a/test/router/all_tests.dart b/test/router/all_tests.dart index aef587e4..fa157791 100644 --- a/test/router/all_tests.dart +++ b/test/router/all_tests.dart @@ -1,5 +1,6 @@ import 'package:angel_route/angel_route.dart'; import 'package:test/test.dart'; +import 'fallback.dart' as fallback; final ABC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; @@ -21,10 +22,12 @@ main() { router.dumpTree(); test('extensible', () { - router.two = 2; - expect(router.properties['two'], equals(2)); + router['two'] = 2; + expect(router.two, equals(2)); }); + group('fallback', fallback.main); + test('hierarchy', () { expect(lower.absoluteParent, equals(router.root)); expect(lower.parent.path, equals('letter/:id')); diff --git a/test/router/fallback.dart b/test/router/fallback.dart new file mode 100644 index 00000000..d6cd5472 --- /dev/null +++ b/test/router/fallback.dart @@ -0,0 +1,20 @@ +import 'package:angel_route/angel_route.dart'; +import 'package:test/test.dart'; + +bool checkPost(Route route) => route.method == "POST"; + +main() { + final router = new Router(); + + final userById = router.group('/user', (router) { + router.get('/:id', (id) => 'User $id'); + }).resolve(':id'); + + final fallback = router.get('*', () => 'fallback'); + + test('resolve', () { + expect(router.resolve('/foo'), equals(fallback)); + expect(router.resolve('/user/:id'), equals(userById)); + expect(router.resolve('/user/:id', checkPost), isNull); + }); +}