Params will be fixed :)

This commit is contained in:
thosakwe 2016-10-13 16:50:27 -04:00
parent 051a253636
commit ceb66dd520
13 changed files with 154 additions and 17 deletions

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Route Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Route Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/route/all_tests.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Router Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Router Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/router/all_tests.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Fallback" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Router Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/router/fallback.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="No Params" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Route Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/route/no_params.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Parse Params" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Route Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/route/parse_params.dart" />
<method />
</configuration>
</component>

View file

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="With Params" type="DartTestRunConfigurationType" factoryName="Dart Test" folderName="Route Tests" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/route/with_params.dart" />
<method />
</configuration>
</component>

View file

@ -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';
});
}
```

View file

@ -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;
}
}

View file

@ -185,9 +185,10 @@ class Route {
Map parseParameters(String requestPath) {
Map result = {};
Iterable<String> values = _parseParameters(requestPath.replaceAll(_straySlashes, ''));
Iterable<Match> matches = _param.allMatches(
_pathified.replaceAll(new RegExp('\/'), r'\/'));
Iterable<String> values =
_parseParameters(requestPath.replaceAll(_straySlashes, ''));
Iterable<Match> 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))

11
test/index.html Normal file
View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tests</title>
</head>
<body>
<script src="all_tests.dart" type="application/dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>

View file

@ -1,3 +1,64 @@
main() {
import 'package:angel_route/angel_route.dart';
import 'package:test/test.dart';
}
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));
});
}

View file

@ -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'));

20
test/router/fallback.dart Normal file
View file

@ -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);
});
}