Permalink
Browse files

Splitting up logic with http into separate modules.

Hope to unit test individually
  • Loading branch information...
1 parent 1afcc85 commit a3ad6c8a21a9d12f0d06ff44d7095c574980b2c9 @bbyars committed Jun 3, 2011
View
@@ -1,6 +1,8 @@
## Refactorings
* filter out stub matching logic into module, unit test
* Remove string.format for something more javascript like
+* Pass console.log around, allows using different logger
+* Move the (path || '/') logic to repository
## Build
* Pretty up github release page
@@ -12,9 +14,12 @@
* Add smtp mocking, with same REST API (create servers on demand)
* Would be nice as a plugin, allow other protocols as plugins
* Add protocol to post /servers, use same REST API for each
- * Allow bin/httpmock to accept a paramter to a plugins path, allowing dynamic extension
+ * Allow bin/httpmock to accept a parameter to a plugins path, allowing dynamic extension
* Accept HTML; allow QA's to manually set up tests
* Allow ordering stub calls to same path to simulate state change
+* Other language bindings
+ * C#
+ * bash (allow scripted setups)
## Bugs
* isPortInUse gives intermittent test failures (timing issue?)
@@ -1,122 +1,3 @@
'use strict';
-require('extensions');
-
-var connect = require('connect'),
- repositories = require('repository'),
- merge = connect.utils.merge;
-
-// We can't use keepalive connections, because a test case
-// may shutdown the stub, which prevents new connections for
-// the port, but that won't prevent the system under test
-// from reusing an existing TCP connection after the stub
-// has shutdown, causing difficult to track down bugs when
-// multiple tests are run.
-var defaults = {
- statusCode: 200,
- headers: {
- 'Connection': 'close'
- },
- body: ''
-};
-
-var create = function (port, callback) {
- var requests = repositories.create(),
- stubs = repositories.create(),
- logPrefix = '[{0}]: '.format(port),
- server;
-
- function recorder(request, response, next) {
- request.body = '';
- request.setEncoding('utf8');
-
- request.on('data', function (chunk) {
- request.body += chunk;
- });
-
- request.on('end', function () {
- requests.save({
- path: request.url,
- method: request.method,
- headers: request.headers,
- body: request.body
- });
- next();
- });
- }
-
- function methodMatches(actual, expected) {
- return !expected || actual === expected;
- }
-
- function allHeadersMatch(actual, expected) {
- return !expected || Object.keys(expected).every(function (header) {
- return expected[header] === actual[header.toLowerCase()];
- });
- }
-
- function bodyMatches(actual, expected) {
- return !expected || actual.indexOf(expected) >= 0;
- }
-
- function requestMatches(actual, expected) {
- return methodMatches(actual.method, expected.method) &&
- allHeadersMatch(actual.headers, expected.headers) &&
- bodyMatches(actual.body, expected.body);
- }
-
- function findFirstMatchingStub(request) {
- var possibleMatches = stubs.load(request.url),
- stub;
-
- stub = possibleMatches.filter(function (stub) {
- return (!stub.request || requestMatches(request, stub.request));
- })[0];
-
- if (!stub || !stub.response) {
- return Object.create(defaults);
- }
- return stub.response;
- }
-
- function stubber(request, response) {
- var defaultStub = Object.create(defaults),
- match = findFirstMatchingStub(request),
- headers = merge(defaultStub.headers, match.headers),
- stub = merge(defaultStub, match);
-
- response.writeHead(stub.statusCode, headers);
- response.write(stub.body);
- response.end();
- }
-
- server = connect.createServer(
- connect.logger({format: logPrefix + ':method :url'}),
- recorder,
- stubber);
-
- server.on('close', function () {
- console.log(logPrefix + 'Ciao...');
- });
-
- server.listen(port, function () {
- console.log(logPrefix + 'Open for business...');
-
- callback({
- close: function (callback) {
- server.on('close', callback);
- server.close();
- },
-
- loadRequests: function (path) {
- return requests.load(path || '/');
- },
-
- addStub: function (stub) {
- stubs.save(stub);
- }
- });
- });
-};
-
-exports.create = create;
+exports.create = require('./server').create;
@@ -0,0 +1,35 @@
+'use strict';
+
+var repositories = require('repository');
+
+function create() {
+ var requests = repositories.create();
+
+ function recorder(request, response, next) {
+ request.body = '';
+ request.setEncoding('utf8');
+
+ request.on('data', function (chunk) {
+ request.body += chunk;
+ });
+
+ request.on('end', function () {
+ requests.save({
+ path: request.url,
+ method: request.method,
+ headers: request.headers,
+ body: request.body
+ });
+ next();
+ });
+ }
+
+ return {
+ middleware: recorder,
+ load: function (path) {
+ return requests.load(path);
+ }
+ };
+}
+
+exports.create = create;
@@ -0,0 +1,45 @@
+'use strict';
+
+require('extensions');
+
+var connect = require('connect'),
+ stubs = require('./stubbing'),
+ recorders = require('./recording'),
+ merge = connect.utils.merge;
+
+var create = function (port, callback) {
+ var logPrefix = '[{0}]: '.format(port),
+ stub = stubs.create(),
+ recorder = recorders.create(),
+ server;
+
+ server = connect.createServer(
+ connect.logger({format: logPrefix + ':method :url'}),
+ recorder.middleware,
+ stub.middleware);
+
+ server.on('close', function () {
+ console.log(logPrefix + 'Ciao...');
+ });
+
+ server.listen(port, function () {
+ console.log(logPrefix + 'Open for business...');
+
+ callback({
+ close: function (callback) {
+ server.on('close', callback);
+ server.close();
+ },
+
+ loadRequests: function (path) {
+ return recorder.load(path || '/');
+ },
+
+ addStub: function (stubResponse) {
+ stub.addStub(stubResponse);
+ }
+ });
+ });
+};
+
+exports.create = create;
@@ -0,0 +1,77 @@
+'use strict';
+
+var connect = require('connect'),
+ merge = connect.utils.merge,
+ repositories = require('repository');
+
+// We don't want to use keepalive connections, because a test case
+// may shutdown the stub, which prevents new connections for
+// the port, but that won't prevent the system under test
+// from reusing an existing TCP connection after the stub
+// has shutdown, causing difficult to track down bugs when
+// multiple tests are run.
+var defaults = {
+ statusCode: 200,
+ headers: {
+ 'Connection': 'close'
+ },
+ body: ''
+};
+
+function methodMatches(actual, expected) {
+ return !expected || actual === expected;
+}
+
+function allHeadersMatch(actual, expected) {
+ return !expected || Object.keys(expected).every(function (header) {
+ return expected[header] === actual[header.toLowerCase()];
+ });
+}
+
+function bodyMatches(actual, expected) {
+ return !expected || actual.indexOf(expected) >= 0;
+}
+
+function requestMatches(actual, expected) {
+ return methodMatches(actual.method, expected.method) &&
+ allHeadersMatch(actual.headers, expected.headers) &&
+ bodyMatches(actual.body, expected.body);
+}
+
+function create() {
+ var stubs = repositories.create();
+
+ function findFirstMatchingStub(request) {
+ var possibleMatches = stubs.load(request.url),
+ stub;
+
+ stub = possibleMatches.filter(function (stub) {
+ return (!stub.request || requestMatches(request, stub.request));
+ })[0];
+
+ if (!stub || !stub.response) {
+ return Object.create(defaults);
+ }
+ return stub.response;
+ }
+
+ function stubber(request, response) {
+ var defaultStub = Object.create(defaults),
+ match = findFirstMatchingStub(request),
+ headers = merge(defaultStub.headers, match.headers),
+ stub = merge(defaultStub, match);
+
+ response.writeHead(stub.statusCode, headers);
+ response.write(stub.body);
+ response.end();
+ }
+
+ return {
+ middleware: stubber,
+ addStub: function (stub) {
+ stubs.save(stub);
+ }
+ };
+}
+
+exports.create = create;

0 comments on commit a3ad6c8

Please sign in to comment.