Updated route

This commit is contained in:
thomashii@dukefirehawk.com 2021-05-07 13:21:13 +08:00
parent f749264fbe
commit 5b3c589c8e
5 changed files with 38 additions and 26 deletions

View file

@ -72,6 +72,7 @@ hasMapTests(FutureOr<QueryExecutor> Function() createExecutor,
expect(await query.get(executor), isEmpty); expect(await query.get(executor), isEmpty);
}); });
// TODO: Failed test case
test('list equals', () async { test('list equals', () async {
var query = HasMapQuery(); var query = HasMapQuery();
query.where?.list.equals(['1', 2, 3.0]); query.where?.list.equals(['1', 2, 3.0]);

View file

@ -4,7 +4,7 @@ class RouteGrammar {
static const String notSlashRgx = r'([^/]+)'; static const String notSlashRgx = r'([^/]+)';
//static final RegExp rgx = RegExp(r'\((.+)\)'); //static final RegExp rgx = RegExp(r'\((.+)\)');
static final Parser<String> notSlash = static final Parser<String> notSlash =
match<String>(RegExp(notSlashRgx)).value((r) => r.span!.text); match<String>(RegExp(notSlashRgx)).value((r) => r.span?.text ?? '');
static final Parser<Match?> regExp = static final Parser<Match?> regExp =
match<Match?>(RegExp(r'\(([^\n)]+)\)([^/]+)?')) match<Match?>(RegExp(r'\(([^\n)]+)\)([^/]+)?'))

View file

@ -4,10 +4,11 @@ import 'router.dart';
class MiddlewarePipeline<T> { class MiddlewarePipeline<T> {
/// All the possible routes that matched the given path. /// All the possible routes that matched the given path.
final Iterable<RoutingResult<T>> routingResults; final Iterable<RoutingResult<T>> routingResults;
List<T>? _handlers; final List<T> _handlers = [];
/// An ordered list of every handler delegated to handle this request. /// An ordered list of every handler delegated to handle this request.
List<T>? get handlers { List<T> get handlers {
/*
if (_handlers != null) return _handlers; if (_handlers != null) return _handlers;
final handlers = <T>[]; final handlers = <T>[];
@ -16,6 +17,17 @@ class MiddlewarePipeline<T> {
} }
return _handlers = handlers; return _handlers = handlers;
*/
if (_handlers.isEmpty) {
return _handlers;
}
for (var result in routingResults) {
_handlers.addAll(result.allHandlers);
}
return _handlers;
} }
MiddlewarePipeline(Iterable<RoutingResult<T>> routingResults) MiddlewarePipeline(Iterable<RoutingResult<T>> routingResults)

View file

@ -65,7 +65,7 @@ class Router<T> {
/// for requests with the given method (case-insensitive). /// for requests with the given method (case-insensitive).
/// Provide '*' as the method to respond to all methods. /// Provide '*' as the method to respond to all methods.
Route<T> addRoute(String method, String path, T handler, Route<T> addRoute(String method, String path, T handler,
{Iterable<T>? middleware}) { {Iterable<T> middleware = const []}) {
if (_useCache == true) { if (_useCache == true) {
throw StateError('Cannot add routes after caching is enabled.'); throw StateError('Cannot add routes after caching is enabled.');
} }
@ -73,7 +73,7 @@ class Router<T> {
// Check if any mounted routers can match this // Check if any mounted routers can match this
final handlers = <T>[handler]; final handlers = <T>[handler];
middleware ??= <T>[]; //middleware ??= <T>[];
handlers.insertAll(0, middleware); handlers.insertAll(0, middleware);
@ -165,7 +165,7 @@ class Router<T> {
/// Returns the created route. /// Returns the created route.
/// You can also register middleware within the router. /// You can also register middleware within the router.
SymlinkRoute<T> group(String path, void Function(Router<T> router) callback, SymlinkRoute<T> group(String path, void Function(Router<T> router) callback,
{Iterable<T> middleware = const Iterable.empty(), String name = ''}) { {Iterable<T> middleware = const [], String name = ''}) {
final router = Router<T>().._middleware.addAll(middleware); final router = Router<T>().._middleware.addAll(middleware);
callback(router); callback(router);
return mount(path, router)..name = name; return mount(path, router)..name = name;
@ -174,8 +174,7 @@ class Router<T> {
/// Asynchronous equivalent of [group]. /// Asynchronous equivalent of [group].
Future<SymlinkRoute<T>> groupAsync( Future<SymlinkRoute<T>> groupAsync(
String path, FutureOr<void> Function(Router<T> router) callback, String path, FutureOr<void> Function(Router<T> router) callback,
{Iterable<T> middleware = const Iterable.empty(), {Iterable<T> middleware = const [], String name = ''}) async {
String name = ''}) async {
final router = Router<T>().._middleware.addAll(middleware); final router = Router<T>().._middleware.addAll(middleware);
await callback(router); await callback(router);
return mount(path, router)..name = name; return mount(path, router)..name = name;
@ -372,42 +371,43 @@ class Router<T> {
} }
/// Adds a route that responds to any request matching the given path. /// Adds a route that responds to any request matching the given path.
Route<T> all(String path, T handler, {Iterable<T>? middleware}) { Route<T> all(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('*', path, handler, middleware: middleware); return addRoute('*', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a DELETE request. /// Adds a route that responds to a DELETE request.
Route<T> delete(String path, T handler, {Iterable<T>? middleware}) { Route<T> delete(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('DELETE', path, handler, middleware: middleware); return addRoute('DELETE', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a GET request. /// Adds a route that responds to a GET request.
Route<T> get(String path, T handler, {Iterable<T>? middleware}) { Route<T> get(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('GET', path, handler, middleware: middleware); return addRoute('GET', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a HEAD request. /// Adds a route that responds to a HEAD request.
Route<T> head(String path, T handler, {Iterable<T>? middleware}) { Route<T> head(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('HEAD', path, handler, middleware: middleware); return addRoute('HEAD', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a OPTIONS request. /// Adds a route that responds to a OPTIONS request.
Route<T> options(String path, T handler, {Iterable<T>? middleware}) { Route<T> options(String path, T handler,
{Iterable<T> middleware = const {}}) {
return addRoute('OPTIONS', path, handler, middleware: middleware); return addRoute('OPTIONS', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a POST request. /// Adds a route that responds to a POST request.
Route<T> post(String path, T handler, {Iterable<T>? middleware}) { Route<T> post(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('POST', path, handler, middleware: middleware); return addRoute('POST', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a PATCH request. /// Adds a route that responds to a PATCH request.
Route<T> patch(String path, T handler, {Iterable<T>? middleware}) { Route<T> patch(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('PATCH', path, handler, middleware: middleware); return addRoute('PATCH', path, handler, middleware: middleware);
} }
/// Adds a route that responds to a PUT request. /// Adds a route that responds to a PUT request.
Route put(String path, T handler, {Iterable<T>? middleware}) { Route put(String path, T handler, {Iterable<T> middleware = const []}) {
return addRoute('PUT', path, handler, middleware: middleware); return addRoute('PUT', path, handler, middleware: middleware);
} }
} }
@ -424,8 +424,7 @@ class _ChainedRouter<T> extends Router<T> {
@override @override
Route<T> addRoute(String method, String path, handler, Route<T> addRoute(String method, String path, handler,
{Iterable<T>? middleware}) { {Iterable<T> middleware = const []}) {
middleware ??= <T>[];
var route = super.addRoute(method, path, handler, var route = super.addRoute(method, path, handler,
middleware: [..._handlers, ...middleware]); middleware: [..._handlers, ...middleware]);
//_root._routes.add(route); //_root._routes.add(route);
@ -434,8 +433,7 @@ class _ChainedRouter<T> extends Router<T> {
@override @override
SymlinkRoute<T> group(String path, void Function(Router<T> router) callback, SymlinkRoute<T> group(String path, void Function(Router<T> router) callback,
{Iterable<T>? middleware, String name = ''}) { {Iterable<T> middleware = const [], String? name}) {
middleware ??= <T>[];
final router = _ChainedRouter<T>(_root, [..._handlers, ...middleware]); final router = _ChainedRouter<T>(_root, [..._handlers, ...middleware]);
callback(router); callback(router);
return mount(path, router)..name = name; return mount(path, router)..name = name;
@ -444,8 +442,7 @@ class _ChainedRouter<T> extends Router<T> {
@override @override
Future<SymlinkRoute<T>> groupAsync( Future<SymlinkRoute<T>> groupAsync(
String path, FutureOr<void> Function(Router<T> router) callback, String path, FutureOr<void> Function(Router<T> router) callback,
{Iterable<T>? middleware, String name = ''}) async { {Iterable<T> middleware = const [], String? name}) async {
middleware ??= <T>[];
final router = _ChainedRouter<T>(_root, [..._handlers, ...middleware]); final router = _ChainedRouter<T>(_root, [..._handlers, ...middleware]);
await callback(router); await callback(router);
return mount(path, router)..name = name; return mount(path, router)..name = name;

View file

@ -87,12 +87,12 @@ void main() {
router.resolveAbsolute(req.uri.toString(), method: req.method); router.resolveAbsolute(req.uri.toString(), method: req.method);
final pipeline = MiddlewarePipeline(results); final pipeline = MiddlewarePipeline(results);
if (pipeline.handlers!.isEmpty) { if (pipeline.handlers.isEmpty) {
res res
..statusCode = 404 ..statusCode = 404
..writeln('404 Not Found'); ..writeln('404 Not Found');
} else { } else {
for (final handler in pipeline.handlers!) { for (final handler in pipeline.handlers) {
if (!((await handler(req, res)) as bool)) break; if (!((await handler(req, res)) as bool)) break;
} }
} }
@ -151,7 +151,8 @@ void main() {
group('mount', () { group('mount', () {
group('path', () { group('path', () {
test('top-level', () async { test('top-level', () async {
final res = await client!.post(Uri.parse('$url/beatles/spinal_clacker')); final res =
await client!.post(Uri.parse('$url/beatles/spinal_clacker'));
print('Response: ${res.body}'); print('Response: ${res.body}');
expect(res.body, equals('come together')); expect(res.body, equals('come together'));
}); });
@ -197,7 +198,8 @@ void main() {
await expect404(client!.head(Uri.parse(url!))); await expect404(client!.head(Uri.parse(url!)));
await expect404(client!.patch(Uri.parse('$url/people'))); await expect404(client!.patch(Uri.parse('$url/people')));
await expect404(client!.post(Uri.parse('$url/people/0'))); await expect404(client!.post(Uri.parse('$url/people/0')));
await expect404(client!.delete(Uri.parse('$url/beatles2/spinal_clacker'))); await expect404(
client!.delete(Uri.parse('$url/beatles2/spinal_clacker')));
}); });
}); });
} }