diff --git a/.idea/runConfigurations/All_Tests.xml b/.idea/runConfigurations/All_Tests.xml index ac11209e..482db2f9 100644 --- a/.idea/runConfigurations/All_Tests.xml +++ b/.idea/runConfigurations/All_Tests.xml @@ -2,6 +2,7 @@ \ No newline at end of file diff --git a/.idea/runConfigurations/parse_in_parse_test_dart.xml b/.idea/runConfigurations/parse_in_parse_test_dart.xml new file mode 100644 index 00000000..f37be7fe --- /dev/null +++ b/.idea/runConfigurations/parse_in_parse_test_dart.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 932dd204..5f30bc69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ -# 3.0.0-alpha +# 3.0.0 * Make `Router` and `Route` single-parameter generic. -* Remove `package:browser` dependency. \ No newline at end of file +* Remove `package:browser` dependency. +* `BrowserRouter.on` now only accepts a `String`. +* `MiddlewarePipeline.routingResults` now accepts +an `Iterable`, instead of just a `List`. +* Removed deprecated `Route.as`, as well as `Router.registerMiddleware`. +* Completely removed `Route.requestMiddleware`. \ No newline at end of file diff --git a/lib/browser.dart b/lib/browser.dart index e6cffb80..97ac1d34 100644 --- a/lib/browser.dart +++ b/lib/browser.dart @@ -39,7 +39,7 @@ abstract class BrowserRouter extends Router { void listen(); /// Identical to [all]. - Route on(Pattern path, handler, {List middleware}); + Route on(String path, handler, {List middleware}); } abstract class _BrowserRouterImpl extends Router implements BrowserRouter { @@ -64,7 +64,7 @@ abstract class _BrowserRouterImpl extends Router implements BrowserRouter { @override void go(Iterable linkParams) => _goTo(navigate(linkParams)); - Route on(Pattern path, handler, {List middleware}) => + Route on(String path, handler, {List middleware}) => all(path, handler, middleware: middleware); void prepareAnchors() { @@ -176,7 +176,7 @@ class _PushStateRouter extends _BrowserRouterImpl { void handleState(state) { if (state is Map && state.containsKey('path')) { - var path = state['path']; + var path = state['path'].toString(); final resolved = resolveAbsolute(path).first; if (resolved != null && resolved.route != _current) { diff --git a/lib/src/grammar.dart b/lib/src/grammar.dart index 870264a4..bc038768 100644 --- a/lib/src/grammar.dart +++ b/lib/src/grammar.dart @@ -2,13 +2,13 @@ part of angel_route.src.router; class RouteGrammar { static final Parser notSlash = - match(new RegExp(r'[^/]+')).value((r) => r.span.text); + match(new RegExp(r'[^/]+')).value((r) => r.span.text); static final Parser regExp = match(new RegExp(r'\((.+)\)')) .value((r) => new RegExp(r.scanner.lastMatch[1])); static final Parser parameterName = - match(new RegExp(r':([A-Za-z0-9_]+)')) + match(new RegExp(r':([A-Za-z0-9_]+)')) .value((r) => r.span.text.substring(1)); static final Parser parameterSegment = chain([ @@ -16,7 +16,7 @@ class RouteGrammar { match('?').value((r) => true).opt(), regExp.opt(), ]).map((r) { - var s = new ParameterSegment(r.value[0], r.value[2]); + var s = new ParameterSegment(r.value[0] as String, r.value[2] as RegExp); return r.value[1] == true ? new OptionalSegment(s) : s; }); @@ -26,16 +26,17 @@ class RouteGrammar { .map((r) => r.span.text), parameterSegment, ]).map((r) { - return new ParsedParameterSegment(r.value[0], r.value[1]); + return new ParsedParameterSegment( + r.value[0] as String, r.value[1] as ParameterSegment); }); static final Parser wildcardSegment = - match('*').value((r) => new WildcardSegment()); + match('*').value((r) => new WildcardSegment()); static final Parser constantSegment = - notSlash.map((r) => new ConstantSegment(r.value)); + notSlash.map((r) => new ConstantSegment(r.value)); - static final Parser routeSegment = any([ + static final Parser routeSegment = any([ parsedParameterSegment, parameterSegment, wildcardSegment, @@ -62,7 +63,8 @@ class RouteDefinition { if (out == null) out = s.compile(isLast); else - out = s.compileNext(out.then(match('/')).index(0), isLast); + out = s.compileNext( + out.then(match('/')).index(0).cast>(), isLast); } return out; @@ -88,13 +90,13 @@ class ConstantSegment extends RouteSegment { @override Parser> compile(bool isLast) { - return match(text).value((r) => {}); + return match>(text).value((r) => {}); } @override Parser> compileNext( Parser> p, bool isLast) { - return p.then(compile(isLast)).index(0); + return p.then(compile(isLast)).index(0).cast>(); } } @@ -117,7 +119,7 @@ class WildcardSegment extends RouteSegment { @override Parser> compileNext( Parser> p, bool isLast) { - return p.then(_compile(isLast)).index(0); + return p.then(_compile(isLast)).index(0).cast>(); } } @@ -140,8 +142,9 @@ class OptionalSegment extends ParameterSegment { Parser> compileNext( Parser> p, bool isLast) { return p.then(_compile().opt()).map((r) { - if (r.value[1] == null) return r.value[0]; - return r.value[0]..addAll({name: Uri.decodeComponent(r.value[1])}); + if (r.value[1] == null) return r.value[0] as Map; + return (r.value[0] as Map) + ..addAll({name: Uri.decodeComponent(r.value[1] as String)}); }); } } @@ -158,22 +161,24 @@ class ParameterSegment extends RouteSegment { return 'Param: $name'; } - Parser> _compile() { + Parser _compile() { return regExp != null - ? match(regExp).value((r) => r.span.text) + ? match(regExp).value((r) => r.span.text) : RouteGrammar.notSlash; } @override Parser> compile(bool isLast) { - return _compile().map((r) => {name: Uri.decodeComponent(r.span.text)}); + return _compile().map>( + (r) => {name: Uri.decodeComponent(r.span.text)}); } @override Parser> compileNext( Parser> p, bool isLast) { return p.then(_compile()).map((r) { - return r.value[0]..addAll({name: Uri.decodeComponent(r.value[1])}); + return (r.value[0] as Map) + ..addAll({name: Uri.decodeComponent(r.value[1] as String)}); }); } } @@ -205,8 +210,10 @@ class ParsedParameterSegment extends RouteSegment { Parser> compileNext( Parser> p, bool isLast) { return p.then(parameter._compile()).map((r) { - return r.value[0] - ..addAll({parameter.name: getValue(Uri.decodeComponent(r.value[1]))}); + return (r.value[0] as Map) + ..addAll({ + parameter.name: getValue(Uri.decodeComponent(r.value[1] as String)) + }); }); } } diff --git a/lib/src/middleware_pipeline.dart b/lib/src/middleware_pipeline.dart index 267a4edc..141d9e66 100644 --- a/lib/src/middleware_pipeline.dart +++ b/lib/src/middleware_pipeline.dart @@ -1,17 +1,17 @@ import 'router.dart'; /// A chain of arbitrary handlers obtained by routing a path. -class MiddlewarePipeline { +class MiddlewarePipeline { /// All the possible routes that matched the given path. - final List routingResults; - List _handlers; + final Iterable> routingResults; + List _handlers; /// An ordered list of every handler delegated to handle this request. - List get handlers { + List get handlers { if (_handlers != null) return _handlers; - final handlers = []; + final handlers = []; - for (RoutingResult result in routingResults) { + for (var result in routingResults) { handlers.addAll(result.allHandlers); } diff --git a/lib/src/route.dart b/lib/src/route.dart index 5ce9ec7e..c17d7891 100644 --- a/lib/src/route.dart +++ b/lib/src/route.dart @@ -1,10 +1,10 @@ part of angel_route.src.router; /// Represents a virtual location within an application. -class Route { +class Route { final String method; final String path; - final List handlers; + final List handlers; final Map> _cache = {}; final RouteDefinition _routeDefinition; String name; @@ -14,10 +14,12 @@ class Route { : _routeDefinition = RouteGrammar.routeDefinition .parse(new SpanScanner(path.replaceAll(_straySlashes, ''))) .value { - if (_routeDefinition.segments.isEmpty) _parser = match('').value((r) => {}); + if (_routeDefinition?.segments?.isNotEmpty != true) + _parser = + match>('').value((r) => {}); } - factory Route.join(Route a, Route b) { + factory Route.join(Route a, Route b) { var start = a.path.replaceAll(_straySlashes, ''); var end = b.path.replaceAll(_straySlashes, ''); return new Route('$start/$end'.replaceAll(_straySlashes, ''), @@ -27,23 +29,16 @@ class Route { Parser> get parser => _parser ??= _routeDefinition.compile(); - @override String toString() { return '$method $path => $handlers'; } - Route clone() { - return new Route(path, method: method, handlers: handlers) + Route clone() { + return new Route(path, method: method, handlers: handlers) .._cache.addAll(_cache); } - /// Use the setter instead. - @deprecated - void as(String n) { - name = n; - } - String makeUri(Map params) { var b = new StringBuffer(); int i = 0; diff --git a/lib/src/router.dart b/lib/src/router.dart index fb26c83c..052e9732 100644 --- a/lib/src/router.dart +++ b/lib/src/router.dart @@ -3,42 +3,46 @@ library angel_route.src.router; import 'package:combinator/combinator.dart'; import 'package:meta/meta.dart'; import 'package:string_scanner/string_scanner.dart'; -import 'routing_exception.dart'; + import '../string_util.dart'; +import 'routing_exception.dart'; + part 'grammar.dart'; -part 'symlink_route.dart'; + part 'route.dart'; + part 'routing_result.dart'; -final RegExp _param = new RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?'); -final RegExp _rgxEnd = new RegExp(r'\$+$'); -final RegExp _rgxStart = new RegExp(r'^\^+'); -final RegExp _rgxStraySlashes = - new RegExp(r'(^((\\+/)|(/))+)|(((\\+/)|(/))+$)'); -final RegExp _slashDollar = new RegExp(r'/+\$'); +part 'symlink_route.dart'; + +//final RegExp _param = new RegExp(r':([A-Za-z0-9_]+)(\((.+)\))?'); +//final RegExp _rgxEnd = new RegExp(r'\$+$'); +//final RegExp _rgxStart = new RegExp(r'^\^+'); +//final RegExp _rgxStraySlashes = +// new RegExp(r'(^((\\+/)|(/))+)|(((\\+/)|(/))+$)'); +//final RegExp _slashDollar = new RegExp(r'/+\$'); final RegExp _straySlashes = new RegExp(r'(^/+)|(/+$)'); /// An abstraction over complex [Route] trees. Use this instead of the raw API. :) -class Router { +class Router { final Map> _cache = {}; + //final List<_ChainedRouter> _chained = []; - final List _middleware = []; - final Map _mounted = {}; - final List _routes = []; + final List _middleware = []; + final Map> _mounted = {}; + final List> _routes = []; bool _useCache = false; - List get middleware => new List.unmodifiable(_middleware); + List get middleware => new List.unmodifiable(_middleware); Map get mounted => new Map.unmodifiable(_mounted); - /// Additional filters to be run on designated requests. - Map requestMiddleware = {}; - - List get routes { - return _routes.fold>([], (out, route) { - if (route is SymlinkRoute) { - var childRoutes = route.router.routes.fold>([], (out, r) { + List> get routes { + return _routes.fold>>([], (out, route) { + if (route is SymlinkRoute) { + var childRoutes = + route.router.routes.fold>>([], (out, r) { return out ..add( route.path.isEmpty ? r : new Route.join(route, r), @@ -64,46 +68,44 @@ class Router { /// Adds a route that responds to the given path /// for requests with the given method (case-insensitive). /// Provide '*' as the method to respond to all methods. - Route addRoute(String method, String path, Object handler, - {List middleware: const []}) { + Route addRoute(String method, String path, T handler, + {Iterable middleware: const []}) { if (_useCache == true) throw new StateError('Cannot add routes after caching is enabled.'); // Check if any mounted routers can match this - final handlers = [handler]; + final handlers = [handler]; if (middleware != null) handlers.insertAll(0, middleware); - final route = new Route(path, method: method, handlers: handlers); + final route = new Route(path, method: method, handlers: handlers); _routes.add(route); return route; } - /// Prepends the given middleware to any routes created + /// Prepends the given [middleware] to any routes created /// by the resulting router. /// - /// [middleware] can be either an `Iterable`, or a single object. - /// /// The resulting router can be chained, too. - _ChainedRouter chain(middleware) { - var piped = new _ChainedRouter(this, middleware); - var route = new SymlinkRoute('/', piped); + _ChainedRouter chain(Iterable middleware) { + var piped = new _ChainedRouter(this, middleware); + var route = new SymlinkRoute('/', piped); _routes.add(route); return piped; } /// Returns a [Router] with a duplicated version of this tree. - Router clone() { - final router = new Router(); - final newMounted = new Map.from(mounted); + Router clone() { + final router = new Router(); + final newMounted = new Map>.from(mounted); - for (Route route in routes) { - if (route is! SymlinkRoute) { + for (var route in routes) { + if (route is! SymlinkRoute) { router._routes.add(route.clone()); - } else if (route is SymlinkRoute) { + } else if (route is SymlinkRoute) { final newRouter = route.router.clone(); newMounted[route.path] = newRouter; - final symlink = new SymlinkRoute(route.path, newRouter); + final symlink = new SymlinkRoute(route.path, newRouter); router._routes.add(symlink); } } @@ -161,13 +163,11 @@ class Router { /// /// Returns the created route. /// You can also register middleware within the router. - SymlinkRoute group(String path, void callback(Router router), - {Iterable middleware: const [], - String name: null, - String namespace: null}) { - final router = new Router().._middleware.addAll(middleware); + SymlinkRoute group(String path, void callback(Router router), + {Iterable middleware: const [], String name: null}) { + final router = new Router().._middleware.addAll(middleware); callback(router); - return mount(path, router, namespace: namespace)..name = name; + return mount(path, router)..name = name; } /// Generates a URI string based on the given input. @@ -265,12 +265,6 @@ class Router { : segments.join('/'); } - /// Manually assign via [requestMiddleware] instead. - @deprecated - registerMiddleware(String name, middleware) { - requestMiddleware[name] = middleware; - } - /// Finds the first [Route] that matches the given path, /// with the given method. bool resolve(String absolute, String relative, List out, @@ -344,122 +338,97 @@ class Router { } /// Incorporates another [Router]'s routes into this one's. - /// - /// If `hooked` is set to `true` and a [Service] is provided, - /// then that service will be wired to a [HookedService] proxy. - /// If a `namespace` is provided, then any middleware - /// from the provided [Router] will be prefixed by that namespace, - /// with a dot. - /// For example, if the [Router] has a middleware 'y', and the `namespace` - /// is 'x', then that middleware will be available as 'x.y' in the main router. - /// These namespaces can be nested. - SymlinkRoute mount(String path, Router router, - {bool hooked: true, String namespace: null}) { - // Let's copy middleware, heeding the optional middleware namespace. - String middlewarePrefix = namespace != null ? "$namespace." : ""; - - Map copiedMiddleware = new Map.from(router.requestMiddleware); - for (String middlewareName in copiedMiddleware.keys) { - requestMiddleware["$middlewarePrefix$middlewareName"] = - copiedMiddleware[middlewareName]; - } - - final route = new SymlinkRoute(path, router); + SymlinkRoute mount(String path, Router router) { + final route = new SymlinkRoute(path, router); _mounted[route.path] = router; _routes.add(route); //route._head = new RegExp(route.matcher.pattern.replaceAll(_rgxEnd, '')); - return route..name = namespace; + return route; } /// Adds a route that responds to any request matching the given path. - Route all(String path, Object handler, {List middleware}) { + Route all(String path, T handler, {Iterable middleware}) { return addRoute('*', path, handler, middleware: middleware); } /// Adds a route that responds to a DELETE request. - Route delete(String path, Object handler, {List middleware}) { + Route delete(String path, T handler, {Iterable middleware}) { return addRoute('DELETE', path, handler, middleware: middleware); } /// Adds a route that responds to a GET request. - Route get(String path, Object handler, {List middleware}) { + Route get(String path, T handler, {Iterable middleware}) { return addRoute('GET', path, handler, middleware: middleware); } /// Adds a route that responds to a HEAD request. - Route head(String path, Object handler, {List middleware}) { + Route head(String path, T handler, {Iterable middleware}) { return addRoute('HEAD', path, handler, middleware: middleware); } /// Adds a route that responds to a OPTIONS request. - Route options(String path, Object handler, {List middleware}) { + Route options(String path, T handler, {Iterable middleware}) { return addRoute('OPTIONS', path, handler, middleware: middleware); } /// Adds a route that responds to a POST request. - Route post(String path, Object handler, {List middleware}) { + Route post(String path, T handler, {Iterable middleware}) { return addRoute('POST', path, handler, middleware: middleware); } /// Adds a route that responds to a PATCH request. - Route patch(String path, Object handler, {List middleware}) { + Route patch(String path, T handler, {Iterable middleware}) { return addRoute('PATCH', path, handler, middleware: middleware); } /// Adds a route that responds to a PUT request. - Route put(String path, Object handler, {List middleware}) { + Route put(String path, T handler, {Iterable middleware}) { return addRoute('PUT', path, handler, middleware: middleware); } } -class _ChainedRouter extends Router { - final List _handlers = []; +class _ChainedRouter extends Router { + final List _handlers = []; Router _root; _ChainedRouter.empty(); - _ChainedRouter(Router root, middleware) { + _ChainedRouter(Router root, Iterable middleware) { this._root = root; - _handlers.addAll(middleware is Iterable ? middleware : [middleware]); + _handlers.addAll(middleware); } @override - Route addRoute(String method, String path, handler, - {List middleware: const []}) { + Route addRoute(String method, String path, handler, + {Iterable middleware: const []}) { var route = super.addRoute(method, path, handler, middleware: []..addAll(_handlers)..addAll(middleware ?? [])); //_root._routes.add(route); return route; } - SymlinkRoute group(String path, void callback(Router router), - {Iterable middleware: const [], - String name: null, - String namespace: null}) { + SymlinkRoute group(String path, void callback(Router router), + {Iterable middleware: const [], String name: null}) { final router = - new _ChainedRouter(_root, []..addAll(_handlers)..addAll(middleware)); + new _ChainedRouter(_root, []..addAll(_handlers)..addAll(middleware)); callback(router); - return mount(path, router, namespace: namespace)..name = name; + return mount(path, router)..name = name; } @override - SymlinkRoute mount(String path, Router router, - {bool hooked: true, String namespace: null}) { - final route = - super.mount(path, router, hooked: hooked, namespace: namespace); + SymlinkRoute mount(String path, Router router) { + final route = super.mount(path, router); route.router._middleware.insertAll(0, _handlers); //_root._routes.add(route); return route; } @override - _ChainedRouter chain(middleware) { - final piped = new _ChainedRouter.empty().._root = _root; - piped._handlers.addAll([] - ..addAll(_handlers) - ..addAll(middleware is Iterable ? middleware : [middleware])); - var route = new SymlinkRoute('/', piped); + _ChainedRouter chain(Iterable middleware) { + final piped = new _ChainedRouter.empty().._root = _root; + piped._handlers.addAll([]..addAll(_handlers)..addAll(middleware)); + var route = new SymlinkRoute('/', piped); _routes.add(route); return piped; } @@ -467,14 +436,12 @@ class _ChainedRouter extends Router { /// Optimizes a router by condensing all its routes into one level. Router flatten(Router router) { - var flattened = new Router() - ..requestMiddleware.addAll(router.requestMiddleware); + var flattened = new Router(); for (var route in router.routes) { if (route is SymlinkRoute) { var base = route.path.replaceAll(_straySlashes, ''); var child = flatten(route.router); - flattened.requestMiddleware.addAll(child.requestMiddleware); for (var route in child.routes) { var path = route.path.replaceAll(_straySlashes, ''); diff --git a/lib/src/routing_result.dart b/lib/src/routing_result.dart index cd22be81..38a2bd3a 100644 --- a/lib/src/routing_result.dart +++ b/lib/src/routing_result.dart @@ -1,12 +1,12 @@ part of angel_route.src.router; /// Represents a complex result of navigating to a path. -class RoutingResult { +class RoutingResult { /// The parse result that matched the given sub-path. final ParseResult> parseResult; /// A nested instance, if a sub-path was matched. - final Iterable nested; + final Iterable> nested; /// All route params matching this route on the current sub-path. final Map params = {}; @@ -14,18 +14,18 @@ class RoutingResult { /// The [Route] that answered this sub-path. /// /// This is mostly for internal use, and useless in production. - final Route shallowRoute; + final Route shallowRoute; /// The [Router] that answered this sub-path. /// /// Only really for internal use. - final Router shallowRouter; + final Router shallowRouter; /// The remainder of the full path that was not matched, and was passed to [nested] routes. final String tail; /// The [RoutingResult] that matched the most specific sub-path. - RoutingResult get deepest { + RoutingResult get deepest { var search = this; while (search?.nested?.isNotEmpty == true) search = search.nested.first; @@ -34,21 +34,21 @@ class RoutingResult { } /// The most specific route. - Route get route => deepest.shallowRoute; + Route get route => deepest.shallowRoute; /// The most specific router. - Router get router => deepest.shallowRouter; + Router get router => deepest.shallowRouter; /// The handlers at this sub-path. - List get handlers { - return []..addAll(shallowRouter.middleware)..addAll(shallowRoute.handlers); + List get handlers { + return []..addAll(shallowRouter.middleware)..addAll(shallowRoute.handlers); } /// All handlers on this sub-path and its children. - List get allHandlers { - final handlers = []; + List get allHandlers { + final handlers = []; - void crawl(RoutingResult result) { + void crawl(RoutingResult result) { handlers.addAll(result.handlers); if (result.nested?.isNotEmpty == true) { diff --git a/lib/src/symlink_route.dart b/lib/src/symlink_route.dart index 9d9dcfe8..cf3a3cf2 100644 --- a/lib/src/symlink_route.dart +++ b/lib/src/symlink_route.dart @@ -2,7 +2,7 @@ part of angel_route.src.router; /// Placeholder [Route] to serve as a symbolic link /// to a mounted [Router]. -class SymlinkRoute extends Route { - final Router router; +class SymlinkRoute extends Route { + final Router router; SymlinkRoute(String path, this.router) : super(path, method: null, handlers: null); } diff --git a/pubspec.yaml b/pubspec.yaml index 0a2e9fb0..34ce7553 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: angel_route description: A powerful, isomorphic routing library for Dart. It is mainly used in the Angel framework, but can be used in Flutter and on the Web. -version: 3.0.0-alpha +version: 3.0.0 author: Tobe O homepage: https://github.com/angel-dart/angel_route environment: diff --git a/test/chain_nest_test.dart b/test/chain_nest_test.dart index e1446114..0feeae3b 100644 --- a/test/chain_nest_test.dart +++ b/test/chain_nest_test.dart @@ -2,9 +2,9 @@ import 'package:angel_route/angel_route.dart'; import 'package:test/test.dart'; main() { - var router = new Router() - ..chain('a').group('/b', (router) { - router.chain('c').chain('d').group('/e', (router) { + var router = new Router() + ..chain(['a']).group('/b', (router) { + router.chain(['c']).chain(['d']).group('/e', (router) { router.get('f', 'g'); }); }) diff --git a/test/navigate_test.dart b/test/navigate_test.dart index befff514..06df68ef 100644 --- a/test/navigate_test.dart +++ b/test/navigate_test.dart @@ -9,7 +9,7 @@ main() { router.get('/first/:first/last/:last', 'GET').name = 'full_name'; navigate(params) { - final uri = router.navigate(params); + final uri = router.navigate(params as Iterable); print('Uri: $uri'); return uri; } diff --git a/test/parse_test.dart b/test/parse_test.dart index ab90526b..3a7d0fd8 100644 --- a/test/parse_test.dart +++ b/test/parse_test.dart @@ -9,7 +9,7 @@ void main() { num getId(String path) { var result = router.resolveAbsolute(path).first; - return result.allParams['id']; + return result.allParams['id'] as num; } test('parse', () { diff --git a/test/server_test.dart b/test/server_test.dart index d926ffee..11a7abdc 100644 --- a/test/server_test.dart +++ b/test/server_test.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; + import 'package:angel_route/angel_route.dart'; import 'package:http/http.dart' as http; import 'package:test/test.dart'; @@ -76,7 +77,7 @@ main() { client = new http.Client(); router.dumpTree(); - server = await HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0); + server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0); url = 'http://${server.address.address}:${server.port}'; server.listen((req) async { @@ -89,11 +90,11 @@ main() { if (pipeline.handlers.isEmpty) { res - ..statusCode = HttpStatus.NOT_FOUND + ..statusCode = 404 ..writeln('404 Not Found'); } else { for (final handler in pipeline.handlers) { - if (!await handler(req, res)) break; + if (!((await handler(req, res)) as bool)) break; } }