Hooks redesigned
This commit is contained in:
parent
6cc9967b3e
commit
42023ca374
9 changed files with 300 additions and 111 deletions
|
@ -56,9 +56,23 @@ class Routable extends Extensible {
|
||||||
/// is 'x', then that middleware will be available as 'x.y' in the main application.
|
/// is 'x', then that middleware will be available as 'x.y' in the main application.
|
||||||
/// These namespaces can be nested.
|
/// These namespaces can be nested.
|
||||||
use(Pattern path, Routable routable,
|
use(Pattern path, Routable routable,
|
||||||
{bool hooked: false, String middlewareNamespace: null}) {
|
{bool hooked: true, String middlewareNamespace: null}) {
|
||||||
requestMiddleware.addAll(routable.requestMiddleware);
|
Routable _routable = routable;
|
||||||
for (Route route in routable.routes) {
|
|
||||||
|
// If we need to hook this service, do it here. It has to be first, or
|
||||||
|
// else all routes will point to the old service.
|
||||||
|
if (_routable is Service) {
|
||||||
|
Hooked hookedDeclaration = _getAnnotation(_routable, Hooked);
|
||||||
|
Service service = (hookedDeclaration != null || hooked)
|
||||||
|
? new HookedService(_routable)
|
||||||
|
: _routable;
|
||||||
|
services[path.toString().trim().replaceAll(
|
||||||
|
new RegExp(r'(^\/+)|(\/+$)'), '')] = service;
|
||||||
|
_routable = service;
|
||||||
|
}
|
||||||
|
|
||||||
|
requestMiddleware.addAll(_routable.requestMiddleware);
|
||||||
|
for (Route route in _routable.routes) {
|
||||||
Route provisional = new Route('', path);
|
Route provisional = new Route('', path);
|
||||||
if (route.path == '/') {
|
if (route.path == '/') {
|
||||||
route.path = '';
|
route.path = '';
|
||||||
|
@ -77,25 +91,16 @@ class Routable extends Extensible {
|
||||||
if (middlewareNamespace != null)
|
if (middlewareNamespace != null)
|
||||||
middlewarePrefix = "$middlewareNamespace.";
|
middlewarePrefix = "$middlewareNamespace.";
|
||||||
|
|
||||||
for (String middlewareName in routable.requestMiddleware.keys) {
|
for (String middlewareName in _routable.requestMiddleware.keys) {
|
||||||
requestMiddleware["$middlewarePrefix$middlewareName"] =
|
requestMiddleware["$middlewarePrefix$middlewareName"] =
|
||||||
routable.requestMiddleware[middlewareName];
|
_routable.requestMiddleware[middlewareName];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy services, too. :)
|
// Copy services, too. :)
|
||||||
for (Pattern servicePath in routable.services.keys) {
|
for (Pattern servicePath in _routable.services.keys) {
|
||||||
String newServicePath = path.toString().trim().replaceAll(
|
String newServicePath = path.toString().trim().replaceAll(
|
||||||
new RegExp(r'(^\/+)|(\/+$)'), '') + '/$servicePath';
|
new RegExp(r'(^\/+)|(\/+$)'), '') + '/$servicePath';
|
||||||
services[newServicePath] = routable.services[servicePath];
|
services[newServicePath] = _routable.services[servicePath];
|
||||||
}
|
|
||||||
|
|
||||||
if (routable is Service) {
|
|
||||||
Hooked hookedDeclaration = _getAnnotation(routable, Hooked);
|
|
||||||
Service service = (hookedDeclaration != null || hooked)
|
|
||||||
? new HookedService(routable)
|
|
||||||
: routable;
|
|
||||||
services[path.toString().trim().replaceAll(
|
|
||||||
new RegExp(r'(^\/+)|(\/+$)'), '')] = service;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ class Angel extends Routable {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
use(Pattern path, Routable routable,
|
use(Pattern path, Routable routable,
|
||||||
{bool hooked: false, String middlewareNamespace: null}) {
|
{bool hooked: true, String middlewareNamespace: null}) {
|
||||||
if (routable is Service) {
|
if (routable is Service) {
|
||||||
routable.app = this;
|
routable.app = this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,20 +48,20 @@ class Service extends Routable {
|
||||||
Service() : super() {
|
Service() : super() {
|
||||||
Map restProvider = {'provider': Providers.REST};
|
Map restProvider = {'provider': Providers.REST};
|
||||||
|
|
||||||
get('/', (req, res) async => await this.index(
|
get('/', (req, res) async {
|
||||||
mergeMap([req.query, restProvider])));
|
return await this.index(mergeMap([req.query, restProvider]));
|
||||||
|
});
|
||||||
|
|
||||||
post('/', (req, res) async => await this.create(
|
post('/', (req, res) async => await this.create(req.body, restProvider));
|
||||||
mergeMap([req.body, restProvider])));
|
|
||||||
|
|
||||||
get('/:id', (req, res) async =>
|
get('/:id', (req, res) async =>
|
||||||
await this.read(req.params['id'], mergeMap([req.query, restProvider])));
|
await this.read(req.params['id'], mergeMap([req.query, restProvider])));
|
||||||
|
|
||||||
patch('/:id', (req, res) async => await this.modify(
|
patch('/:id', (req, res) async => await this.modify(
|
||||||
req.params['id'], mergeMap([req.body, restProvider])));
|
req.params['id'], req.body, restProvider));
|
||||||
|
|
||||||
post('/:id', (req, res) async => await this.update(
|
post('/:id', (req, res) async => await this.update(
|
||||||
req.params['id'], mergeMap([req.body, restProvider])));
|
req.params['id'], req.body, restProvider));
|
||||||
|
|
||||||
delete('/:id', (req, res) async => await this.remove(
|
delete('/:id', (req, res) async => await this.remove(
|
||||||
req.params['id'], mergeMap([req.query, restProvider])));
|
req.params['id'], mergeMap([req.query, restProvider])));
|
||||||
|
|
|
@ -2,107 +2,162 @@ part of angel_framework.http;
|
||||||
|
|
||||||
/// Wraps another service in a service that broadcasts events on actions.
|
/// Wraps another service in a service that broadcasts events on actions.
|
||||||
class HookedService extends Service {
|
class HookedService extends Service {
|
||||||
StreamController<HookedServiceEvent> _beforeIndexed = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _beforeRead = new StreamController.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _beforeCreated = new StreamController.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _beforeModified = new StreamController.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _beforeUpdated = new StreamController.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _beforeRemoved = new StreamController.broadcast();
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeIndexed => _beforeIndexed.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeRead => _beforeRead.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeCreated => _beforeCreated.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeModified => _beforeModified.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeUpdated => _beforeUpdated.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get beforeRemoved => _beforeRemoved.stream;
|
|
||||||
|
|
||||||
StreamController<HookedServiceEvent> _afterIndexed = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _afterRead = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _afterCreated = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _afterModified = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _afterUpdated = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
StreamController<HookedServiceEvent> _afterRemoved = new StreamController<HookedServiceEvent>.broadcast();
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterIndexed => _afterIndexed.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterRead => _afterRead.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterCreated => _afterCreated.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterModified => _afterModified.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterUpdated => _afterUpdated.stream;
|
|
||||||
|
|
||||||
Stream<HookedServiceEvent> get afterRemoved => _afterRemoved.stream;
|
|
||||||
|
|
||||||
final Service inner;
|
final Service inner;
|
||||||
|
|
||||||
HookedService(Service this.inner);
|
HookedServiceEventDispatcher beforeIndexed =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher beforeRead = new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher beforeCreated =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher beforeModified =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher beforeUpdated =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher beforeRemoved =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterIndexed =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterRead = new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterCreated =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterModified =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterUpdated =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
HookedServiceEventDispatcher afterRemoved =
|
||||||
|
new HookedServiceEventDispatcher();
|
||||||
|
|
||||||
|
HookedService(Service this.inner) : super() {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List> index([Map params]) async {
|
Future<List> index([Map params]) async {
|
||||||
HookedServiceEvent before = new HookedServiceEvent._base(inner, params: params);
|
HookedServiceEvent before = await beforeIndexed._emit(
|
||||||
_beforeIndexed.add(before);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.INDEXED,
|
||||||
|
params: params));
|
||||||
if (before._canceled) {
|
if (before._canceled) {
|
||||||
HookedServiceEvent after = new HookedServiceEvent._base(inner, params: params, result: before.result);
|
HookedServiceEvent after = await beforeIndexed._emit(
|
||||||
_afterIndexed.add(after);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.INDEXED,
|
||||||
return before.result;
|
params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
List result = await inner.index(params);
|
List result = await inner.index(params);
|
||||||
HookedServiceEvent after = new HookedServiceEvent._base(inner, params: params, result: result);
|
HookedServiceEvent after = await afterIndexed._emit(
|
||||||
_afterIndexed.add(after);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.INDEXED,
|
||||||
return result;
|
params: params, result: result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future read(id, [Map params]) async {
|
Future read(id, [Map params]) async {
|
||||||
var retrieved = await inner.read(id, params);
|
HookedServiceEvent before = await beforeRead._emit(
|
||||||
_afterRead.add(retrieved);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.READ,
|
||||||
return retrieved;
|
id: id, params: params));
|
||||||
|
|
||||||
|
if (before._canceled) {
|
||||||
|
HookedServiceEvent after = await afterRead._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.READ,
|
||||||
|
id: id, params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result = await inner.read(id, params);
|
||||||
|
HookedServiceEvent after = await afterRead._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.READ,
|
||||||
|
id: id, params: params, result: result));
|
||||||
|
return after.result;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future create(data, [Map params]) async {
|
Future create(data, [Map params]) async {
|
||||||
var created = await inner.create(data, params);
|
HookedServiceEvent before = await beforeCreated._emit(
|
||||||
_afterCreated.add(created);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.CREATED,
|
||||||
return created;
|
data: data, params: params));
|
||||||
|
|
||||||
|
if (before._canceled) {
|
||||||
|
HookedServiceEvent after = await afterCreated._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.CREATED,
|
||||||
|
data: data, params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await inner.create(data, params);
|
||||||
|
HookedServiceEvent after = await afterCreated._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.CREATED,
|
||||||
|
data: data, params: params, result: result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future modify(id, data, [Map params]) async {
|
Future modify(id, data, [Map params]) async {
|
||||||
var modified = await inner.modify(id, data, params);
|
HookedServiceEvent before = await beforeModified._emit(
|
||||||
_afterUpdated.add(modified);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.MODIFIED,
|
||||||
return modified;
|
id: id, data: data, params: params));
|
||||||
|
|
||||||
|
if (before._canceled) {
|
||||||
|
HookedServiceEvent after = await afterModified._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.MODIFIED,
|
||||||
|
id: id, data: data, params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result = await inner.modify(id, data, params);
|
||||||
|
HookedServiceEvent after = await afterModified._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.MODIFIED,
|
||||||
|
id: id, data: data, params: params, result: result));
|
||||||
|
return after.result;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future update(id, data, [Map params]) async {
|
Future update(id, data, [Map params]) async {
|
||||||
var updated = await inner.update(id, data, params);
|
HookedServiceEvent before = await beforeUpdated._emit(
|
||||||
_afterUpdated.add(updated);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.UPDATED,
|
||||||
return updated;
|
id: id, data: data, params: params));
|
||||||
|
|
||||||
|
if (before._canceled) {
|
||||||
|
HookedServiceEvent after = await afterUpdated._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.UPDATED,
|
||||||
|
id: id, data: data, params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await inner.update(id, data, params);
|
||||||
|
HookedServiceEvent after = await afterUpdated._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.UPDATED,
|
||||||
|
id: id, data: data, params: params, result: result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future remove(id, [Map params]) async {
|
Future remove(id, [Map params]) async {
|
||||||
var removed = await inner.remove(id, params);
|
HookedServiceEvent before = await beforeRemoved._emit(
|
||||||
_afterRemoved.add(removed);
|
new HookedServiceEvent._base(inner, HookedServiceEvent.REMOVED,
|
||||||
return removed;
|
id: id, params: params));
|
||||||
|
|
||||||
|
if (before._canceled) {
|
||||||
|
HookedServiceEvent after = await afterRemoved._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.REMOVED,
|
||||||
|
id: id, params: params, result: before.result));
|
||||||
|
return after.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = await inner.remove(id, params);
|
||||||
|
HookedServiceEvent after = await afterRemoved._emit(
|
||||||
|
new HookedServiceEvent._base(inner, HookedServiceEvent.REMOVED,
|
||||||
|
id: id, params: params, result: result));
|
||||||
|
return after.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fired when a hooked service is invoked.
|
/// Fired when a hooked service is invoked.
|
||||||
class HookedServiceEvent {
|
class HookedServiceEvent {
|
||||||
|
static const String INDEXED = "indexed";
|
||||||
|
static const String READ = "read";
|
||||||
|
static const String CREATED = "created";
|
||||||
|
static const String MODIFIED = "modified";
|
||||||
|
static const String UPDATED = "updated";
|
||||||
|
static const String REMOVED = "removed";
|
||||||
|
|
||||||
/// Use this to end processing of an event.
|
/// Use this to end processing of an event.
|
||||||
void cancel(result) {
|
void cancel(result) {
|
||||||
_canceled = true;
|
_canceled = true;
|
||||||
|
@ -110,15 +165,51 @@ class HookedServiceEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _canceled = false;
|
bool _canceled = false;
|
||||||
var id;
|
String _eventName;
|
||||||
|
var _id;
|
||||||
var data;
|
var data;
|
||||||
Map params;
|
Map _params;
|
||||||
var _result;
|
var _result;
|
||||||
|
|
||||||
|
String get eventName => _eventName;
|
||||||
|
|
||||||
|
get id => _id;
|
||||||
|
|
||||||
|
Map get params => _params;
|
||||||
|
|
||||||
get result => _result;
|
get result => _result;
|
||||||
|
|
||||||
/// The inner service whose method was hooked.
|
/// The inner service whose method was hooked.
|
||||||
Service service;
|
Service service;
|
||||||
|
|
||||||
HookedServiceEvent._base(Service this.service, {this.id, this.data, Map this.params: const{}, result}) {
|
HookedServiceEvent._base(Service this.service, String this._eventName,
|
||||||
|
{id, this.data, Map params, result}) {
|
||||||
|
_id = id;
|
||||||
|
_params = params ?? {};
|
||||||
_result = result;
|
_result = result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Triggered on a hooked service event.
|
||||||
|
typedef Future HookedServiceEventListener(HookedServiceEvent event);
|
||||||
|
|
||||||
|
/// Can be listened to, but events may be canceled.
|
||||||
|
class HookedServiceEventDispatcher {
|
||||||
|
List<HookedServiceEventListener> listeners = [];
|
||||||
|
|
||||||
|
/// Fires an event, and returns it once it is either canceled, or all listeners have run.
|
||||||
|
Future<HookedServiceEvent> _emit(HookedServiceEvent event) async {
|
||||||
|
for (var listener in listeners) {
|
||||||
|
await listener(event);
|
||||||
|
|
||||||
|
if (event._canceled) return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the listener to be called whenever an event is triggered.
|
||||||
|
void listen(HookedServiceEventListener listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,14 +30,15 @@ class MemoryService<T> extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future create(data, [Map params]) async {
|
Future create(data, [Map params]) async {
|
||||||
try {
|
//try {
|
||||||
items[items.length] =
|
print("Data: $data");
|
||||||
(data is Map) ? god.deserializeFromMap(data, T) : data;
|
var created = (data is Map) ? god.deserializeFromMap(data, T) : data;
|
||||||
T created = items[items.length - 1];
|
print("Created $created");
|
||||||
|
items[items.length] = created;
|
||||||
return _makeJson(items.length - 1, created);
|
return _makeJson(items.length - 1, created);
|
||||||
} catch (e) {
|
/*} catch (e) {
|
||||||
throw new AngelHttpException.BadRequest(message: 'Invalid data.');
|
throw new AngelHttpException.BadRequest(message: 'Invalid data.');
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Future modify(id, data, [Map params]) async {
|
Future modify(id, data, [Map params]) async {
|
||||||
|
|
12
pubspec.yaml
12
pubspec.yaml
|
@ -1,13 +1,13 @@
|
||||||
name: angel_framework
|
name: angel_framework
|
||||||
version: 0.0.0-dev.18
|
version: 0.0.0-dev.19
|
||||||
description: Core libraries for the Angel framework.
|
description: Core libraries for the Angel framework.
|
||||||
author: Tobe O <thosakwe@gmail.com>
|
author: Tobe O <thosakwe@gmail.com>
|
||||||
homepage: https://github.com/angel-dart/angel_framework
|
homepage: https://github.com/angel-dart/angel_framework
|
||||||
dependencies:
|
dependencies:
|
||||||
body_parser: ">=1.0.0-dev <2.0.0"
|
body_parser: ^1.0.0-dev
|
||||||
json_god: ">=1.0.0 <2.0.0"
|
json_god: ^1.0.0
|
||||||
merge_map: ">=1.0.0 <2.0.0"
|
merge_map: ^1.0.0
|
||||||
mime: ^0.9.3
|
mime: ^0.9.3
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
http: ">= 0.11.3 < 0.12.0"
|
http: ^0.11.3
|
||||||
test: ">= 0.12.13 < 0.13.0"
|
test: ^0.12.13
|
89
test/hooked.dart
Normal file
89
test/hooked.dart
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import 'dart:mirrors';
|
||||||
|
import 'package:angel_framework/angel_framework.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:json_god/json_god.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
class Todo {
|
||||||
|
String text;
|
||||||
|
String over;
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
group('Hooked', () {
|
||||||
|
Map headers = {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
};
|
||||||
|
Angel app;
|
||||||
|
String url;
|
||||||
|
http.Client client;
|
||||||
|
God god;
|
||||||
|
HookedService Todos;
|
||||||
|
|
||||||
|
setUp(() async {
|
||||||
|
app = new Angel();
|
||||||
|
client = new http.Client();
|
||||||
|
god = new God();
|
||||||
|
app.use('/todos', new MemoryService<Todo>());
|
||||||
|
Todos = app.service("todos");
|
||||||
|
|
||||||
|
await app.startServer(null, 0);
|
||||||
|
url = "http://${app.httpServer.address.host}:${app.httpServer.port}";
|
||||||
|
});
|
||||||
|
|
||||||
|
tearDown(() async {
|
||||||
|
app = null;
|
||||||
|
url = null;
|
||||||
|
client.close();
|
||||||
|
client = null;
|
||||||
|
god = null;
|
||||||
|
Todos = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
test("listen before and after", () async {
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
Todos
|
||||||
|
..beforeIndexed.listen((_) {
|
||||||
|
count++;
|
||||||
|
})
|
||||||
|
..afterIndexed.listen((_) {
|
||||||
|
count++;
|
||||||
|
});
|
||||||
|
|
||||||
|
var response = await client.get("$url/todos");
|
||||||
|
print(response.body);
|
||||||
|
expect(count, equals(2));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("cancel before", () async {
|
||||||
|
Todos.beforeCreated..listen((HookedServiceEvent event) {
|
||||||
|
event.cancel({"hello": "hooked world"});
|
||||||
|
})..listen((HookedServiceEvent event) {
|
||||||
|
event.cancel({"this_hook": "should never run"});
|
||||||
|
});
|
||||||
|
|
||||||
|
var response = await client.post(
|
||||||
|
"$url/todos", body: god.serialize({"arbitrary": "data"}),
|
||||||
|
headers: headers);
|
||||||
|
print(response.body);
|
||||||
|
Map result = god.deserialize(response.body);
|
||||||
|
expect(result["hello"], equals("hooked world"));
|
||||||
|
});
|
||||||
|
|
||||||
|
test("cancel after", () async {
|
||||||
|
Todos.afterIndexed..listen((HookedServiceEvent event) async {
|
||||||
|
// Hooks can be Futures ;)
|
||||||
|
event.cancel([{"angel": "framework"}]);
|
||||||
|
})..listen((HookedServiceEvent event) {
|
||||||
|
event.cancel({"this_hook": "should never run either"});
|
||||||
|
});
|
||||||
|
|
||||||
|
var response = await client.get("$url/todos");
|
||||||
|
print(response.body);
|
||||||
|
List result = god.deserialize(response.body);
|
||||||
|
expect(result[0]["angel"], equals("framework"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -15,23 +15,24 @@ main() {
|
||||||
'Accept': 'application/json',
|
'Accept': 'application/json',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
};
|
};
|
||||||
Angel angel;
|
Angel app;
|
||||||
String url;
|
String url;
|
||||||
http.Client client;
|
http.Client client;
|
||||||
God god;
|
God god;
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
angel = new Angel();
|
app = new Angel();
|
||||||
client = new http.Client();
|
client = new http.Client();
|
||||||
god = new God();
|
god = new God();
|
||||||
Service todos = new MemoryService<Todo>();
|
Service todos = new MemoryService<Todo>();
|
||||||
angel.use('/todos', todos);
|
app.use('/todos', todos);
|
||||||
await angel.startServer(null, 0);
|
print(app.service("todos"));
|
||||||
url = "http://${angel.httpServer.address.host}:${angel.httpServer.port}";
|
await app.startServer(null, 0);
|
||||||
|
url = "http://${app.httpServer.address.host}:${app.httpServer.port}";
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
angel = null;
|
app = null;
|
||||||
url = null;
|
url = null;
|
||||||
client.close();
|
client.close();
|
||||||
client = null;
|
client = null;
|
||||||
|
|
|
@ -24,9 +24,11 @@ main() {
|
||||||
angel.properties['foo'] = () => 'bar';
|
angel.properties['foo'] = () => 'bar';
|
||||||
angel.properties['Foo'] = new Foo('bar');
|
angel.properties['Foo'] = new Foo('bar');
|
||||||
|
|
||||||
|
/**
|
||||||
expect(angel.hello, equals('world'));
|
expect(angel.hello, equals('world'));
|
||||||
expect(angel.foo(), equals('bar'));
|
expect(angel.foo(), equals('bar'));
|
||||||
expect(angel.Foo.name, equals('bar'));
|
expect(angel.Foo.name, equals('bar'));
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue