Skip to content

Commit

Permalink
Align pipeline behavior (#10)
Browse files Browse the repository at this point in the history
* Change to set

* Rename handlers -> behaviors

* Correct generic type names

* Add assertion test

* Update getPipelines to return a set of behaviors
  • Loading branch information
Matthiee authored May 12, 2024
1 parent 7bcefed commit 5399863
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 27 deletions.
4 changes: 2 additions & 2 deletions lib/src/request/pipeline/pipeline_behavior.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import 'package:meta/meta.dart';
typedef RequestHandlerDelegate<TResponse> = FutureOr<TResponse> Function();

/// Factory to create a [PipelineBehavior].
typedef PipelineBehaviorFactory<TRequest, TResponse>
= PipelineBehavior<TRequest, TResponse> Function();
typedef PipelineBehaviorFactory<TResponse, TRequest>
= PipelineBehavior<TResponse, TRequest> Function();

typedef PipelineHandler<TResponse, TRequest> = FutureOr<TResponse> Function(
TRequest, RequestHandlerDelegate<TResponse>);
Expand Down
42 changes: 26 additions & 16 deletions lib/src/request/pipeline/pipeline_behavior_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ import 'package:dart_mediator/src/request/pipeline/pipeline_configurator.dart';
import 'package:dart_mediator/src/request/pipeline/pipeline_behavior.dart';

class PipelineBehaviorStore implements PipelineConfigurator {
final _handlers = <Type, List<PipelineBehavior>>{};
final _genericHandlers = <PipelineBehavior>{};
final _typedBehaviors = <Type, Set<PipelineBehavior>>{};
final _genericBehaviors = <PipelineBehavior>{};

@override
void register<TResponse extends Object?, TRequest extends Request<TResponse>>(
PipelineBehavior<TResponse, TRequest> behavior,
) {
final handlers = _handlers.putIfAbsent(
final handlers = _typedBehaviors.putIfAbsent(
TRequest,
() => <PipelineBehavior>[],
() => <PipelineBehavior>{},
);

assert(
!handlers.contains(behavior),
'register<$TResponse, $TRequest> was called with an already registered behavior',
);

handlers.add(behavior);
Expand All @@ -22,45 +27,50 @@ class PipelineBehaviorStore implements PipelineConfigurator {
void registerGeneric(
PipelineBehavior behavior,
) {
_genericHandlers.add(behavior);
assert(
!_genericBehaviors.contains(behavior),
'registerGeneric was called with an already registered behavior',
);

_genericBehaviors.add(behavior);
}

@override
void unregister<TResponse extends Object?,
TRequest extends Request<TResponse>>(
PipelineBehavior<TResponse, TRequest> behavior,
) {
final handlers = _handlers[TRequest];
final behaviors = _typedBehaviors[TRequest];

assert(
handlers != null,
behaviors != null && behaviors.contains(behavior),
'unregister<$TResponse, $TRequest> was called for a behavior that was never registered',
);

handlers!.remove(behavior);
behaviors!.remove(behavior);
}

@override
void unregisterGeneric(PipelineBehavior behavior) {
assert(
_genericHandlers.contains(behavior),
_genericBehaviors.contains(behavior),
'unregisterGeneric was called for a behavior that was never registered',
);

_genericHandlers.remove(behavior);
_genericBehaviors.remove(behavior);
}

/// Returns all [PipelineBehavior]'s that match.
List<PipelineBehavior> getPipelines(
Set<PipelineBehavior> getPipelines(
Request request,
) {
final requestType = request.runtimeType;

final handlers = _handlers[requestType];
final behaviors = _typedBehaviors[requestType];

return [
if (handlers != null) ...handlers,
..._genericHandlers,
];
return {
if (behaviors != null) ...behaviors,
..._genericBehaviors,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void main() {
group('register', () {
final mockBehavior = MockPipelineBehavior<int, MockRequest<int>>();

test('it registers the handler', () {
test('it registers the behavior', () {
expect(
() => pipelineBehaviorStore.register(mockBehavior),
returnsNormally,
Expand All @@ -27,6 +27,18 @@ void main() {
[mockBehavior],
);
});

test('it throws when the behavior was already registered', () {
expect(
() => pipelineBehaviorStore.register(mockBehavior),
returnsNormally,
);

expect(
() => pipelineBehaviorStore.register(mockBehavior),
throwsAssertionError,
);
});
});

group('registerGenericFunction', () {
Expand Down Expand Up @@ -81,7 +93,7 @@ void main() {
group('registerGeneric', () {
final mockBehavior = MockPipelineBehavior();

test('it registers the handler', () {
test('it registers the behavior', () {
expect(
() => pipelineBehaviorStore.registerGeneric(mockBehavior),
returnsNormally,
Expand All @@ -97,7 +109,7 @@ void main() {
group('registerGenericFactory', () {
MockPipelineBehavior factory() => MockPipelineBehavior();

test('it registers the handler', () {
test('it registers the behavior', () {
expect(
() => pipelineBehaviorStore.registerGenericFactory(factory),
returnsNormally,
Expand Down Expand Up @@ -127,7 +139,21 @@ void main() {
);
});

test('it throws when behavior does not exist', () {
test('it throws when behavior type does not exist', () {
expect(
() => pipelineBehaviorStore.unregister(mockBehavior),
throwsAssertionError,
);
});

test('it throws when the behavior does not exist', () {
pipelineBehaviorStore.register(mockBehavior);

expect(
() => pipelineBehaviorStore.unregister(mockBehavior),
returnsNormally,
);

expect(
() => pipelineBehaviorStore.unregister(mockBehavior),
throwsAssertionError,
Expand Down Expand Up @@ -222,17 +248,18 @@ void main() {
// Will not be returned in the getPipelines call.
pipelineBehaviorStore.register(incorrectBehavior);
pipelineBehaviorStore.registerFactory(incorrectFactory);
pipelineBehaviorStore.registerFunction(incorrectBehavior.handle);

expect(
pipelineBehaviorStore.getPipelines(mockRequest),
[
{
correctBehavior,
PipelineBehavior.function(correctBehavior.handle),
PipelineBehavior.factory(correctFactory),
logBehavior,
PipelineBehavior.function(logBehavior.handle),
PipelineBehavior.factory(logBehaviorFactory),
],
},
);
});
});
Expand Down
6 changes: 3 additions & 3 deletions test/unit/request/requests_manager_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void main() {
.thenReturn(mockRequestHandler);

when(() => mockPipelineBehaviorStore.getPipelines(mockRequest))
.thenReturn([]);
.thenReturn({});

final result = await requestsManager.send(mockRequest);

Expand Down Expand Up @@ -134,7 +134,7 @@ void main() {
});

when(() => mockPipelineBehaviorStore.getPipelines(mockRequest))
.thenReturn([mockBehavior]);
.thenReturn({mockBehavior});

final result = await requestsManager.send(mockRequest);

Expand Down Expand Up @@ -166,7 +166,7 @@ void main() {
});

when(() => mockPipelineBehaviorStore.getPipelines(mockRequest))
.thenReturn([mockWrongBehavior]);
.thenReturn({mockWrongBehavior});

await expectLater(
() => requestsManager.send(mockRequest),
Expand Down

0 comments on commit 5399863

Please sign in to comment.