2024-10-07 02:35:39 +00:00
|
|
|
import 'dart:async';
|
|
|
|
|
2024-10-06 16:50:42 +00:00
|
|
|
import 'package:angel3_bus/angel3_bus.dart';
|
|
|
|
import 'package:angel3_container/angel3_container.dart';
|
|
|
|
import 'package:angel3_event_bus/event_bus.dart';
|
|
|
|
import 'package:angel3_mq/mq.dart';
|
|
|
|
import 'package:mockito/mockito.dart';
|
2024-10-07 02:35:39 +00:00
|
|
|
import 'package:test/test.dart';
|
2024-10-06 16:50:42 +00:00
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
class MockContainer extends Mock implements Container {
|
|
|
|
final Map<Type, dynamic> _instances = {};
|
2024-10-06 16:50:42 +00:00
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
@override
|
|
|
|
T make<T>([Type? type]) {
|
|
|
|
type ??= T;
|
|
|
|
return _instances[type] as T;
|
|
|
|
}
|
2024-10-06 16:50:42 +00:00
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
void registerInstance<T>(T instance) {
|
|
|
|
_instances[T] = instance;
|
|
|
|
}
|
|
|
|
}
|
2024-10-06 16:50:42 +00:00
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
class MockEventBus extends Mock implements EventBus {
|
|
|
|
@override
|
|
|
|
Stream<T> on<T extends AppEvent>() {
|
|
|
|
return super.noSuchMethod(
|
|
|
|
Invocation.method(#on, [], {#T: T}),
|
|
|
|
returnValue: Stream<T>.empty(),
|
|
|
|
) as Stream<T>;
|
|
|
|
}
|
|
|
|
}
|
2024-10-06 16:50:42 +00:00
|
|
|
|
|
|
|
class MockMQClient extends Mock implements MQClient {}
|
|
|
|
|
|
|
|
class TestCommand implements Command {
|
|
|
|
final String data;
|
|
|
|
TestCommand(this.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
class TestHandler implements Handler {
|
|
|
|
@override
|
|
|
|
Future<dynamic> handle(Command command) async {
|
|
|
|
if (command is TestCommand) {
|
|
|
|
return 'Handled: ${command.data}';
|
|
|
|
}
|
|
|
|
throw UnimplementedError();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
class TestQueuedCommand implements Command, ShouldQueue {
|
|
|
|
final String data;
|
|
|
|
TestQueuedCommand(this.data);
|
|
|
|
}
|
|
|
|
|
2024-10-06 16:50:42 +00:00
|
|
|
void main() {
|
|
|
|
late MockContainer container;
|
2024-10-07 02:35:39 +00:00
|
|
|
late MockEventBus eventBus;
|
|
|
|
late MockMQClient mqClient;
|
2024-10-06 16:50:42 +00:00
|
|
|
late Dispatcher dispatcher;
|
|
|
|
|
|
|
|
setUp(() {
|
|
|
|
container = MockContainer();
|
2024-10-07 02:35:39 +00:00
|
|
|
eventBus = MockEventBus();
|
|
|
|
mqClient = MockMQClient();
|
|
|
|
|
|
|
|
container.registerInstance<EventBus>(eventBus);
|
|
|
|
container.registerInstance<MQClient>(mqClient);
|
2024-10-06 16:50:42 +00:00
|
|
|
|
|
|
|
dispatcher = Dispatcher(container);
|
|
|
|
});
|
|
|
|
|
|
|
|
group('Dispatcher', () {
|
|
|
|
test('dispatchNow should handle command and return result', () async {
|
|
|
|
final command = TestCommand('test data');
|
|
|
|
final handler = TestHandler();
|
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
container.registerInstance<TestHandler>(handler);
|
2024-10-06 16:50:42 +00:00
|
|
|
dispatcher.map({TestCommand: TestHandler});
|
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
final commandEventController = StreamController<CommandEvent>();
|
|
|
|
when(eventBus.on<CommandEvent>())
|
|
|
|
.thenAnswer((_) => commandEventController.stream);
|
|
|
|
|
|
|
|
final future = dispatcher.dispatchNow(command);
|
2024-10-06 16:50:42 +00:00
|
|
|
|
2024-10-07 02:35:39 +00:00
|
|
|
// Simulate the event firing
|
|
|
|
commandEventController
|
|
|
|
.add(CommandEvent(command, result: 'Handled: test data'));
|
|
|
|
|
|
|
|
final result = await future;
|
2024-10-06 16:50:42 +00:00
|
|
|
expect(result, equals('Handled: test data'));
|
2024-10-07 02:35:39 +00:00
|
|
|
|
|
|
|
await commandEventController.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('dispatch should handle regular commands immediately', () async {
|
|
|
|
final command = TestCommand('regular');
|
|
|
|
final handler = TestHandler();
|
|
|
|
|
|
|
|
container.registerInstance<TestHandler>(handler);
|
|
|
|
dispatcher.map({TestCommand: TestHandler});
|
|
|
|
|
|
|
|
final commandEventController = StreamController<CommandEvent>();
|
|
|
|
when(eventBus.on<CommandEvent>())
|
|
|
|
.thenAnswer((_) => commandEventController.stream);
|
|
|
|
|
|
|
|
final future = dispatcher.dispatch(command);
|
|
|
|
|
|
|
|
// Simulate the event firing
|
|
|
|
commandEventController
|
|
|
|
.add(CommandEvent(command, result: 'Handled: regular'));
|
|
|
|
|
|
|
|
final result = await future;
|
|
|
|
expect(result, equals('Handled: regular'));
|
|
|
|
|
|
|
|
await commandEventController.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
test('map should register command handlers', () {
|
|
|
|
dispatcher.map({TestCommand: TestHandler});
|
|
|
|
|
|
|
|
// Mock the event bus behavior for this test
|
|
|
|
when(eventBus.on<CommandEvent>()).thenAnswer((_) => Stream.empty());
|
|
|
|
|
|
|
|
// This test is a bit tricky to verify directly, but we can check if dispatch doesn't throw
|
|
|
|
expect(() => dispatcher.dispatch(TestCommand('test')), returnsNormally);
|
2024-10-06 16:50:42 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|