Skip to content

Commit

Permalink
Add Pipeline (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
donny-dont authored and nex3 committed Jun 23, 2017
1 parent 5466bac commit 866628b
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/src/pipeline.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
k// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'client.dart';
import 'handler.dart';
import 'middleware.dart';

/// A helper that makes it easy to compose a set of [Middleware] and a
/// [Client].
///
/// var client = const Pipeline()
/// .addMiddleware(loggingMiddleware)
/// .addMiddleware(basicAuthMiddleware)
/// .addClient(new Client());
class Pipeline {
/// The outer pipeline.
final Pipeline _parent;

/// The [Middleware] that is invoked at this stage.
final Middleware _middleware;

const Pipeline()
: _parent = null,
_middleware = null;

Pipeline._(this._parent, this._middleware);

/// Returns a new [Pipeline] with [middleware] added to the existing set of
/// [Middleware].
///
/// [middleware] will be the last [Middleware] to process a request and
/// the first to process a response.
Pipeline addMiddleware(Middleware middleware) =>
new Pipeline._(this, middleware);

/// Returns a new [Client] with [client] as the final processor of a
/// [Request] if all of the middleware in the pipeline have passed the request
/// through.
Client addClient(Client client) =>
_middleware == null ? client : _parent.addClient(_middleware(client));

/// Returns a new [Client] with [handler] as the final processor of a
/// [Request] if all of the middleware in the pipeline have passed the request
/// through.
Client addHandler(Handler handler) => addClient(new Client.handler(handler));

/// Exposes this pipeline of [Middleware] as a single middleware instance.
Middleware get middleware => addClient;
}
112 changes: 112 additions & 0 deletions test/pipeline_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:test/test.dart';

import 'package:http/http.dart';

void main() {
test('compose middleware with Pipeline', () async {
var accessLocation = 0;

var middlewareA = createMiddleware(requestHandler: (request) async {
expect(accessLocation, 0);
accessLocation = 1;
return request;
}, responseHandler: (response) async {
expect(accessLocation, 4);
accessLocation = 5;
return response;
});

var middlewareB = createMiddleware(requestHandler: (request) async {
expect(accessLocation, 1);
accessLocation = 2;
return request;
}, responseHandler: (response) async {
expect(accessLocation, 3);
accessLocation = 4;
return response;
});

var client = const Pipeline()
.addMiddleware(middlewareA)
.addMiddleware(middlewareB)
.addClient(new Client.handler((request) async {
expect(accessLocation, 2);
accessLocation = 3;
return new Response(Uri.parse('dart:http'), 200);
}));

var response = await client.get(Uri.parse('dart:http'));

expect(response, isNotNull);
expect(accessLocation, 5);
});

test('Pipeline can be used as middleware', () async {
int accessLocation = 0;

var middlewareA = createMiddleware(requestHandler: (request) async {
expect(accessLocation, 0);
accessLocation = 1;
return request;
}, responseHandler: (response) async {
expect(accessLocation, 4);
accessLocation = 5;
return response;
});

var middlewareB = createMiddleware(requestHandler: (request) async {
expect(accessLocation, 1);
accessLocation = 2;
return request;
}, responseHandler: (response) async {
expect(accessLocation, 3);
accessLocation = 4;
return response;
});

var innerPipeline =
const Pipeline().addMiddleware(middlewareA).addMiddleware(middlewareB);

var client = const Pipeline()
.addMiddleware(innerPipeline.middleware)
.addClient(new Client.handler((request) async {
expect(accessLocation, 2);
accessLocation = 3;
return new Response(Uri.parse('dart:http'), 200);
}));

var response = await client.get(Uri.parse('dart:http'));

expect(response, isNotNull);
expect(accessLocation, 5);
});

test('Pipeline calls close on all middleware', () {
int accessLocation = 0;

var middlewareA = createMiddleware(onClose: () {
expect(accessLocation, 0);
accessLocation = 1;
});

var middlewareB = createMiddleware(onClose: () {
expect(accessLocation, 1);
accessLocation = 2;
});

var client = const Pipeline()
.addMiddleware(middlewareA)
.addMiddleware(middlewareB)
.addClient(new Client.handler((request) async => null, onClose: () {
expect(accessLocation, 2);
accessLocation = 3;
}));

client.close();
expect(accessLocation, 3);
});
}

0 comments on commit 866628b

Please sign in to comment.