import 'dart:async'; 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'; import 'package:test/test.dart'; class MockContainer extends Mock implements Container { final Map _instances = {}; @override T make([Type? type]) { type ??= T; return _instances[type] as T; } void registerInstance(T instance) { _instances[T] = instance; } } class MockEventBus extends Mock implements EventBus { @override Stream on() { return super.noSuchMethod( Invocation.method(#on, [], {#T: T}), returnValue: Stream.empty(), ) as Stream; } } class MockMQClient extends Mock implements MQClient {} class TestCommand implements Command { final String data; TestCommand(this.data); } class TestHandler implements Handler { @override Future handle(Command command) async { if (command is TestCommand) { return 'Handled: ${command.data}'; } throw UnimplementedError(); } } class TestQueuedCommand implements Command, ShouldQueue { final String data; TestQueuedCommand(this.data); } void main() { late MockContainer container; late MockEventBus eventBus; late MockMQClient mqClient; late Dispatcher dispatcher; setUp(() { container = MockContainer(); eventBus = MockEventBus(); mqClient = MockMQClient(); container.registerInstance(eventBus); container.registerInstance(mqClient); dispatcher = Dispatcher(container); }); group('Dispatcher', () { test('dispatchNow should handle command and return result', () async { final command = TestCommand('test data'); final handler = TestHandler(); container.registerInstance(handler); dispatcher.map({TestCommand: TestHandler}); final commandEventController = StreamController(); when(eventBus.on()) .thenAnswer((_) => commandEventController.stream); final future = dispatcher.dispatchNow(command); // Simulate the event firing commandEventController .add(CommandEvent(command, result: 'Handled: test data')); final result = await future; expect(result, equals('Handled: test data')); await commandEventController.close(); }); test('dispatch should handle regular commands immediately', () async { final command = TestCommand('regular'); final handler = TestHandler(); container.registerInstance(handler); dispatcher.map({TestCommand: TestHandler}); final commandEventController = StreamController(); when(eventBus.on()) .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()).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); }); }); }