From 54843c669aee4cd7e8d36e599bd1546e353c29d3 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 09:21:17 -0400 Subject: [PATCH 01/37] initial implementation --- README.md | 7 ++++ index.js | 1 + lib/amqp-config-utils.js | 15 ++++++++ lib/fudd.js | 76 +++++++++++++++++++++++++++++++++++----- 4 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 index.js create mode 100644 lib/amqp-config-utils.js diff --git a/README.md b/README.md index 1b8d61b..c095409 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,9 @@ +[![Build Status](https://travis-ci.org/GannettDigital/fudd.svg?branch=master)](https://travis-ci.org/GannettDigital/fudd) +[![Coverage Status](https://coveralls.io/repos/github/GannettDigital/fudd/badge.svg?branch=master)](https://coveralls.io/github/GannettDigital/fudd?branch=master) + # fudd simple rabbit mq infrastructure setup/teardown utility + +# usage + +# configuration \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..418e013 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +module.exports = require('./lib/fudd.js'); \ No newline at end of file diff --git a/lib/amqp-config-utils.js b/lib/amqp-config-utils.js new file mode 100644 index 0000000..80fcd87 --- /dev/null +++ b/lib/amqp-config-utils.js @@ -0,0 +1,15 @@ +'use strict'; + +var format = require('util').format; + +module.exports = function formatAmqpUrl(urlComponents) { + return format( + 'amqp://%s:%s@%s:%s/%s?heartbeat=%s', + urlComponents.login, + urlComponents.password, + urlComponents.host, + urlComponents.port, + encodeURIComponent(urlComponents.vhost), + urlComponents.heartbeat + ); +}; diff --git a/lib/fudd.js b/lib/fudd.js index 74b9440..5d22ac7 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -1,21 +1,81 @@ 'use strict'; +var amqp = require('amqplib/callback_api'); +var formatAmqpUrl = require('./amqp-config-utils.js'); -function Fudd() { +module.exports = Fudd; +function Fudd(config) { + this.config = config; } -Fudd.prototype.init = function(config) { - return true; -}; +Fudd.prototype.setup = function(callback) { + var config = JSON.parse(JSON.stringify(this.config)); + connect(config, function(connection, channel) { + createExchanges(channel, Object.keys(config.exchanges), function(err) { + if (err) return callback(err); -Fudd.prototype.setup = function() { + createQueues(channel, Object.keys(config.queues), function(err){ + if (err) return callback(err); -}; + doBindings(channel, config.bindings, callback); + }) + }); + }); + + function doBindings(channel, bindings, callback){ + if (bindings.length === 0) return callback(); + + var binding = bindings.pop(); + + var boundBindings = doBindings.bind(this, channel, bindings, callback); + bindAllKeys(channel, binding, binding.bindingKeys, boundBindings); + } + + function bindAllKeys(channel, binding, keys, callback){ + if (keys.length === 0) return callback(); -Fudd.prototype.tearDown = function() { + var key = keys.pop(); + var onBound = bindAllKeys.bind(this, channel, binding, keys, callback); + console.log('binding'); + if (binding.bindingType === 'queue') { + channel.bindQueue(binding.to, binding.from, key, {}, onBound); + } else { + channel.bindExchange(binding.to, binding.from, key, {}, onBound); + } + } + function createQueues(channel, queueKeys, callback){ + if (queueKeys.length === 0) return callback(); + var queueKey = queueKeys.pop(); + + console.log('asserting Q'); + var exchangeAsserted = createQueues.bind(this, channel, queueKeys, callback); + channel.assertQueue(queueKey, {durable: true}, exchangeAsserted); + } + + function createExchanges(channel, exchangeKeys, callback) { + if (exchangeKeys.length === 0) return callback(); + var exchangeKey = exchangeKeys.pop(); + + console.log('asserting'); + var exchangeAsserted = createExchanges.bind(this, channel, exchangeKeys, callback); + channel.assertExchange(exchangeKey, config.exchanges[exchangeKey].type, {}, exchangeAsserted); + } }; -module.exports = Fudd; \ No newline at end of file +Fudd.prototype.teardown = function(callback){ + callback(); +}; + +function connect(config, callback) { + var url = formatAmqpUrl(config.cluster); + amqp.connect(url, function(error, connection) { + if (error) throw error; + connection.createChannel(function(error, channel) { + if (error) throw error; + callback(connection, channel); + }); + }); +} From abcea3f9530a5c32142d9d749454fcf97483b9fd Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 12:01:55 -0400 Subject: [PATCH 02/37] initial commit --- .gitignore | 2 + README.md | 10 ++- lib/fudd.js | 108 ++++++++++++----------------- package.json | 7 +- test/integration/config/default.js | 41 +++++++++++ test/integration/config/local.js | 55 +++++++++++++++ test/integration/fudd.js | 21 ++++++ test/unit/fudd.js | 41 +++++++++-- 8 files changed, 210 insertions(+), 75 deletions(-) create mode 100644 test/integration/config/default.js create mode 100644 test/integration/config/local.js create mode 100644 test/integration/fudd.js diff --git a/.gitignore b/.gitignore index 2fcbb03..44ce220 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ jspm_packages # Optional REPL history .node_repl_history + +./test/integration/config/local.js \ No newline at end of file diff --git a/README.md b/README.md index c095409..635bb80 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,12 @@ # fudd simple rabbit mq infrastructure setup/teardown utility -# usage +## Installation -# configuration \ No newline at end of file +## Test + +## Coverage + +## Usage + +## Configuration \ No newline at end of file diff --git a/lib/fudd.js b/lib/fudd.js index 183ba7e..dac5037 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -1,79 +1,59 @@ 'use strict'; var amqp = require('amqplib/callback_api'); var formatAmqpUrl = require('./amqp-config-utils.js'); +var palinode = require('palinode'); -module.exports = Fudd; +var Fudd = { + setup: function(config, finalCallback) { + Fudd._connect(config, function(connection, channel) { + //TODO: re-write using palinode.series -function Fudd(config) { - this.config = config; -} + palinode.mapEach(config.exchanges, Fudd._createExchange.bind(null, channel), function(err) { + if (err) return finalCallback(err); -Fudd.prototype.setup = function(callback) { - var config = JSON.parse(JSON.stringify(this.config)); + palinode.mapEach(config.queues, Fudd._createQueue.bind(null, channel), function(err) { + if (err) return finalCallback(err); - connect(config, function(connection, channel) { - createExchanges(channel, Object.keys(config.exchanges), function(err) { - if (err) return callback(err); - createQueues(channel, Object.keys(config.queues), function(err){ - if (err) return callback(err); - - doBindings(channel, config.bindings, callback); - }) + palinode.mapEach(config.bindings, Fudd._createBindings.bind(null, channel), function(err) { + if (err) return finalCallback(err); + finalCallback(); + }); + }); + }); }); - }); - - function doBindings(channel, bindings, callback){ - if (bindings.length === 0) return callback(); - - var binding = bindings.pop(); - var boundBindings = doBindings.bind(this, channel, bindings, callback); - bindAllKeys(channel, binding, binding.bindingKeys, boundBindings); - } - - function bindAllKeys(channel, binding, keys, callback){ - if (keys.length === 0) return callback(); - - - var key = keys.pop(); - var onBound = bindAllKeys.bind(this, channel, binding, keys, callback); - console.log('binding'); - if (binding.bindingType === 'queue') { - channel.bindQueue(binding.to, binding.from, key, {}, onBound); + }, + teardown: function(callback) { + callback(); + }, + _createExchange: function(channel, exchangeDefinition, callback) { + channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, callback); + }, + _createQueue: function(channel, queueDefinition, callback) { + channel.assertQueue(queueDefinition.name, queueDefinition.options, callback); + }, + _createBindings: function(channel, bindingDefinition, callback) { + var boundCreateBinding = Fudd._createBinding.bind(null, channel, bindingDefinition); + palinode.mapEach(bindingDefinition.bindingKeys, boundCreateBinding, callback); + }, + _createBinding: function(channel, bindingDefinition, bindingKey, callback) { + if (bindingDefinition.bindingType === 'queue') { + channel.bindQueue(bindingDefinition.to, bindingDefinition.from, bindingKey, bindingDefinition.options, callback); } else { - channel.bindExchange(binding.to, binding.from, key, {}, onBound); + channel.bindExchange(bindingDefinition.to, bindingDefinition.from, bindingKey, bindingDefinition.options, callback); } - } + }, + _connect: function(config, callback) { + var url = formatAmqpUrl(config.cluster); + amqp.connect(url, function(error, connection) { + if (error) return callback(error); - function createQueues(channel, queueKeys, callback){ - if (queueKeys.length === 0) return callback(); - var queueKey = queueKeys.pop(); + connection.createChannel(function(error, channel) { + if (error) return callback(error); - console.log('asserting Q'); - var exchangeAsserted = createQueues.bind(this, channel, queueKeys, callback); - channel.assertQueue(queueKey, {durable: true}, exchangeAsserted); - } - - function createExchanges(channel, exchangeKeys, callback) { - if (exchangeKeys.length === 0) return callback(); - var exchangeKey = exchangeKeys.pop(); - - console.log('asserting'); - var exchangeAsserted = createExchanges.bind(this, channel, exchangeKeys, callback); - channel.assertExchange(exchangeKey, config.exchanges[exchangeKey].type, {}, exchangeAsserted); + callback(connection, channel); + }); + }); } }; -Fudd.prototype.teardown = function(callback){ - callback(); -}; - -function connect(config, callback) { - var url = formatAmqpUrl(config.cluster); - amqp.connect(url, function(error, connection) { - if (error) throw error; - connection.createChannel(function(error, channel) { - if (error) throw error; - callback(connection, channel); - }); - }); -} +module.exports = Object.create(Fudd); \ No newline at end of file diff --git a/package.json b/package.json index b156fa4..679c00d 100644 --- a/package.json +++ b/package.json @@ -15,14 +15,17 @@ "homepage": "https://github.com/GannettDigital/fudd#readme", "devDependencies": { "chai": "3.5.0", + "config": "^1.21.0", "coveralls": "2.11.9", "istanbul": "0.4.3", "jscs": "^3.0.4", "mocha": "2.5.3", - "mockery": "1.7.0" + "mockery": "1.7.0", + "sinon": "1.17.4" }, "dependencies": { - "amqplib": "0.4.2" + "amqplib": "0.4.2", + "palinode": "0.0.3" }, "scripts": { "test": "mocha --recursive test/unit", diff --git a/test/integration/config/default.js b/test/integration/config/default.js new file mode 100644 index 0000000..1210e7d --- /dev/null +++ b/test/integration/config/default.js @@ -0,0 +1,41 @@ +module.exports = { + // app configuration: + key: {nested: 'value'} + + /*testInfrastructure: { + // fudd configuration example + cluster: { + port: 5672, + vhost: '/', + login: 'user', + heartbeat: 10, + password: 'password', + host: 'host.com' + }, + exchanges: { + 'fanout.fx': { + type: 'fanout' + }, + 'topic.tx': { + type: 'topic' + } + }, + queues: { + 'queue1': {} + }, + bindings: [ + { + bindingType: 'queue', + from: 'fanout.fx', + to: 'queue1', + bindingKeys: ['#'] + }, + { + bindingType: 'exchange', + from: 'fanout.fx', + to: 'topic.tx', + bindingKeys: ['#'] + } + ] + }*/ +}; \ No newline at end of file diff --git a/test/integration/config/local.js b/test/integration/config/local.js new file mode 100644 index 0000000..ae4fc1e --- /dev/null +++ b/test/integration/config/local.js @@ -0,0 +1,55 @@ +'use strict'; +module.exports = { + cluster: { + port: 5672, + vhost: '/', + login: 'gduser', + heartbeat: 10, + password: 'Passw0rd', + host: '845-3512-scalr.development.gannettdigital.com' + }, + exchanges: [ + { + name: 'fanout.fx', + type: 'fanout', + options: {} + }, + { + name: 'topic.tx', + type: 'topic', + options: {} + } + ], + queues: [ + { + name: 'queue1', + options: {durable: true} + }, + { + name: 'queue2', + options: {durable: false} + } + ], + + bindings: [ + { + bindingType: 'queue', + from: 'fanout.fx', + to: 'queue1', + bindingKeys: ['#'] + }, + { + bindingType: 'exchange', + from: 'fanout.fx', + to: 'topic.tx', + bindingKeys: ['#'], + options: {} + }, + { + bindingType: 'queue', + from: 'topic.tx', + to: 'queue2', + bindingKeys: ['#.topic1', '#.topic2'] + } + ] +}; \ No newline at end of file diff --git a/test/integration/fudd.js b/test/integration/fudd.js new file mode 100644 index 0000000..cd3e608 --- /dev/null +++ b/test/integration/fudd.js @@ -0,0 +1,21 @@ +'use strict'; + +var expect = require('chai').expect; +var fudd = require('../../index.js'); +var config = require('config'); + +describe('fudd integration test', function(){ + this.timeout(5000); + + before('setup', function(done){ + fudd.setup(config, done); + }); + + it('should do stuff', function(done){ + done(); + }); + + after('teardown', function(done){ + fudd.teardown(done); + }) +}); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 0f3c550..5ab9c81 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -1,18 +1,45 @@ 'use strict'; var expect = require('chai').expect; +var mockery = require('mockery'); +var sinon = require('sinon'); describe('fudd', function() { var fudd; - before(function() { - var Fudd = require('../../lib/fudd.js'); - fudd = new Fudd(); + var configUtilsStub; + + before('enable mockery', function() { + mockery.enable({useCleanCache: true}); + }); + + beforeEach('setup mocks', function(){ + mockery.registerAllowable('../../lib/fudd.js'); + mockery.registerAllowable('util'); + + mockery.registerMock('amqplib/callback_api', {}); + mockery.registerMock('palinode', {}); + mockery.registerMock('./amqp-config-utils.js', configUtilsStub = sinon.stub().returns('amqp://some.host')); + + fudd = require('../../lib/fudd.js'); }); - describe('init', function() { - it('should return true', function() { - var result = fudd.init(); - expect(result).to.equal(true); + after('disable mockery', mockery.disable); + + describe('setup', function() { + it('should call connect with supplied config', function() { + var connectSpy = sinon.spy(); + fudd.__proto__._connect = connectSpy; + var config = {key: 'value'}; + fudd.setup(config); + expect(connectSpy.calledWith(config)).to.equal(true); + }); + + it('should call connect with supplied config', function() { + var connectSpy = sinon.spy(); + fudd.__proto__._connect = connectSpy; + var config = {key: 'value'}; + fudd.setup(config); + expect(connectSpy.calledWith(config)).to.equal(true); }); }); }); From e0a45ae172494bfaf2cd916f0ddaa87a51c6d813 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 13:12:29 -0400 Subject: [PATCH 03/37] add teardown & rabbitmq to travis --- .travis.yml | 2 + lib/fudd.js | 22 +++++++- package.json | 1 + test/integration/config/default.js | 88 +++++++++++++++++------------- test/integration/config/local.js | 2 +- test/integration/fudd.js | 14 ++--- test/unit/fudd.js | 2 +- 7 files changed, 82 insertions(+), 49 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3fb1b13..99573d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: node_js +services: +- rabbitmq node_js: - "6" - "6.1" diff --git a/lib/fudd.js b/lib/fudd.js index dac5037..f69d287 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -22,8 +22,18 @@ var Fudd = { }); }); }, - teardown: function(callback) { - callback(); + teardown: function(config, finalCallback) { + Fudd._connect(config, function(connection, channel) { + palinode.mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { + if (err) return finalCallback(err); + + palinode.mapEach(config.queues, Fudd._deleteQueue.bind(null, channel), function(err) { + if (err) return finalCallback(err); + + finalCallback(); + }); + }); + }); }, _createExchange: function(channel, exchangeDefinition, callback) { channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, callback); @@ -42,6 +52,12 @@ var Fudd = { channel.bindExchange(bindingDefinition.to, bindingDefinition.from, bindingKey, bindingDefinition.options, callback); } }, + _deleteExchange: function(channel, exchangeDefinition, callback) { + channel.deleteExchange(exchangeDefinition.name, {}, callback); + }, + _deleteQueue: function(channel, queueDefinition, callback) { + channel.deleteQueue(queueDefinition.name, {}, callback); + }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); amqp.connect(url, function(error, connection) { @@ -56,4 +72,4 @@ var Fudd = { } }; -module.exports = Object.create(Fudd); \ No newline at end of file +module.exports = Object.create(Fudd); diff --git a/package.json b/package.json index 679c00d..ac9e20b 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "scripts": { "test": "mocha --recursive test/unit", "lint": "./node_modules/.bin/jscs ./lib/ ./test", + "fix-lint": "npm run lint -- -x", "cover": "node ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec test/unit --recursive", "coveralls": "npm run cover && ./node_modules/coveralls/bin/coveralls.js < coverage/lcov.info" } diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 1210e7d..f83de83 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -1,41 +1,55 @@ +'use strict'; module.exports = { - // app configuration: - key: {nested: 'value'} - - /*testInfrastructure: { - // fudd configuration example - cluster: { - port: 5672, - vhost: '/', - login: 'user', - heartbeat: 10, - password: 'password', - host: 'host.com' + cluster: { + port: 5672, + vhost: '/', + login: 'guest', + heartbeat: 10, + password: 'guest', + host: 'localhost' + }, + exchanges: [ + { + name: 'fanout.fx', + type: 'fanout', + options: {} + }, + { + name: 'topic.tx', + type: 'topic', + options: {} + } + ], + queues: [ + { + name: 'queue1', + options: {durable: true} }, - exchanges: { - 'fanout.fx': { - type: 'fanout' - }, - 'topic.tx': { - type: 'topic' - } + { + name: 'queue2', + options: {durable: false} + } + ], + + bindings: [ + { + bindingType: 'queue', + from: 'fanout.fx', + to: 'queue1', + bindingKeys: ['#'] }, - queues: { - 'queue1': {} + { + bindingType: 'exchange', + from: 'fanout.fx', + to: 'topic.tx', + bindingKeys: ['#'], + options: {} }, - bindings: [ - { - bindingType: 'queue', - from: 'fanout.fx', - to: 'queue1', - bindingKeys: ['#'] - }, - { - bindingType: 'exchange', - from: 'fanout.fx', - to: 'topic.tx', - bindingKeys: ['#'] - } - ] - }*/ -}; \ No newline at end of file + { + bindingType: 'queue', + from: 'topic.tx', + to: 'queue2', + bindingKeys: ['#.topic1', '#.topic2'] + } + ] +}; diff --git a/test/integration/config/local.js b/test/integration/config/local.js index ae4fc1e..e850e61 100644 --- a/test/integration/config/local.js +++ b/test/integration/config/local.js @@ -52,4 +52,4 @@ module.exports = { bindingKeys: ['#.topic1', '#.topic2'] } ] -}; \ No newline at end of file +}; diff --git a/test/integration/fudd.js b/test/integration/fudd.js index cd3e608..e48537f 100644 --- a/test/integration/fudd.js +++ b/test/integration/fudd.js @@ -4,18 +4,18 @@ var expect = require('chai').expect; var fudd = require('../../index.js'); var config = require('config'); -describe('fudd integration test', function(){ +describe('fudd integration test', function() { this.timeout(5000); - before('setup', function(done){ + before('setup', function(done) { fudd.setup(config, done); }); - it('should do stuff', function(done){ - done(); + it('should do stuff', function(done) { + setTimeout(done, 4000); }); - after('teardown', function(done){ - fudd.teardown(done); - }) + after('teardown', function(done) { + fudd.teardown(config, done); + }); }); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 5ab9c81..0a20700 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -12,7 +12,7 @@ describe('fudd', function() { mockery.enable({useCleanCache: true}); }); - beforeEach('setup mocks', function(){ + beforeEach('setup mocks', function() { mockery.registerAllowable('../../lib/fudd.js'); mockery.registerAllowable('util'); From fd3befa9f4de62f2ed7d4d28a1412e6272f44402 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 13:17:14 -0400 Subject: [PATCH 04/37] more travis configuration --- .travis.yml | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 99573d1..de10620 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: node_js services: - rabbitmq +env: +- NODE_CONFIG_DIR='./test/integration/config' node_js: - "6" - "6.1" diff --git a/package.json b/package.json index ac9e20b..ea1b010 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "palinode": "0.0.3" }, "scripts": { - "test": "mocha --recursive test/unit", + "test": "mocha --recursive test/unit --recursive test/integration", "lint": "./node_modules/.bin/jscs ./lib/ ./test", "fix-lint": "npm run lint -- -x", "cover": "node ./node_modules/.bin/istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec test/unit --recursive", From 66f9eec10a97b6df2969a2143c5f4116869a050a Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 13:24:22 -0400 Subject: [PATCH 05/37] more travis configuration --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index de10620..93ee508 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: node_js +sudo: required services: - rabbitmq env: From 32a7ce4eb9ccb244878ba45c6db92107239941a8 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 13:59:39 -0400 Subject: [PATCH 06/37] fixed some sequencing logic --- lib/fudd.js | 63 ++++++++++++++++++++++++++++++----------------- test/unit/fudd.js | 31 +++++++++-------------- 2 files changed, 53 insertions(+), 41 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index dac5037..8123e86 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -1,24 +1,36 @@ 'use strict'; var amqp = require('amqplib/callback_api'); var formatAmqpUrl = require('./amqp-config-utils.js'); -var palinode = require('palinode'); +var series = require('palinode').series; +var mapEach = require('palinode').mapEach; var Fudd = { setup: function(config, finalCallback) { - Fudd._connect(config, function(connection, channel) { - //TODO: re-write using palinode.series - palinode.mapEach(config.exchanges, Fudd._createExchange.bind(null, channel), function(err) { - if (err) return finalCallback(err); + var establishChannel = [Fudd._connect.bind(null, config), Fudd._createChannel]; - palinode.mapEach(config.queues, Fudd._createQueue.bind(null, channel), function(err) { - if (err) return finalCallback(err); + series(establishChannel, function(error, connection, channel) { + if(error) return finalCallback(error); + var infrastructure = []; - palinode.mapEach(config.bindings, Fudd._createBindings.bind(null, channel), function(err) { - if (err) return finalCallback(err); - finalCallback(); - }); - }); + config.exchanges.reduce(function(series, exchangeDefinition) { + series.push(Fudd._createExchange.bind(null, channel, exchangeDefinition)); + return series; + }, infrastructure); + + config.queues.reduce(function(series, queueDefinition) { + series.push(Fudd._createQueue.bind(null, channel, queueDefinition)); + return series; + }, infrastructure); + + config.bindings.reduce(function(series, bindingDefinition) { + series.push(Fudd._createBindings.bind(null, channel, bindingDefinition)); + return series; + }, infrastructure); + + series(infrastructure, function(error) { + if(error) return finalCallback(error); + Fudd._disconnect(connection, finalCallback); }); }); }, @@ -26,14 +38,20 @@ var Fudd = { callback(); }, _createExchange: function(channel, exchangeDefinition, callback) { - channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, callback); + channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error){ + callback(error) + }); }, _createQueue: function(channel, queueDefinition, callback) { - channel.assertQueue(queueDefinition.name, queueDefinition.options, callback); + channel.assertQueue(queueDefinition.name, queueDefinition.options, function(error) { + callback(error); + }); }, _createBindings: function(channel, bindingDefinition, callback) { var boundCreateBinding = Fudd._createBinding.bind(null, channel, bindingDefinition); - palinode.mapEach(bindingDefinition.bindingKeys, boundCreateBinding, callback); + mapEach(bindingDefinition.bindingKeys, boundCreateBinding, function(error) { + callback(error); + }); }, _createBinding: function(channel, bindingDefinition, bindingKey, callback) { if (bindingDefinition.bindingType === 'queue') { @@ -44,15 +62,16 @@ var Fudd = { }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); - amqp.connect(url, function(error, connection) { + amqp.connect(url, callback); + }, + _createChannel: function(connection, callback) { + connection.createChannel(function(error, channel) { if (error) return callback(error); - - connection.createChannel(function(error, channel) { - if (error) return callback(error); - - callback(connection, channel); - }); + callback(null, connection, channel); }); + }, + _disconnect: function(connection, callback) { + connection.close(callback); } }; diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 5ab9c81..2931e68 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -5,13 +5,15 @@ var sinon = require('sinon'); describe('fudd', function() { - var fudd; + var Fudd; var configUtilsStub; before('enable mockery', function() { mockery.enable({useCleanCache: true}); }); + after('disable mockery', mockery.disable); + beforeEach('setup mocks', function(){ mockery.registerAllowable('../../lib/fudd.js'); mockery.registerAllowable('util'); @@ -20,26 +22,17 @@ describe('fudd', function() { mockery.registerMock('palinode', {}); mockery.registerMock('./amqp-config-utils.js', configUtilsStub = sinon.stub().returns('amqp://some.host')); - fudd = require('../../lib/fudd.js'); + Fudd = require('../../lib/fudd.js'); }); - after('disable mockery', mockery.disable); - describe('setup', function() { - it('should call connect with supplied config', function() { - var connectSpy = sinon.spy(); - fudd.__proto__._connect = connectSpy; - var config = {key: 'value'}; - fudd.setup(config); - expect(connectSpy.calledWith(config)).to.equal(true); - }); - - it('should call connect with supplied config', function() { - var connectSpy = sinon.spy(); - fudd.__proto__._connect = connectSpy; - var config = {key: 'value'}; - fudd.setup(config); - expect(connectSpy.calledWith(config)).to.equal(true); - }); + var config = {thisIs: 'config'}; + var connectBindStub; + + before('setup stubs', function() { + connectBindStub + }) + + }); }); From 7f676d40f1e29011e2a259a2667abcc483ef15d8 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:06:32 -0400 Subject: [PATCH 07/37] lint --- lib/fudd.js | 8 ++++---- test/unit/fudd.js | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 03a3452..fa0a344 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -10,7 +10,7 @@ var Fudd = { var establishChannel = [Fudd._connect.bind(null, config), Fudd._createChannel]; series(establishChannel, function(error, connection, channel) { - if(error) return finalCallback(error); + if (error) return finalCallback(error); var infrastructure = []; config.exchanges.reduce(function(series, exchangeDefinition) { @@ -29,7 +29,7 @@ var Fudd = { }, infrastructure); series(infrastructure, function(error) { - if(error) return finalCallback(error); + if (error) return finalCallback(error); Fudd._disconnect(connection, finalCallback); }); }); @@ -48,8 +48,8 @@ var Fudd = { }); }, _createExchange: function(channel, exchangeDefinition, callback) { - channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error){ - callback(error) + channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error) { + callback(error); }); }, _createQueue: function(channel, queueDefinition, callback) { diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 2931e68..fc3524a 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -14,7 +14,7 @@ describe('fudd', function() { after('disable mockery', mockery.disable); - beforeEach('setup mocks', function(){ + beforeEach('setup mocks', function() { mockery.registerAllowable('../../lib/fudd.js'); mockery.registerAllowable('util'); @@ -30,9 +30,8 @@ describe('fudd', function() { var connectBindStub; before('setup stubs', function() { - connectBindStub - }) - + connectBindStub; + }); }); }); From 0e8669ccff4db5087a0429f4389b5c342c28662e Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:14:58 -0400 Subject: [PATCH 08/37] rabbit test --- lib/fudd.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index fa0a344..6724cb0 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -36,10 +36,10 @@ var Fudd = { }, teardown: function(config, finalCallback) { Fudd._connect(config, function(connection, channel) { - palinode.mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { + mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { if (err) return finalCallback(err); - palinode.mapEach(config.queues, Fudd._deleteQueue.bind(null, channel), function(err) { + mapEach(config.queues, Fudd._deleteQueue.bind(null, channel), function(err) { if (err) return finalCallback(err); finalCallback(); @@ -48,6 +48,7 @@ var Fudd = { }); }, _createExchange: function(channel, exchangeDefinition, callback) { + console.log('creating exchange'); channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error) { callback(error); }); @@ -78,11 +79,14 @@ var Fudd = { }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); + console.log('connecting'); amqp.connect(url, callback); }, _createChannel: function(connection, callback) { + console.log('creating channel'); connection.createChannel(function(error, channel) { if (error) return callback(error); + console.log('created channel'); callback(null, connection, channel); }); }, From 2ef7dd05fd5bbbf2f0f403ec4f55a4f9c72b656a Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 14:23:53 -0400 Subject: [PATCH 09/37] unit test progress --- test/unit/fudd.js | 68 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 2931e68..59ee931 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -3,36 +3,86 @@ var expect = require('chai').expect; var mockery = require('mockery'); var sinon = require('sinon'); +var config = { + exchanges: [ + { + name: 'fanout.fx', + type: 'fanout', + options: {} + } + ], + queues: [ + { + name: 'queue1', + options: {durable: true} + } + ], + + bindings: [ + { + bindingType: 'queue', + from: 'fanout.fx', + to: 'queue1', + bindingKeys: ['#'] + } + ] +}; + describe('fudd', function() { var Fudd; var configUtilsStub; + var mapEachStub; + var seriesStub; before('enable mockery', function() { mockery.enable({useCleanCache: true}); - }); - - after('disable mockery', mockery.disable); - - beforeEach('setup mocks', function(){ mockery.registerAllowable('../../lib/fudd.js'); - mockery.registerAllowable('util'); mockery.registerMock('amqplib/callback_api', {}); - mockery.registerMock('palinode', {}); + mockery.registerMock('palinode', { + series: seriesStub = sinon.stub(), + mapEach: mapEachStub = sinon.stub() + }); mockery.registerMock('./amqp-config-utils.js', configUtilsStub = sinon.stub().returns('amqp://some.host')); Fudd = require('../../lib/fudd.js'); }); + after('disable mockery', mockery.disable); + describe('setup', function() { var config = {thisIs: 'config'}; + var callbackSpy; var connectBindStub; + var boundConnect = function connectBindResult() {}; before('setup stubs', function() { - connectBindStub - }) + connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); + }); + + after('restore stubbed methods', function() { + Fudd._connect.bind.restore(); + }); + + beforeEach('reset stubs', function() { + callbackSpy = sinon.spy(); + connectBindStub.reset(); + seriesStub.reset(); + mapEachStub.reset(); + Fudd.setup(config, callbackSpy); + }); + + it('should bind config to the _connect function', function() { + expect(connectBindStub.args[0]).to.eql([ + null, config + ]); + }); + it('should invoke series with the bound _connect and Fudd._create channel functions', function() { + expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]) + }); + it('') }); }); From fab0777587d4deb659b1f3d34caedd1877e0979c Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:24:08 -0400 Subject: [PATCH 10/37] rabbit test --- .travis.yml | 2 ++ test/integration/config/default.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93ee508..73fe60a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,8 @@ node_js: - "0.12" before_script: - npm run lint +- rabbitmqctl add_user travis p@$$ +- rabbitmqctl set_permissions travis ".*" ".*" ".*" after_script: - npm run coveralls deploy: diff --git a/test/integration/config/default.js b/test/integration/config/default.js index f83de83..2f3fe39 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -3,9 +3,9 @@ module.exports = { cluster: { port: 5672, vhost: '/', - login: 'guest', + login: 'p@$$', heartbeat: 10, - password: 'guest', + password: 'p@$$', host: 'localhost' }, exchanges: [ From ba59e2d306b1b16d90dc837cd93add983e665e82 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 14:26:43 -0400 Subject: [PATCH 11/37] cleanup --- lib/fudd.js | 4 ---- test/unit/fudd.js | 2 -- 2 files changed, 6 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 6724cb0..7a79f1d 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -48,7 +48,6 @@ var Fudd = { }); }, _createExchange: function(channel, exchangeDefinition, callback) { - console.log('creating exchange'); channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error) { callback(error); }); @@ -79,14 +78,11 @@ var Fudd = { }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); - console.log('connecting'); amqp.connect(url, callback); }, _createChannel: function(connection, callback) { - console.log('creating channel'); connection.createChannel(function(error, channel) { if (error) return callback(error); - console.log('created channel'); callback(null, connection, channel); }); }, diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 51b6efc..81b4c2b 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -54,8 +54,6 @@ describe('fudd', function() { Fudd = require('../../lib/fudd.js'); }); - after('disable mockery', mockery.disable); - describe('setup', function() { var config = {thisIs: 'config'}; var callbackSpy; From 64654da236d7a05b67c48d9c39ee4adc738f61b9 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:27:09 -0400 Subject: [PATCH 12/37] rabbit test --- .travis.yml | 4 ++-- test/integration/config/default.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 73fe60a..9c9a990 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,8 +11,8 @@ node_js: - "0.12" before_script: - npm run lint -- rabbitmqctl add_user travis p@$$ -- rabbitmqctl set_permissions travis ".*" ".*" ".*" +- sudo rabbitmqctl add_user travis p@$$ +- sudo rabbitmqctl set_permissions travis ".*" ".*" ".*" after_script: - npm run coveralls deploy: diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 2f3fe39..9ca6ded 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -6,7 +6,7 @@ module.exports = { login: 'p@$$', heartbeat: 10, password: 'p@$$', - host: 'localhost' + host: 'server' }, exchanges: [ { From adfabe6c34443f398cbabf752d628180b3cb0afc Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:27:50 -0400 Subject: [PATCH 13/37] rabbit test --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9c9a990..c42ac41 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ node_js: - "0.12" before_script: - npm run lint +- sudo rabbitmqctl status - sudo rabbitmqctl add_user travis p@$$ - sudo rabbitmqctl set_permissions travis ".*" ".*" ".*" after_script: From e4f52d33e2388003727474ba2470aca95dccd2ae Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:28:20 -0400 Subject: [PATCH 14/37] lint --- test/unit/fudd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 81b4c2b..15b2279 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -86,6 +86,6 @@ describe('fudd', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - it('') + it(''); }); }); From 2ab3fb9e9c4769801c54eabf804b406ca6bcd9a1 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 14:35:52 -0400 Subject: [PATCH 15/37] fix unit test start sequence --- test/unit/fudd.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 81b4c2b..846619b 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -37,11 +37,6 @@ describe('fudd', function() { before('enable mockery', function() { mockery.enable({useCleanCache: true}); - }); - - after('disable mockery', mockery.disable); - - beforeEach('setup mocks', function() { mockery.registerAllowable('../../lib/fudd.js'); mockery.registerMock('amqplib/callback_api', {}); @@ -54,6 +49,8 @@ describe('fudd', function() { Fudd = require('../../lib/fudd.js'); }); + after('disable mockery', mockery.disable); + describe('setup', function() { var config = {thisIs: 'config'}; var callbackSpy; @@ -61,6 +58,7 @@ describe('fudd', function() { var boundConnect = function connectBindResult() {}; before('setup stubs', function() { + callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); }); @@ -69,7 +67,7 @@ describe('fudd', function() { }); beforeEach('reset stubs', function() { - callbackSpy = sinon.spy(); + callbackSpy.reset(); connectBindStub.reset(); seriesStub.reset(); mapEachStub.reset(); @@ -85,7 +83,5 @@ describe('fudd', function() { it('should invoke series with the bound _connect and Fudd._create channel functions', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - - it('') }); }); From e7f291eff14c02df5646a6ad6e745df6c483b136 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 14:40:27 -0400 Subject: [PATCH 16/37] lint --- test/integration/config/default.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 9ca6ded..683bfc4 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -1,4 +1,5 @@ 'use strict'; +var os = require('os'); module.exports = { cluster: { port: 5672, @@ -6,7 +7,7 @@ module.exports = { login: 'p@$$', heartbeat: 10, password: 'p@$$', - host: 'server' + host: os.hostname() }, exchanges: [ { From 6baa38ec82f56715fe408644c7a3a0920c63e199 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 14:51:06 -0400 Subject: [PATCH 17/37] more tests for setup --- test/unit/fudd.js | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 9587243..b54e5a4 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -52,18 +52,29 @@ describe('fudd', function() { after('disable mockery', mockery.disable); describe('setup', function() { - var config = {thisIs: 'config'}; var callbackSpy; var connectBindStub; + var createExchangeBindStub; + var createQueueBindStub; + var createBindingsBindStub; var boundConnect = function connectBindResult() {}; + var boundCreateExchange = function createExchangeBindResult() {}; + var boundCreateQueue = function createQueueBindResult() {}; + var boundCreateBindings = function createBindingsBindResult() {}; before('setup stubs', function() { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); + createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); + createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); + createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); }); after('restore stubbed methods', function() { Fudd._connect.bind.restore(); + Fudd._createExchange.bind.restore(); + Fudd._createQueue.bind.restore(); + Fudd._createBindings.bind.restore(); }); beforeEach('reset stubs', function() { @@ -71,6 +82,9 @@ describe('fudd', function() { connectBindStub.reset(); seriesStub.reset(); mapEachStub.reset(); + createExchangeBindStub.reset(); + createQueueBindStub.reset(); + createBindingsBindStub.reset(); Fudd.setup(config, callbackSpy); }); @@ -84,5 +98,15 @@ describe('fudd', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); + it('should invoke series again with a sequence of functions derived from the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(seriesStub.args[1][0]).to.eql([ + boundCreateExchange, + boundCreateQueue, + boundCreateBindings + ]); + }); + + }); }); From 80d92f8306a3e46fdbacfddcd84eac0f91618b31 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:10:06 -0400 Subject: [PATCH 18/37] remove local.js --- test/integration/config/local.js | 55 -------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 test/integration/config/local.js diff --git a/test/integration/config/local.js b/test/integration/config/local.js deleted file mode 100644 index e850e61..0000000 --- a/test/integration/config/local.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict'; -module.exports = { - cluster: { - port: 5672, - vhost: '/', - login: 'gduser', - heartbeat: 10, - password: 'Passw0rd', - host: '845-3512-scalr.development.gannettdigital.com' - }, - exchanges: [ - { - name: 'fanout.fx', - type: 'fanout', - options: {} - }, - { - name: 'topic.tx', - type: 'topic', - options: {} - } - ], - queues: [ - { - name: 'queue1', - options: {durable: true} - }, - { - name: 'queue2', - options: {durable: false} - } - ], - - bindings: [ - { - bindingType: 'queue', - from: 'fanout.fx', - to: 'queue1', - bindingKeys: ['#'] - }, - { - bindingType: 'exchange', - from: 'fanout.fx', - to: 'topic.tx', - bindingKeys: ['#'], - options: {} - }, - { - bindingType: 'queue', - from: 'topic.tx', - to: 'queue2', - bindingKeys: ['#.topic1', '#.topic2'] - } - ] -}; From 6d4554e0de8f9b4d42fc57241cc6920b24963a5d Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:11:13 -0400 Subject: [PATCH 19/37] tweak rabbit settings --- .travis.yml | 6 +++--- test/integration/config/default.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index c42ac41..33e6a43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: node_js sudo: required +addons: + hosts: + - rabbit services: - rabbitmq env: @@ -11,9 +14,6 @@ node_js: - "0.12" before_script: - npm run lint -- sudo rabbitmqctl status -- sudo rabbitmqctl add_user travis p@$$ -- sudo rabbitmqctl set_permissions travis ".*" ".*" ".*" after_script: - npm run coveralls deploy: diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 683bfc4..12531e3 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -4,10 +4,10 @@ module.exports = { cluster: { port: 5672, vhost: '/', - login: 'p@$$', + login: 'test', heartbeat: 10, - password: 'p@$$', - host: os.hostname() + password: 'test', + host: 'rabbit' }, exchanges: [ { From 35e027827837aaef5fb67e6e2cc677d01a3dd004 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:12:41 -0400 Subject: [PATCH 20/37] update gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 44ce220..4ecb5ef 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,4 @@ jspm_packages # Optional REPL history .node_repl_history -./test/integration/config/local.js \ No newline at end of file +local.js \ No newline at end of file From 0c6d3120cbb2e7b77210bb13a3d9fe76f1490603 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:13:41 -0400 Subject: [PATCH 21/37] fix teardown --- lib/fudd.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/fudd.js b/lib/fudd.js index 7a79f1d..7ac631d 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -35,7 +35,9 @@ var Fudd = { }); }, teardown: function(config, finalCallback) { - Fudd._connect(config, function(connection, channel) { + var establishChannel = [Fudd._connect.bind(null, config), Fudd._createChannel]; + + series(establishChannel, function(error, connection, channel) { mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { if (err) return finalCallback(err); From 8dd2630f148b8a211d66b6c3d93fac066d288b3d Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:14:07 -0400 Subject: [PATCH 22/37] lint --- test/unit/fudd.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index b54e5a4..cad6004 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -107,6 +107,5 @@ describe('fudd', function() { ]); }); - }); }); From f544f0a2eefbb392d1e3f32df57d75e15c77a56e Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:20:00 -0400 Subject: [PATCH 23/37] readme updates --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 635bb80..2f579cb 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,35 @@ simple rabbit mq infrastructure setup/teardown utility ## Installation +``` +npm install fudd``` ## Test +```npm run test``` +This will run both unit tests & integration tests. To successfully run integration tests, you must have a rabbitmq instance +available & configured. See Configuration for examples + ## Coverage +```npm run cover-html``` + ## Usage +``` +var fudd = require('fudd'); + +fudd.setup(config, function(err){ + if(err) throw err; + + // do your thing with rabbitmq +}); + +fudd.teardown(config, function(err){ + if(err) throw err; + + // all things torn +}); +``` + ## Configuration \ No newline at end of file From b8eece0845a54af52a3f28fd9cc0a99b9c371efd Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:20:34 -0400 Subject: [PATCH 24/37] update rabbit credentials --- test/integration/config/default.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 12531e3..05be31b 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -4,9 +4,9 @@ module.exports = { cluster: { port: 5672, vhost: '/', - login: 'test', + login: 'guest', heartbeat: 10, - password: 'test', + password: 'guest', host: 'rabbit' }, exchanges: [ From ac795d069a399e178c092e400e1d50ca6482138d Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 15:21:41 -0400 Subject: [PATCH 25/37] readme updates --- README.md | 60 +++++++++++++++++++++++++++++- test/integration/config/default.js | 1 - 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2f579cb..2ef86c4 100644 --- a/README.md +++ b/README.md @@ -36,4 +36,62 @@ fudd.teardown(config, function(err){ }); ``` -## Configuration \ No newline at end of file +## Configuration + +Configuration should look like the following: +```javascript +{ + cluster: { + port: 5672, + vhost: '/', + login: 'guest', + heartbeat: 10, + password: 'guest', + host: 'rabbit' + }, + exchanges: [ + { + name: 'fanout.fx', + type: 'fanout', + options: {} + }, + { + name: 'topic.tx', + type: 'topic', + options: {} + } + ], + queues: [ + { + name: 'queue1', + options: {durable: true} + }, + { + name: 'queue2', + options: {durable: false} + } + ], + + bindings: [ + { + bindingType: 'queue', + from: 'fanout.fx', + to: 'queue1', + bindingKeys: ['#'] + }, + { + bindingType: 'exchange', + from: 'fanout.fx', + to: 'topic.tx', + bindingKeys: ['#'], + options: {} + }, + { + bindingType: 'queue', + from: 'topic.tx', + to: 'queue2', + bindingKeys: ['#.topic1', '#.topic2'] + } + ] +} +``` \ No newline at end of file diff --git a/test/integration/config/default.js b/test/integration/config/default.js index 05be31b..2d54edd 100644 --- a/test/integration/config/default.js +++ b/test/integration/config/default.js @@ -1,5 +1,4 @@ 'use strict'; -var os = require('os'); module.exports = { cluster: { port: 5672, From 32bc8ddd072eac25f8331e1797f6edcb926fe7ec Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 15:47:53 -0400 Subject: [PATCH 26/37] setup tests complete --- test/unit/fudd.js | 61 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index b54e5a4..e6685cd 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -17,7 +17,6 @@ var config = { options: {durable: true} } ], - bindings: [ { bindingType: 'queue', @@ -29,24 +28,13 @@ var config = { }; describe('fudd', function() { - var Fudd; - var configUtilsStub; var mapEachStub; var seriesStub; before('enable mockery', function() { mockery.enable({useCleanCache: true}); mockery.registerAllowable('../../lib/fudd.js'); - - mockery.registerMock('amqplib/callback_api', {}); - mockery.registerMock('palinode', { - series: seriesStub = sinon.stub(), - mapEach: mapEachStub = sinon.stub() - }); - mockery.registerMock('./amqp-config-utils.js', configUtilsStub = sinon.stub().returns('amqp://some.host')); - - Fudd = require('../../lib/fudd.js'); }); after('disable mockery', mockery.disable); @@ -54,6 +42,7 @@ describe('fudd', function() { describe('setup', function() { var callbackSpy; var connectBindStub; + var disconnectStub; var createExchangeBindStub; var createQueueBindStub; var createBindingsBindStub; @@ -62,9 +51,22 @@ describe('fudd', function() { var boundCreateQueue = function createQueueBindResult() {}; var boundCreateBindings = function createBindingsBindResult() {}; + before('setup mocks', function() { + mockery.deregisterAll(); + mockery.resetCache(); + mockery.registerMock('amqplib/callback_api', {}); + mockery.registerMock('palinode', { + series: seriesStub = sinon.stub(), + mapEach: mapEachStub = sinon.stub() + }); + mockery.registerMock('./amqp-config-utils.js', {}); + Fudd = require('../../lib/fudd.js'); + }); + before('setup stubs', function() { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); + Fudd.__proto__._disconnect = disconnectStub = sinon.spy(); createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); @@ -80,6 +82,7 @@ describe('fudd', function() { beforeEach('reset stubs', function() { callbackSpy.reset(); connectBindStub.reset(); + disconnectStub.reset(); seriesStub.reset(); mapEachStub.reset(); createExchangeBindStub.reset(); @@ -98,6 +101,27 @@ describe('fudd', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); + it('should call the finalCallback if the first series call calls back with an error', function() { + var expectedError = new Error('things happened'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + + it('should call _createExchange.bind for each exchange in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createExchangeBindStub.callCount).to.equal(config.exchanges.length); + }); + + it('should call _createExchange.bind for each queue in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createQueueBindStub.callCount).to.equal(config.queues.length); + }); + + it('should call _createExchange.bind for each binding in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createBindingsBindStub.callCount).to.equal(config.bindings.length); + }); + it('should invoke series again with a sequence of functions derived from the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(seriesStub.args[1][0]).to.eql([ @@ -107,6 +131,19 @@ describe('fudd', function() { ]); }); + it('should call the final callback with the error returned from creating the infrastructure', function() { + var expectedError = new Error('error creating infrastructure'); + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + it('should invoke Fudd._disconnect wtih the connection and callback', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, null); + expect(disconnectStub.args[0]).to.eql([ + 'connection', callbackSpy + ]); + }) }); }); From 3711a3d598145aa17e6cb18494cdaef57dddbed9 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 16:08:23 -0400 Subject: [PATCH 27/37] more integration --- test/integration/fudd.js | 79 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/test/integration/fudd.js b/test/integration/fudd.js index e48537f..a76fc99 100644 --- a/test/integration/fudd.js +++ b/test/integration/fudd.js @@ -3,19 +3,90 @@ var expect = require('chai').expect; var fudd = require('../../index.js'); var config = require('config'); +var series = require('palinode').series; describe('fudd integration test', function() { this.timeout(5000); - before('setup', function(done) { + var verificationChannel; + var verificationConnection; + var messageCounter = 0; + + it('should setup the infrastructure without error', function(done) { fudd.setup(config, done); }); - it('should do stuff', function(done) { - setTimeout(done, 4000); + config.exchanges.forEach(function(exchangeDefinition){ + it('should verify the exchange ' + exchangeDefinition.name + ' exists', function(done){ + var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; + series(establishChannel, function(err, connection, channel){ + if(err) return done(err); + + channel.checkExchange(exchangeDefinition.name, function(err){ + if(err) return done(err); + + fudd._disconnect(connection, done); + }); + + + }) + }) + }); + + config.queues.forEach(function(queueDefinition){ + it('should verify the queue ' + queueDefinition.name + ' exists', function(done){ + var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; + series(establishChannel, function(err, connection, channel){ + if(err) return done(err); + + channel.checkQueue(queueDefinition.name, function(err){ + if(err) return done(err); + + fudd._disconnect(connection, done); + }); + }) + }) + }); + + it('should establish channel for messages', function(done){ + var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; + series(establishChannel, function(err, connection, channel) { + if (err) return done(err); + + verificationChannel = channel; + verificationConnection = connection; + + done(); + }); + }); + + // specific tests + it('should publish messages to the fanout', function(){ + verificationChannel.publish('fanout.fx', 'some.key', new Buffer('message1')); + verificationChannel.publish('fanout.fx', 'key.topic1', new Buffer('message1')); + verificationChannel.publish('fanout.fx', 'key.topic2', new Buffer('message1')); + }); + + config.queues.forEach(function(queueDefinition){ + it('should purge the ' + queueDefinition.name + ' queue', function(done){ + verificationChannel.purgeQueue(queueDefinition.name, function(err, ok){ + messageCounter += ok.messageCount; + done(); + }) + }); + }); + + it('should have come across corret number of messages', function(){ + // msg - route + // 1 - fanout to queue1 + // 2 - fanout to queue1 + // 3 - fanout to queue1 + // 2 - fanout to topic to queue2 + // 3 - fanout to topic to queue2 + expect(messageCounter).to.equal(5); }); - after('teardown', function(done) { + it('should teardown the infrastructure without error', function(done) { fudd.teardown(config, done); }); }); From 3dea2e29ee5b2150cda43b94f723c416f3284378 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 16:08:44 -0400 Subject: [PATCH 28/37] lint --- test/integration/fudd.js | 47 ++++++++++++++++++++-------------------- test/unit/fudd.js | 4 ++-- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/test/integration/fudd.js b/test/integration/fudd.js index a76fc99..ab7e146 100644 --- a/test/integration/fudd.js +++ b/test/integration/fudd.js @@ -16,39 +16,38 @@ describe('fudd integration test', function() { fudd.setup(config, done); }); - config.exchanges.forEach(function(exchangeDefinition){ - it('should verify the exchange ' + exchangeDefinition.name + ' exists', function(done){ + config.exchanges.forEach(function(exchangeDefinition) { + it('should verify the exchange ' + exchangeDefinition.name + ' exists', function(done) { var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; - series(establishChannel, function(err, connection, channel){ - if(err) return done(err); + series(establishChannel, function(err, connection, channel) { + if (err) return done(err); - channel.checkExchange(exchangeDefinition.name, function(err){ - if(err) return done(err); + channel.checkExchange(exchangeDefinition.name, function(err) { + if (err) return done(err); fudd._disconnect(connection, done); }); - - }) - }) + }); + }); }); - config.queues.forEach(function(queueDefinition){ - it('should verify the queue ' + queueDefinition.name + ' exists', function(done){ + config.queues.forEach(function(queueDefinition) { + it('should verify the queue ' + queueDefinition.name + ' exists', function(done) { var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; - series(establishChannel, function(err, connection, channel){ - if(err) return done(err); + series(establishChannel, function(err, connection, channel) { + if (err) return done(err); - channel.checkQueue(queueDefinition.name, function(err){ - if(err) return done(err); + channel.checkQueue(queueDefinition.name, function(err) { + if (err) return done(err); fudd._disconnect(connection, done); }); - }) - }) + }); + }); }); - it('should establish channel for messages', function(done){ + it('should establish channel for messages', function(done) { var establishChannel = [fudd._connect.bind(null, config), fudd._createChannel]; series(establishChannel, function(err, connection, channel) { if (err) return done(err); @@ -61,22 +60,22 @@ describe('fudd integration test', function() { }); // specific tests - it('should publish messages to the fanout', function(){ + it('should publish messages to the fanout', function() { verificationChannel.publish('fanout.fx', 'some.key', new Buffer('message1')); verificationChannel.publish('fanout.fx', 'key.topic1', new Buffer('message1')); verificationChannel.publish('fanout.fx', 'key.topic2', new Buffer('message1')); }); - config.queues.forEach(function(queueDefinition){ - it('should purge the ' + queueDefinition.name + ' queue', function(done){ - verificationChannel.purgeQueue(queueDefinition.name, function(err, ok){ + config.queues.forEach(function(queueDefinition) { + it('should purge the ' + queueDefinition.name + ' queue', function(done) { + verificationChannel.purgeQueue(queueDefinition.name, function(err, ok) { messageCounter += ok.messageCount; done(); - }) + }); }); }); - it('should have come across corret number of messages', function(){ + it('should have come across corret number of messages', function() { // msg - route // 1 - fanout to queue1 // 2 - fanout to queue1 diff --git a/test/unit/fudd.js b/test/unit/fudd.js index e6685cd..2411d11 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -62,7 +62,7 @@ describe('fudd', function() { mockery.registerMock('./amqp-config-utils.js', {}); Fudd = require('../../lib/fudd.js'); }); - + before('setup stubs', function() { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); @@ -144,6 +144,6 @@ describe('fudd', function() { expect(disconnectStub.args[0]).to.eql([ 'connection', callbackSpy ]); - }) + }); }); }); From 6d77b27a922516cbe45f5945370199c188537cd7 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 16:18:52 -0400 Subject: [PATCH 29/37] begin teardown tests --- lib/fudd.js | 4 ++ test/unit/fudd.js | 162 ++++++++++++++++++++++++++++------------------ 2 files changed, 103 insertions(+), 63 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 7ac631d..dee0659 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -38,6 +38,10 @@ var Fudd = { var establishChannel = [Fudd._connect.bind(null, config), Fudd._createChannel]; series(establishChannel, function(error, connection, channel) { + if(error) return finalCallback(error); + var teardownMethods = []; + //config.exchanges + mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { if (err) return finalCallback(err); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index e6685cd..2050a34 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -34,26 +34,20 @@ describe('fudd', function() { before('enable mockery', function() { mockery.enable({useCleanCache: true}); - mockery.registerAllowable('../../lib/fudd.js'); }); after('disable mockery', mockery.disable); - describe('setup', function() { + describe('setup and teardown', function() { var callbackSpy; var connectBindStub; var disconnectStub; - var createExchangeBindStub; - var createQueueBindStub; - var createBindingsBindStub; var boundConnect = function connectBindResult() {}; - var boundCreateExchange = function createExchangeBindResult() {}; - var boundCreateQueue = function createQueueBindResult() {}; - var boundCreateBindings = function createBindingsBindResult() {}; before('setup mocks', function() { mockery.deregisterAll(); mockery.resetCache(); + mockery.registerAllowable('../../lib/fudd.js'); mockery.registerMock('amqplib/callback_api', {}); mockery.registerMock('palinode', { series: seriesStub = sinon.stub(), @@ -67,16 +61,10 @@ describe('fudd', function() { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); Fudd.__proto__._disconnect = disconnectStub = sinon.spy(); - createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); - createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); - createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); }); after('restore stubbed methods', function() { Fudd._connect.bind.restore(); - Fudd._createExchange.bind.restore(); - Fudd._createQueue.bind.restore(); - Fudd._createBindings.bind.restore(); }); beforeEach('reset stubs', function() { @@ -85,65 +73,113 @@ describe('fudd', function() { disconnectStub.reset(); seriesStub.reset(); mapEachStub.reset(); - createExchangeBindStub.reset(); - createQueueBindStub.reset(); - createBindingsBindStub.reset(); - Fudd.setup(config, callbackSpy); }); - it('should bind config to the _connect function', function() { - expect(connectBindStub.args[0]).to.eql([ - null, config - ]); - }); + describe('setup', function() { + var createExchangeBindStub; + var createQueueBindStub; + var createBindingsBindStub; + var boundCreateExchange = function createExchangeBindResult() {}; + var boundCreateQueue = function createQueueBindResult() {}; + var boundCreateBindings = function createBindingsBindResult() {}; + + before('setup stubs', function() { + createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); + createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); + createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); + }); - it('should invoke series with the bound _connect and Fudd._create channel functions', function() { - expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); - }); + after('restore stubs', function() { + Fudd._createExchange.bind.restore(); + Fudd._createQueue.bind.restore(); + Fudd._createBindings.bind.restore(); + }); - it('should call the finalCallback if the first series call calls back with an error', function() { - var expectedError = new Error('things happened'); - seriesStub.callArgWith(1, expectedError); - expect(callbackSpy.args[0]).to.eql([expectedError]); - }); + beforeEach('reset stubs & invoke', function() { + createExchangeBindStub.reset(); + createQueueBindStub.reset(); + createBindingsBindStub.reset(); + Fudd.setup(config, callbackSpy); + }); - it('should call _createExchange.bind for each exchange in the config', function() { - seriesStub.callArgWith(1, null, 'connection', 'channel'); - expect(createExchangeBindStub.callCount).to.equal(config.exchanges.length); - }); + it('should bind config to the _connect function', function() { + expect(connectBindStub.args[0]).to.eql([ + null, config + ]); + }); - it('should call _createExchange.bind for each queue in the config', function() { - seriesStub.callArgWith(1, null, 'connection', 'channel'); - expect(createQueueBindStub.callCount).to.equal(config.queues.length); - }); + it('should invoke series with the bound _connect and Fudd._create channel functions', function() { + expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); + }); - it('should call _createExchange.bind for each binding in the config', function() { - seriesStub.callArgWith(1, null, 'connection', 'channel'); - expect(createBindingsBindStub.callCount).to.equal(config.bindings.length); - }); + it('should call the finalCallback if the first series call calls back with an error', function() { + var expectedError = new Error('things happened'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); - it('should invoke series again with a sequence of functions derived from the config', function() { - seriesStub.callArgWith(1, null, 'connection', 'channel'); - expect(seriesStub.args[1][0]).to.eql([ - boundCreateExchange, - boundCreateQueue, - boundCreateBindings - ]); - }); + it('should call _createExchange.bind for each exchange in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createExchangeBindStub.callCount).to.equal(config.exchanges.length); + }); + + it('should call _createExchange.bind for each queue in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createQueueBindStub.callCount).to.equal(config.queues.length); + }); - it('should call the final callback with the error returned from creating the infrastructure', function() { - var expectedError = new Error('error creating infrastructure'); - seriesStub.callArgWith(1, null, 'connection', 'channel'); - seriesStub.callArgWith(1, expectedError); - expect(callbackSpy.args[0]).to.eql([expectedError]); + it('should call _createExchange.bind for each binding in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(createBindingsBindStub.callCount).to.equal(config.bindings.length); + }); + + it('should invoke series again with a sequence of functions derived from the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(seriesStub.args[1][0]).to.eql([ + boundCreateExchange, + boundCreateQueue, + boundCreateBindings + ]); + }); + + it('should call the final callback with the error returned from creating the infrastructure', function() { + var expectedError = new Error('error creating infrastructure'); + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + + it('should invoke Fudd._disconnect wtih the connection and callback', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, null); + expect(disconnectStub.args[0]).to.eql([ + 'connection', callbackSpy + ]); + }); }); - it('should invoke Fudd._disconnect wtih the connection and callback', function() { - seriesStub.callArgWith(1, null, 'connection', 'channel'); - seriesStub.callArgWith(1, null); - expect(disconnectStub.args[0]).to.eql([ - 'connection', callbackSpy - ]); - }) + describe('teardown', function() { + var deleteExchangeBindStub; + var deleteQueueBindStub; + var boundDeleteExchange = function deleteExchangeBindResult() {}; + var boundDeleteQueue = function deleteQueueBindResult() {}; + + before('setup stubs', function() { + deleteExchangeBindStub = sinon.stub(Fudd._deleteExchange, 'bind').returns(boundDeleteExchange); + deleteQueueBindStub = sinon.stub(Fudd._deleteQueue, 'bind').returns(boundDeleteQueue); + }); + + after('restore stubs', function() { + Fudd._deleteExchange.bind.restore(); + Fudd._deleteQueue.bind.restore(); + }); + + beforeEach('reset stubs & invoke', function() { + deleteExchangeBindStub.reset(); + deleteQueueBindStub.reset(); + Fudd.teardown(config, callbackSpy); + }); + + }); }); }); From 87bab26e882aae9aff7fe26266fdfd025a772e03 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 16:38:14 -0400 Subject: [PATCH 30/37] teardown tests completed --- lib/fudd.js | 23 ++++++++++++---------- test/unit/fudd.js | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 10 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index dee0659..d5a0e0b 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -39,17 +39,20 @@ var Fudd = { series(establishChannel, function(error, connection, channel) { if(error) return finalCallback(error); - var teardownMethods = []; - //config.exchanges + var infrastructure = []; - mapEach(config.exchanges, Fudd._deleteExchange.bind(null, channel), function(err) { - if (err) return finalCallback(err); + config.exchanges.reduce(function(series, exchangeDefinition) { + infrastructure.push(Fudd._deleteExchange.bind(null, channel, exchangeDefinition)); + }, infrastructure); - mapEach(config.queues, Fudd._deleteQueue.bind(null, channel), function(err) { - if (err) return finalCallback(err); + config.queues.reduce(function(series, queueDefinition) { + series.push(Fudd._deleteQueue.bind(null, channel, queueDefinition)); + return series; + }, infrastructure); - finalCallback(); - }); + series(infrastructure, function(error) { + if (error) return finalCallback(error); + Fudd._disconnect(connection, finalCallback); }); }); }, @@ -77,10 +80,10 @@ var Fudd = { } }, _deleteExchange: function(channel, exchangeDefinition, callback) { - channel.deleteExchange(exchangeDefinition.name, {}, callback); + channel.deleteExchange(exchangeDefinition.name, {}, function(error) { callback(error)}); }, _deleteQueue: function(channel, queueDefinition, callback) { - channel.deleteQueue(queueDefinition.name, {}, callback); + channel.deleteQueue(queueDefinition.name, {}, function(error) { callback(error)}); }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 5c598bc..ab3bb05 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -179,6 +179,55 @@ describe('fudd', function() { deleteQueueBindStub.reset(); Fudd.teardown(config, callbackSpy); }); + + it('should bind config to the _connect function', function() { + expect(connectBindStub.args[0]).to.eql([ + null, config + ]); + }); + + it('should invoke series with the bound _connect and Fudd._create channel functions', function() { + expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); + }); + + it('should call the finalCallback if the first series call calls back with an error', function() { + var expectedError = new Error('things happened'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + + it('should call _deleteExchange.bind for each exchange in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(deleteExchangeBindStub.callCount).to.equal(config.exchanges.length); + }); + + it('should call _deleteExchange.bind for each queue in the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(deleteQueueBindStub.callCount).to.equal(config.queues.length); + }); + + it('should invoke series again with a sequence of functions derived from the config', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + expect(seriesStub.args[1][0]).to.eql([ + boundDeleteExchange, + boundDeleteQueue + ]); + }); + + it('should call the final callback with the error returned from creating the infrastructure', function() { + var expectedError = new Error('error creating infrastructure'); + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + + it('should invoke Fudd._disconnect wtih the connection and callback', function() { + seriesStub.callArgWith(1, null, 'connection', 'channel'); + seriesStub.callArgWith(1, null); + expect(disconnectStub.args[0]).to.eql([ + 'connection', callbackSpy + ]); + }); }); }); }); From 30f33e72766074decee71906656b4573807c6757 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 16:41:51 -0400 Subject: [PATCH 31/37] fixed lint --- lib/fudd.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index d5a0e0b..7a8b360 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -38,7 +38,7 @@ var Fudd = { var establishChannel = [Fudd._connect.bind(null, config), Fudd._createChannel]; series(establishChannel, function(error, connection, channel) { - if(error) return finalCallback(error); + if (error) return finalCallback(error); var infrastructure = []; config.exchanges.reduce(function(series, exchangeDefinition) { @@ -80,10 +80,10 @@ var Fudd = { } }, _deleteExchange: function(channel, exchangeDefinition, callback) { - channel.deleteExchange(exchangeDefinition.name, {}, function(error) { callback(error)}); + channel.deleteExchange(exchangeDefinition.name, {}, function(error) { callback(error);}); }, _deleteQueue: function(channel, queueDefinition, callback) { - channel.deleteQueue(queueDefinition.name, {}, function(error) { callback(error)}); + channel.deleteQueue(queueDefinition.name, {}, function(error) { callback(error);}); }, _connect: function(config, callback) { var url = formatAmqpUrl(config.cluster); From 58f3ec2c13d685cd892207a97f57581042a2bd56 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 16:48:22 -0400 Subject: [PATCH 32/37] more tests --- lib/fudd.js | 9 ++-- test/unit/fudd.js | 104 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 4 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index d5a0e0b..a77b056 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -57,13 +57,13 @@ var Fudd = { }); }, _createExchange: function(channel, exchangeDefinition, callback) { - channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(error) { - callback(error); + channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(err){ + callback(err); }); }, _createQueue: function(channel, queueDefinition, callback) { - channel.assertQueue(queueDefinition.name, queueDefinition.options, function(error) { - callback(error); + channel.assertQueue(queueDefinition.name, queueDefinition.options, function(err){ + callback(err); }); }, _createBindings: function(channel, bindingDefinition, callback) { @@ -91,6 +91,7 @@ var Fudd = { }, _createChannel: function(connection, callback) { connection.createChannel(function(error, channel) { + console.log(error); if (error) return callback(error); callback(null, connection, channel); }); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index ab3bb05..20351ba 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -229,5 +229,109 @@ describe('fudd', function() { ]); }); }); + + describe('_createExchange', function() { + var assertExchangeStub; + var mockChannel; + var callbackStub; + var error; + var exchangeDefinition; + + beforeEach(function() { + mockChannel = {assertExchange: assertExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt:'ion'}}; + }); + + it('should call assertExchange with exchange definition & options', function() { + Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); + expect(assertExchangeStub.args[0]).to.eql([exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, callbackStub]); + }); + + it('should callback with error if assertExchange calls back with error', function() { + assertExchangeStub.callsArgWith(3, error); + Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_createQueue', function() { + var assertQueueStub; + var mockChannel; + var callbackStub; + var error; + var queueDefinition; + + beforeEach(function() { + mockChannel = {assertQueue: assertQueueStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); + + it('should call assertQueue with queue definition & options', function() { + Fudd._createQueue(mockChannel, queueDefinition, callbackStub); + expect(assertQueueStub.args[0]).to.eql([queueDefinition.name, queueDefinition.options, callbackStub]); + }); + + it('should callback with error if assertQueue calls back with error', function() { + assertQueueStub.callsArgWith(2, error); + Fudd._createQueue(mockChannel, queueDefinition, callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_deleteExchange', function() { + var deleteExchangeStub; + var mockChannel; + var callbackStub; + var error; + var exchangeDefinition; + + beforeEach(function() { + mockChannel = {deleteExchange: deleteExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + exchangeDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); + + it('should call deleteExchange with exchange name', function() { + Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); + expect(deleteExchangeStub.args[0]).to.eql([exchangeDefinition.name, {}, callbackStub]); + }); + + it('should callback with error if deleteExchange calls back with error', function() { + deleteExchangeStub.callsArgWith(2, error); + Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_deleteQueue', function() { + var deleteQueue; + var mockChannel; + var callbackStub; + var error; + var queueDefinition; + + beforeEach(function() { + mockChannel = {deleteQueue: deleteQueue = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); + + it('should call deleteQueue with queue name', function() { + Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); + expect(deleteQueue.args[0]).to.eql([queueDefinition.name, {}, callbackStub]); + }); + + it('should callback with error if deleteQueue calls back with error', function() { + deleteQueue.callsArgWith(2, error); + Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); }); }); From be0ded427ff0ae79fb5467dcda276d5c458d3045 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 16:49:15 -0400 Subject: [PATCH 33/37] corrected --- test/integration/fudd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/fudd.js b/test/integration/fudd.js index ab7e146..b32f99b 100644 --- a/test/integration/fudd.js +++ b/test/integration/fudd.js @@ -75,7 +75,7 @@ describe('fudd integration test', function() { }); }); - it('should have come across corret number of messages', function() { + it('should have come across correct number of messages', function() { // msg - route // 1 - fanout to queue1 // 2 - fanout to queue1 From da03374c784bb209f3cd6b0247a86609e52242f0 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 16:58:44 -0400 Subject: [PATCH 34/37] lint --- lib/fudd.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 5b43aba..8bd1b04 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -57,12 +57,12 @@ var Fudd = { }); }, _createExchange: function(channel, exchangeDefinition, callback) { - channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(err){ + channel.assertExchange(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, function(err) { callback(err); }); }, _createQueue: function(channel, queueDefinition, callback) { - channel.assertQueue(queueDefinition.name, queueDefinition.options, function(err){ + channel.assertQueue(queueDefinition.name, queueDefinition.options, function(err) { callback(err); }); }, From 3d606dd2e1ef3de8a82f3ff4b5606a76584c90f5 Mon Sep 17 00:00:00 2001 From: Devansh Dhutia Date: Mon, 20 Jun 2016 17:30:09 -0400 Subject: [PATCH 35/37] more tests --- lib/fudd.js | 6 +- test/unit/fudd.js | 282 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 200 insertions(+), 88 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 8bd1b04..9b4e8c1 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -75,8 +75,12 @@ var Fudd = { _createBinding: function(channel, bindingDefinition, bindingKey, callback) { if (bindingDefinition.bindingType === 'queue') { channel.bindQueue(bindingDefinition.to, bindingDefinition.from, bindingKey, bindingDefinition.options, callback); - } else { + + } else if (bindingDefinition.bindingType === 'exchange') { channel.bindExchange(bindingDefinition.to, bindingDefinition.from, bindingKey, bindingDefinition.options, callback); + + } else { + callback(new Error('unsupported binding type: ' + bindingDefinition.bindingType)); } }, _deleteExchange: function(channel, exchangeDefinition, callback) { diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 20351ba..7fa675d 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -229,108 +229,216 @@ describe('fudd', function() { ]); }); }); + }); - describe('_createExchange', function() { - var assertExchangeStub; - var mockChannel; - var callbackStub; - var error; - var exchangeDefinition; - - beforeEach(function() { - mockChannel = {assertExchange: assertExchangeStub = sinon.stub()}; - callbackStub = sinon.stub(); - error = new Error('something broke'); - exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt:'ion'}}; - }); + describe('_createExchange', function() { + var assertExchangeStub; + var mockChannel; + var callbackStub; + var error; + var exchangeDefinition; + + beforeEach(function() { + mockChannel = {assertExchange: assertExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt:'ion'}}; + }); - it('should call assertExchange with exchange definition & options', function() { - Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); - expect(assertExchangeStub.args[0]).to.eql([exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options, callbackStub]); - }); + it('should call assertExchange with exchange definition & options', function() { + Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); + expect(assertExchangeStub.calledWith(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options)).to.equal(true); + }); - it('should callback with error if assertExchange calls back with error', function() { - assertExchangeStub.callsArgWith(3, error); - Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); - expect(callbackStub.calledWith(error)); - }); + it('should callback with error if assertExchange calls back with error', function() { + assertExchangeStub.callsArgWith(3, error); + Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); + expect(callbackStub.calledWith(error)); }); + }); - describe('_createQueue', function() { - var assertQueueStub; - var mockChannel; - var callbackStub; - var error; - var queueDefinition; - - beforeEach(function() { - mockChannel = {assertQueue: assertQueueStub = sinon.stub()}; - callbackStub = sinon.stub(); - error = new Error('something broke'); - queueDefinition = {name: 'na.me', options: {opt:'ion'}}; - }); + describe('_createQueue', function() { + var assertQueueStub; + var mockChannel; + var callbackStub; + var error; + var queueDefinition; + + beforeEach(function() { + mockChannel = {assertQueue: assertQueueStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); - it('should call assertQueue with queue definition & options', function() { - Fudd._createQueue(mockChannel, queueDefinition, callbackStub); - expect(assertQueueStub.args[0]).to.eql([queueDefinition.name, queueDefinition.options, callbackStub]); - }); + it('should call assertQueue with queue definition & options', function() { + Fudd._createQueue(mockChannel, queueDefinition, callbackStub); + expect(assertQueueStub.calledWith(queueDefinition.name, queueDefinition.options)).to.equal(true); + }); - it('should callback with error if assertQueue calls back with error', function() { - assertQueueStub.callsArgWith(2, error); - Fudd._createQueue(mockChannel, queueDefinition, callbackStub); - expect(callbackStub.calledWith(error)); - }); + it('should callback with error if assertQueue calls back with error', function() { + assertQueueStub.callsArgWith(2, error); + Fudd._createQueue(mockChannel, queueDefinition, callbackStub); + expect(callbackStub.calledWith(error)); }); + }); - describe('_deleteExchange', function() { - var deleteExchangeStub; - var mockChannel; - var callbackStub; - var error; - var exchangeDefinition; - - beforeEach(function() { - mockChannel = {deleteExchange: deleteExchangeStub = sinon.stub()}; - callbackStub = sinon.stub(); - error = new Error('something broke'); - exchangeDefinition = {name: 'na.me', options: {opt:'ion'}}; - }); + describe('_deleteExchange', function() { + var deleteExchangeStub; + var mockChannel; + var callbackStub; + var error; + var exchangeDefinition; + + beforeEach(function() { + mockChannel = {deleteExchange: deleteExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + exchangeDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); - it('should call deleteExchange with exchange name', function() { - Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); - expect(deleteExchangeStub.args[0]).to.eql([exchangeDefinition.name, {}, callbackStub]); - }); + it('should call deleteExchange with exchange name', function() { + Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); + expect(deleteExchangeStub.calledWith(exchangeDefinition.name, {})).to.equal(true); + }); - it('should callback with error if deleteExchange calls back with error', function() { - deleteExchangeStub.callsArgWith(2, error); - Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); - expect(callbackStub.calledWith(error)); - }); + it('should callback with error if deleteExchange calls back with error', function() { + deleteExchangeStub.callsArgWith(2, error); + Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); + expect(callbackStub.calledWith(error)); }); + }); - describe('_deleteQueue', function() { - var deleteQueue; - var mockChannel; - var callbackStub; - var error; - var queueDefinition; - - beforeEach(function() { - mockChannel = {deleteQueue: deleteQueue = sinon.stub()}; - callbackStub = sinon.stub(); - error = new Error('something broke'); - queueDefinition = {name: 'na.me', options: {opt:'ion'}}; - }); + describe('_deleteQueue', function() { + var deleteQueue; + var mockChannel; + var callbackStub; + var error; + var queueDefinition; + + beforeEach(function() { + mockChannel = {deleteQueue: deleteQueue = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + }); - it('should call deleteQueue with queue name', function() { - Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); - expect(deleteQueue.args[0]).to.eql([queueDefinition.name, {}, callbackStub]); - }); + it('should call deleteQueue with queue name', function() { + Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); + expect(deleteQueue.calledWith(queueDefinition.name, {})).to.equal(true); + }); + + it('should callback with error if deleteQueue calls back with error', function() { + deleteQueue.callsArgWith(2, error); + Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_createBindings', function() { + var createBindingBindStub; + var boundCreateBinding = function() {}; + var bindingDefinition; + var callbackSpy; + + before('setup stubs', function() { + createBindingBindStub = sinon.stub(Fudd._createBinding, 'bind').returns(boundCreateBinding); + bindingDefinition = {bindingKeys:['#', '#.#'], bindingType: 'queue', to: 'x', from: 'y'}; + callbackSpy = sinon.spy(); + }); + + after('restore stubs', function() { + Fudd._createBinding.bind.restore(); + }); + + beforeEach('reset stubs & invoke', function() { + createBindingBindStub.reset(); + callbackSpy.reset(); + Fudd._createBindings({}, bindingDefinition, callbackSpy); + }); + + it('should call mapEach with all bindingKeys and a bound createBinding call', function() { + expect(mapEachStub.calledWith(bindingDefinition.bindingKeys, boundCreateBinding)).to.eql(true); + }); + + it('should callback with error if mapEach calls back with error', function() { + var error = new Error('boo'); + mapEachStub.callsArgWith(2, error); + Fudd._createBindings({}, bindingDefinition, callbackSpy); + expect(callbackSpy.calledWith(error)).to.eql(true); + }); + }); + + describe('_createBinding (queue)', function() { + var bindQueueStub; + var mockChannel; + var callbackStub; + var error; + var bindingDefinition; + + beforeEach(function() { + mockChannel = {bindQueue: bindQueueStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'queue'}; + }); + + it('should call bindQueue with queue name & source exchange', function() { + Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); + expect(bindQueueStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); + }); + + it('should callback with error if bindQueue calls back with error', function() { + bindQueueStub.callsArgWith(4, error); + Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_createBinding (exchange)', function() { + var bindExchangeStub; + var mockChannel; + var callbackStub; + var error; + var bindingDefinition; + + beforeEach(function() { + mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exchange'}; + }); + + it('should call bindExchange with exchange name & source exchange', function() { + Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); + expect(bindExchangeStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); + }); + + it('should callback with error if bindExchange calls back with error', function() { + bindExchangeStub.callsArgWith(4, error); + Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); + expect(callbackStub.calledWith(error)); + }); + }); + + describe('_createBinding (unsupported)', function() { + var bindExchangeStub; + var mockChannel; + var callbackStub; + var error; + var bindingDefinition; + + beforeEach(function() { + mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; + callbackStub = sinon.stub(); + error = new Error('something broke'); + bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exhcabge'}; + }); - it('should callback with error if deleteQueue calls back with error', function() { - deleteQueue.callsArgWith(2, error); - Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); - expect(callbackStub.calledWith(error)); + it('should callback with error if bindExchange calls back with error', function() { + var message = 'unsupported binding type: ' + bindingDefinition.bindingType; + Fudd._createBinding(mockChannel, bindingDefinition, '#', function(err) { + expect(err.message).to.equal(message); }); }); }); From e00924bfcd79417075b9ed0504f2abd7feca9462 Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 17:50:44 -0400 Subject: [PATCH 36/37] final unit tests --- lib/fudd.js | 1 - test/unit/fudd.js | 211 +++++++++++++++++++++++++++++----------------- 2 files changed, 133 insertions(+), 79 deletions(-) diff --git a/lib/fudd.js b/lib/fudd.js index 9b4e8c1..25c9217 100644 --- a/lib/fudd.js +++ b/lib/fudd.js @@ -95,7 +95,6 @@ var Fudd = { }, _createChannel: function(connection, callback) { connection.createChannel(function(error, channel) { - console.log(error); if (error) return callback(error); callback(null, connection, channel); }); diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 7fa675d..6966a22 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -32,19 +32,20 @@ describe('fudd', function() { var mapEachStub; var seriesStub; - before('enable mockery', function() { + before('enable mockery', function () { mockery.enable({useCleanCache: true}); }); after('disable mockery', mockery.disable); - describe('setup and teardown', function() { + describe('setup and teardown', function () { var callbackSpy; var connectBindStub; var disconnectStub; - var boundConnect = function connectBindResult() {}; + var boundConnect = function connectBindResult() { + }; - before('setup mocks', function() { + before('setup mocks', function () { mockery.deregisterAll(); mockery.resetCache(); mockery.registerAllowable('../../lib/fudd.js'); @@ -57,17 +58,17 @@ describe('fudd', function() { Fudd = require('../../lib/fudd.js'); }); - before('setup stubs', function() { + before('setup stubs', function () { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); Fudd.__proto__._disconnect = disconnectStub = sinon.spy(); }); - after('restore stubbed methods', function() { + after('restore stubbed methods', function () { Fudd._connect.bind.restore(); }); - beforeEach('reset stubs', function() { + beforeEach('reset stubs', function () { callbackSpy.reset(); connectBindStub.reset(); disconnectStub.reset(); @@ -75,65 +76,68 @@ describe('fudd', function() { mapEachStub.reset(); }); - describe('setup', function() { + describe('setup', function () { var createExchangeBindStub; var createQueueBindStub; var createBindingsBindStub; - var boundCreateExchange = function createExchangeBindResult() {}; - var boundCreateQueue = function createQueueBindResult() {}; - var boundCreateBindings = function createBindingsBindResult() {}; - - before('setup stubs', function() { + var boundCreateExchange = function createExchangeBindResult() { + }; + var boundCreateQueue = function createQueueBindResult() { + }; + var boundCreateBindings = function createBindingsBindResult() { + }; + + before('setup stubs', function () { createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); }); - after('restore stubs', function() { + after('restore stubs', function () { Fudd._createExchange.bind.restore(); Fudd._createQueue.bind.restore(); Fudd._createBindings.bind.restore(); }); - beforeEach('reset stubs & invoke', function() { + beforeEach('reset stubs & invoke', function () { createExchangeBindStub.reset(); createQueueBindStub.reset(); createBindingsBindStub.reset(); Fudd.setup(config, callbackSpy); }); - it('should bind config to the _connect function', function() { + it('should bind config to the _connect function', function () { expect(connectBindStub.args[0]).to.eql([ null, config ]); }); - it('should invoke series with the bound _connect and Fudd._create channel functions', function() { + it('should invoke series with the bound _connect and Fudd._create channel functions', function () { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - it('should call the finalCallback if the first series call calls back with an error', function() { + it('should call the finalCallback if the first series call calls back with an error', function () { var expectedError = new Error('things happened'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should call _createExchange.bind for each exchange in the config', function() { + it('should call _createExchange.bind for each exchange in the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createExchangeBindStub.callCount).to.equal(config.exchanges.length); }); - it('should call _createExchange.bind for each queue in the config', function() { + it('should call _createExchange.bind for each queue in the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createQueueBindStub.callCount).to.equal(config.queues.length); }); - it('should call _createExchange.bind for each binding in the config', function() { + it('should call _createExchange.bind for each binding in the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createBindingsBindStub.callCount).to.equal(config.bindings.length); }); - it('should invoke series again with a sequence of functions derived from the config', function() { + it('should invoke series again with a sequence of functions derived from the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(seriesStub.args[1][0]).to.eql([ boundCreateExchange, @@ -142,14 +146,14 @@ describe('fudd', function() { ]); }); - it('should call the final callback with the error returned from creating the infrastructure', function() { + it('should call the final callback with the error returned from creating the infrastructure', function () { var expectedError = new Error('error creating infrastructure'); seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should invoke Fudd._disconnect wtih the connection and callback', function() { + it('should invoke Fudd._disconnect wtih the connection and callback', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, null); expect(disconnectStub.args[0]).to.eql([ @@ -158,55 +162,57 @@ describe('fudd', function() { }); }); - describe('teardown', function() { + describe('teardown', function () { var deleteExchangeBindStub; var deleteQueueBindStub; - var boundDeleteExchange = function deleteExchangeBindResult() {}; - var boundDeleteQueue = function deleteQueueBindResult() {}; + var boundDeleteExchange = function deleteExchangeBindResult() { + }; + var boundDeleteQueue = function deleteQueueBindResult() { + }; - before('setup stubs', function() { + before('setup stubs', function () { deleteExchangeBindStub = sinon.stub(Fudd._deleteExchange, 'bind').returns(boundDeleteExchange); deleteQueueBindStub = sinon.stub(Fudd._deleteQueue, 'bind').returns(boundDeleteQueue); }); - after('restore stubs', function() { + after('restore stubs', function () { Fudd._deleteExchange.bind.restore(); Fudd._deleteQueue.bind.restore(); }); - beforeEach('reset stubs & invoke', function() { + beforeEach('reset stubs & invoke', function () { deleteExchangeBindStub.reset(); deleteQueueBindStub.reset(); Fudd.teardown(config, callbackSpy); }); - it('should bind config to the _connect function', function() { + it('should bind config to the _connect function', function () { expect(connectBindStub.args[0]).to.eql([ null, config ]); }); - it('should invoke series with the bound _connect and Fudd._create channel functions', function() { + it('should invoke series with the bound _connect and Fudd._create channel functions', function () { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - it('should call the finalCallback if the first series call calls back with an error', function() { + it('should call the finalCallback if the first series call calls back with an error', function () { var expectedError = new Error('things happened'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should call _deleteExchange.bind for each exchange in the config', function() { + it('should call _deleteExchange.bind for each exchange in the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(deleteExchangeBindStub.callCount).to.equal(config.exchanges.length); }); - it('should call _deleteExchange.bind for each queue in the config', function() { + it('should call _deleteExchange.bind for each queue in the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(deleteQueueBindStub.callCount).to.equal(config.queues.length); }); - it('should invoke series again with a sequence of functions derived from the config', function() { + it('should invoke series again with a sequence of functions derived from the config', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(seriesStub.args[1][0]).to.eql([ boundDeleteExchange, @@ -214,14 +220,14 @@ describe('fudd', function() { ]); }); - it('should call the final callback with the error returned from creating the infrastructure', function() { + it('should call the final callback with the error returned from creating the infrastructure', function () { var expectedError = new Error('error creating infrastructure'); seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should invoke Fudd._disconnect wtih the connection and callback', function() { + it('should invoke Fudd._disconnect wtih the connection and callback', function () { seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, null); expect(disconnectStub.args[0]).to.eql([ @@ -231,137 +237,138 @@ describe('fudd', function() { }); }); - describe('_createExchange', function() { + describe('_createExchange', function () { var assertExchangeStub; var mockChannel; var callbackStub; var error; var exchangeDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {assertExchange: assertExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); - exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt:'ion'}}; + exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt: 'ion'}}; }); - it('should call assertExchange with exchange definition & options', function() { + it('should call assertExchange with exchange definition & options', function () { Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); expect(assertExchangeStub.calledWith(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options)).to.equal(true); }); - it('should callback with error if assertExchange calls back with error', function() { + it('should callback with error if assertExchange calls back with error', function () { assertExchangeStub.callsArgWith(3, error); Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createQueue', function() { + describe('_createQueue', function () { var assertQueueStub; var mockChannel; var callbackStub; var error; var queueDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {assertQueue: assertQueueStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); - queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + queueDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call assertQueue with queue definition & options', function() { + it('should call assertQueue with queue definition & options', function () { Fudd._createQueue(mockChannel, queueDefinition, callbackStub); expect(assertQueueStub.calledWith(queueDefinition.name, queueDefinition.options)).to.equal(true); }); - it('should callback with error if assertQueue calls back with error', function() { + it('should callback with error if assertQueue calls back with error', function () { assertQueueStub.callsArgWith(2, error); Fudd._createQueue(mockChannel, queueDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_deleteExchange', function() { + describe('_deleteExchange', function () { var deleteExchangeStub; var mockChannel; var callbackStub; var error; var exchangeDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {deleteExchange: deleteExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); - exchangeDefinition = {name: 'na.me', options: {opt:'ion'}}; + exchangeDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call deleteExchange with exchange name', function() { + it('should call deleteExchange with exchange name', function () { Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); expect(deleteExchangeStub.calledWith(exchangeDefinition.name, {})).to.equal(true); }); - it('should callback with error if deleteExchange calls back with error', function() { + it('should callback with error if deleteExchange calls back with error', function () { deleteExchangeStub.callsArgWith(2, error); Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_deleteQueue', function() { + describe('_deleteQueue', function () { var deleteQueue; var mockChannel; var callbackStub; var error; var queueDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {deleteQueue: deleteQueue = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); - queueDefinition = {name: 'na.me', options: {opt:'ion'}}; + queueDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call deleteQueue with queue name', function() { + it('should call deleteQueue with queue name', function () { Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); expect(deleteQueue.calledWith(queueDefinition.name, {})).to.equal(true); }); - it('should callback with error if deleteQueue calls back with error', function() { + it('should callback with error if deleteQueue calls back with error', function () { deleteQueue.callsArgWith(2, error); Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBindings', function() { + describe('_createBindings', function () { var createBindingBindStub; - var boundCreateBinding = function() {}; + var boundCreateBinding = function () { + }; var bindingDefinition; var callbackSpy; - before('setup stubs', function() { + before('setup stubs', function () { createBindingBindStub = sinon.stub(Fudd._createBinding, 'bind').returns(boundCreateBinding); - bindingDefinition = {bindingKeys:['#', '#.#'], bindingType: 'queue', to: 'x', from: 'y'}; + bindingDefinition = {bindingKeys: ['#', '#.#'], bindingType: 'queue', to: 'x', from: 'y'}; callbackSpy = sinon.spy(); }); - after('restore stubs', function() { + after('restore stubs', function () { Fudd._createBinding.bind.restore(); }); - beforeEach('reset stubs & invoke', function() { + beforeEach('reset stubs & invoke', function () { createBindingBindStub.reset(); callbackSpy.reset(); Fudd._createBindings({}, bindingDefinition, callbackSpy); }); - it('should call mapEach with all bindingKeys and a bound createBinding call', function() { + it('should call mapEach with all bindingKeys and a bound createBinding call', function () { expect(mapEachStub.calledWith(bindingDefinition.bindingKeys, boundCreateBinding)).to.eql(true); }); - it('should callback with error if mapEach calls back with error', function() { + it('should callback with error if mapEach calls back with error', function () { var error = new Error('boo'); mapEachStub.callsArgWith(2, error); Fudd._createBindings({}, bindingDefinition, callbackSpy); @@ -369,77 +376,125 @@ describe('fudd', function() { }); }); - describe('_createBinding (queue)', function() { + describe('_createBinding (queue)', function () { var bindQueueStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {bindQueue: bindQueueStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'queue'}; }); - it('should call bindQueue with queue name & source exchange', function() { + it('should call bindQueue with queue name & source exchange', function () { Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(bindQueueStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); }); - it('should callback with error if bindQueue calls back with error', function() { + it('should callback with error if bindQueue calls back with error', function () { bindQueueStub.callsArgWith(4, error); Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBinding (exchange)', function() { + describe('_createBinding (exchange)', function () { var bindExchangeStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exchange'}; }); - it('should call bindExchange with exchange name & source exchange', function() { + it('should call bindExchange with exchange name & source exchange', function () { Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(bindExchangeStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); }); - it('should callback with error if bindExchange calls back with error', function() { + it('should callback with error if bindExchange calls back with error', function () { bindExchangeStub.callsArgWith(4, error); Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBinding (unsupported)', function() { + describe('_createBinding (unsupported)', function () { var bindExchangeStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function() { + beforeEach(function () { mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exhcabge'}; }); - it('should callback with error if bindExchange calls back with error', function() { + it('should callback with error if bindExchange calls back with error', function () { var message = 'unsupported binding type: ' + bindingDefinition.bindingType; - Fudd._createBinding(mockChannel, bindingDefinition, '#', function(err) { + Fudd._createBinding(mockChannel, bindingDefinition, '#', function (err) { expect(err.message).to.equal(message); }); }); }); + + + describe('_disconnect & createChannel', function () { + + before(function () { + mockery.resetCache(); + mockery.deregisterAll(); + mockery.registerAllowable('../../lib/fudd.js'); + mockery.registerMock('amqplib/callback_api', {}); + mockery.registerMock('palinode', {}); + mockery.registerMock('./amqp-config-utils.js', {}); + Fudd = require('../../lib/fudd.js'); + }); + + var callbackSpy = sinon.spy(); + var connection = { + close: sinon.spy(), + createChannel: sinon.stub() + }; + + beforeEach(function () { + connection.close.reset(); + connection.createChannel.reset(); + callbackSpy.reset(); + }); + + describe('_disconnect', function() { + it('should call close on the provided connection', function () { + Fudd._disconnect(connection, callbackSpy); + expect(connection.close.callCount).to.equal(1); + }); + }); + + describe('_createChannel', function() { + it('should call back with the error from createChannel', function () { + var expectedError = new Error('connection is borked'); + Fudd._createChannel(connection, callbackSpy); + connection.createChannel.callArgWith(0, expectedError); + expect(callbackSpy.args[0]).to.eql([expectedError]); + }); + + it('should call back with the originating connection and the channel from createChannel', function () { + Fudd._createChannel(connection, callbackSpy); + connection.createChannel.callArgWith(0, null, 'this is a fake channel'); + expect(callbackSpy.args[0]).to.eql([null, connection, 'this is a fake channel']); + }); + }); + }); }); From eb30307982412f5e63b442a942e4e11448b42e8d Mon Sep 17 00:00:00 2001 From: "jhaugh42@gmail.com" Date: Mon, 20 Jun 2016 17:53:03 -0400 Subject: [PATCH 37/37] lint again --- test/unit/fudd.js | 145 +++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 73 deletions(-) diff --git a/test/unit/fudd.js b/test/unit/fudd.js index 6966a22..84d2f4f 100644 --- a/test/unit/fudd.js +++ b/test/unit/fudd.js @@ -32,20 +32,20 @@ describe('fudd', function() { var mapEachStub; var seriesStub; - before('enable mockery', function () { + before('enable mockery', function() { mockery.enable({useCleanCache: true}); }); after('disable mockery', mockery.disable); - describe('setup and teardown', function () { + describe('setup and teardown', function() { var callbackSpy; var connectBindStub; var disconnectStub; var boundConnect = function connectBindResult() { }; - before('setup mocks', function () { + before('setup mocks', function() { mockery.deregisterAll(); mockery.resetCache(); mockery.registerAllowable('../../lib/fudd.js'); @@ -58,17 +58,17 @@ describe('fudd', function() { Fudd = require('../../lib/fudd.js'); }); - before('setup stubs', function () { + before('setup stubs', function() { callbackSpy = sinon.spy(); connectBindStub = sinon.stub(Fudd._connect, 'bind').returns(boundConnect); Fudd.__proto__._disconnect = disconnectStub = sinon.spy(); }); - after('restore stubbed methods', function () { + after('restore stubbed methods', function() { Fudd._connect.bind.restore(); }); - beforeEach('reset stubs', function () { + beforeEach('reset stubs', function() { callbackSpy.reset(); connectBindStub.reset(); disconnectStub.reset(); @@ -76,7 +76,7 @@ describe('fudd', function() { mapEachStub.reset(); }); - describe('setup', function () { + describe('setup', function() { var createExchangeBindStub; var createQueueBindStub; var createBindingsBindStub; @@ -87,57 +87,57 @@ describe('fudd', function() { var boundCreateBindings = function createBindingsBindResult() { }; - before('setup stubs', function () { + before('setup stubs', function() { createExchangeBindStub = sinon.stub(Fudd._createExchange, 'bind').returns(boundCreateExchange); createQueueBindStub = sinon.stub(Fudd._createQueue, 'bind').returns(boundCreateQueue); createBindingsBindStub = sinon.stub(Fudd._createBindings, 'bind').returns(boundCreateBindings); }); - after('restore stubs', function () { + after('restore stubs', function() { Fudd._createExchange.bind.restore(); Fudd._createQueue.bind.restore(); Fudd._createBindings.bind.restore(); }); - beforeEach('reset stubs & invoke', function () { + beforeEach('reset stubs & invoke', function() { createExchangeBindStub.reset(); createQueueBindStub.reset(); createBindingsBindStub.reset(); Fudd.setup(config, callbackSpy); }); - it('should bind config to the _connect function', function () { + it('should bind config to the _connect function', function() { expect(connectBindStub.args[0]).to.eql([ null, config ]); }); - it('should invoke series with the bound _connect and Fudd._create channel functions', function () { + it('should invoke series with the bound _connect and Fudd._create channel functions', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - it('should call the finalCallback if the first series call calls back with an error', function () { + it('should call the finalCallback if the first series call calls back with an error', function() { var expectedError = new Error('things happened'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should call _createExchange.bind for each exchange in the config', function () { + it('should call _createExchange.bind for each exchange in the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createExchangeBindStub.callCount).to.equal(config.exchanges.length); }); - it('should call _createExchange.bind for each queue in the config', function () { + it('should call _createExchange.bind for each queue in the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createQueueBindStub.callCount).to.equal(config.queues.length); }); - it('should call _createExchange.bind for each binding in the config', function () { + it('should call _createExchange.bind for each binding in the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(createBindingsBindStub.callCount).to.equal(config.bindings.length); }); - it('should invoke series again with a sequence of functions derived from the config', function () { + it('should invoke series again with a sequence of functions derived from the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(seriesStub.args[1][0]).to.eql([ boundCreateExchange, @@ -146,14 +146,14 @@ describe('fudd', function() { ]); }); - it('should call the final callback with the error returned from creating the infrastructure', function () { + it('should call the final callback with the error returned from creating the infrastructure', function() { var expectedError = new Error('error creating infrastructure'); seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should invoke Fudd._disconnect wtih the connection and callback', function () { + it('should invoke Fudd._disconnect wtih the connection and callback', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, null); expect(disconnectStub.args[0]).to.eql([ @@ -162,7 +162,7 @@ describe('fudd', function() { }); }); - describe('teardown', function () { + describe('teardown', function() { var deleteExchangeBindStub; var deleteQueueBindStub; var boundDeleteExchange = function deleteExchangeBindResult() { @@ -170,49 +170,49 @@ describe('fudd', function() { var boundDeleteQueue = function deleteQueueBindResult() { }; - before('setup stubs', function () { + before('setup stubs', function() { deleteExchangeBindStub = sinon.stub(Fudd._deleteExchange, 'bind').returns(boundDeleteExchange); deleteQueueBindStub = sinon.stub(Fudd._deleteQueue, 'bind').returns(boundDeleteQueue); }); - after('restore stubs', function () { + after('restore stubs', function() { Fudd._deleteExchange.bind.restore(); Fudd._deleteQueue.bind.restore(); }); - beforeEach('reset stubs & invoke', function () { + beforeEach('reset stubs & invoke', function() { deleteExchangeBindStub.reset(); deleteQueueBindStub.reset(); Fudd.teardown(config, callbackSpy); }); - it('should bind config to the _connect function', function () { + it('should bind config to the _connect function', function() { expect(connectBindStub.args[0]).to.eql([ null, config ]); }); - it('should invoke series with the bound _connect and Fudd._create channel functions', function () { + it('should invoke series with the bound _connect and Fudd._create channel functions', function() { expect(seriesStub.args[0][0]).to.eql([boundConnect, Fudd._createChannel]); }); - it('should call the finalCallback if the first series call calls back with an error', function () { + it('should call the finalCallback if the first series call calls back with an error', function() { var expectedError = new Error('things happened'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should call _deleteExchange.bind for each exchange in the config', function () { + it('should call _deleteExchange.bind for each exchange in the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(deleteExchangeBindStub.callCount).to.equal(config.exchanges.length); }); - it('should call _deleteExchange.bind for each queue in the config', function () { + it('should call _deleteExchange.bind for each queue in the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(deleteQueueBindStub.callCount).to.equal(config.queues.length); }); - it('should invoke series again with a sequence of functions derived from the config', function () { + it('should invoke series again with a sequence of functions derived from the config', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); expect(seriesStub.args[1][0]).to.eql([ boundDeleteExchange, @@ -220,14 +220,14 @@ describe('fudd', function() { ]); }); - it('should call the final callback with the error returned from creating the infrastructure', function () { + it('should call the final callback with the error returned from creating the infrastructure', function() { var expectedError = new Error('error creating infrastructure'); seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should invoke Fudd._disconnect wtih the connection and callback', function () { + it('should invoke Fudd._disconnect wtih the connection and callback', function() { seriesStub.callArgWith(1, null, 'connection', 'channel'); seriesStub.callArgWith(1, null); expect(disconnectStub.args[0]).to.eql([ @@ -237,138 +237,138 @@ describe('fudd', function() { }); }); - describe('_createExchange', function () { + describe('_createExchange', function() { var assertExchangeStub; var mockChannel; var callbackStub; var error; var exchangeDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {assertExchange: assertExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); exchangeDefinition = {name: 'na.me', type: 'fanout', options: {opt: 'ion'}}; }); - it('should call assertExchange with exchange definition & options', function () { + it('should call assertExchange with exchange definition & options', function() { Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); expect(assertExchangeStub.calledWith(exchangeDefinition.name, exchangeDefinition.type, exchangeDefinition.options)).to.equal(true); }); - it('should callback with error if assertExchange calls back with error', function () { + it('should callback with error if assertExchange calls back with error', function() { assertExchangeStub.callsArgWith(3, error); Fudd._createExchange(mockChannel, exchangeDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createQueue', function () { + describe('_createQueue', function() { var assertQueueStub; var mockChannel; var callbackStub; var error; var queueDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {assertQueue: assertQueueStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); queueDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call assertQueue with queue definition & options', function () { + it('should call assertQueue with queue definition & options', function() { Fudd._createQueue(mockChannel, queueDefinition, callbackStub); expect(assertQueueStub.calledWith(queueDefinition.name, queueDefinition.options)).to.equal(true); }); - it('should callback with error if assertQueue calls back with error', function () { + it('should callback with error if assertQueue calls back with error', function() { assertQueueStub.callsArgWith(2, error); Fudd._createQueue(mockChannel, queueDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_deleteExchange', function () { + describe('_deleteExchange', function() { var deleteExchangeStub; var mockChannel; var callbackStub; var error; var exchangeDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {deleteExchange: deleteExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); exchangeDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call deleteExchange with exchange name', function () { + it('should call deleteExchange with exchange name', function() { Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); expect(deleteExchangeStub.calledWith(exchangeDefinition.name, {})).to.equal(true); }); - it('should callback with error if deleteExchange calls back with error', function () { + it('should callback with error if deleteExchange calls back with error', function() { deleteExchangeStub.callsArgWith(2, error); Fudd._deleteExchange(mockChannel, exchangeDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_deleteQueue', function () { + describe('_deleteQueue', function() { var deleteQueue; var mockChannel; var callbackStub; var error; var queueDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {deleteQueue: deleteQueue = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); queueDefinition = {name: 'na.me', options: {opt: 'ion'}}; }); - it('should call deleteQueue with queue name', function () { + it('should call deleteQueue with queue name', function() { Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); expect(deleteQueue.calledWith(queueDefinition.name, {})).to.equal(true); }); - it('should callback with error if deleteQueue calls back with error', function () { + it('should callback with error if deleteQueue calls back with error', function() { deleteQueue.callsArgWith(2, error); Fudd._deleteQueue(mockChannel, queueDefinition, callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBindings', function () { + describe('_createBindings', function() { var createBindingBindStub; - var boundCreateBinding = function () { + var boundCreateBinding = function() { }; var bindingDefinition; var callbackSpy; - before('setup stubs', function () { + before('setup stubs', function() { createBindingBindStub = sinon.stub(Fudd._createBinding, 'bind').returns(boundCreateBinding); bindingDefinition = {bindingKeys: ['#', '#.#'], bindingType: 'queue', to: 'x', from: 'y'}; callbackSpy = sinon.spy(); }); - after('restore stubs', function () { + after('restore stubs', function() { Fudd._createBinding.bind.restore(); }); - beforeEach('reset stubs & invoke', function () { + beforeEach('reset stubs & invoke', function() { createBindingBindStub.reset(); callbackSpy.reset(); Fudd._createBindings({}, bindingDefinition, callbackSpy); }); - it('should call mapEach with all bindingKeys and a bound createBinding call', function () { + it('should call mapEach with all bindingKeys and a bound createBinding call', function() { expect(mapEachStub.calledWith(bindingDefinition.bindingKeys, boundCreateBinding)).to.eql(true); }); - it('should callback with error if mapEach calls back with error', function () { + it('should callback with error if mapEach calls back with error', function() { var error = new Error('boo'); mapEachStub.callsArgWith(2, error); Fudd._createBindings({}, bindingDefinition, callbackSpy); @@ -376,84 +376,83 @@ describe('fudd', function() { }); }); - describe('_createBinding (queue)', function () { + describe('_createBinding (queue)', function() { var bindQueueStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {bindQueue: bindQueueStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'queue'}; }); - it('should call bindQueue with queue name & source exchange', function () { + it('should call bindQueue with queue name & source exchange', function() { Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(bindQueueStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); }); - it('should callback with error if bindQueue calls back with error', function () { + it('should callback with error if bindQueue calls back with error', function() { bindQueueStub.callsArgWith(4, error); Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBinding (exchange)', function () { + describe('_createBinding (exchange)', function() { var bindExchangeStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exchange'}; }); - it('should call bindExchange with exchange name & source exchange', function () { + it('should call bindExchange with exchange name & source exchange', function() { Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(bindExchangeStub.calledWith(bindingDefinition.to, bindingDefinition.from, '#', bindingDefinition.options)).to.equal(true); }); - it('should callback with error if bindExchange calls back with error', function () { + it('should callback with error if bindExchange calls back with error', function() { bindExchangeStub.callsArgWith(4, error); Fudd._createBinding(mockChannel, bindingDefinition, '#', callbackStub); expect(callbackStub.calledWith(error)); }); }); - describe('_createBinding (unsupported)', function () { + describe('_createBinding (unsupported)', function() { var bindExchangeStub; var mockChannel; var callbackStub; var error; var bindingDefinition; - beforeEach(function () { + beforeEach(function() { mockChannel = {bindExchange: bindExchangeStub = sinon.stub()}; callbackStub = sinon.stub(); error = new Error('something broke'); bindingDefinition = {to: 'y', from: 'x', options: {opt: 'ion'}, bindingType: 'exhcabge'}; }); - it('should callback with error if bindExchange calls back with error', function () { + it('should callback with error if bindExchange calls back with error', function() { var message = 'unsupported binding type: ' + bindingDefinition.bindingType; - Fudd._createBinding(mockChannel, bindingDefinition, '#', function (err) { + Fudd._createBinding(mockChannel, bindingDefinition, '#', function(err) { expect(err.message).to.equal(message); }); }); }); + describe('_disconnect & createChannel', function() { - describe('_disconnect & createChannel', function () { - - before(function () { + before(function() { mockery.resetCache(); mockery.deregisterAll(); mockery.registerAllowable('../../lib/fudd.js'); @@ -469,28 +468,28 @@ describe('fudd', function() { createChannel: sinon.stub() }; - beforeEach(function () { + beforeEach(function() { connection.close.reset(); connection.createChannel.reset(); callbackSpy.reset(); }); describe('_disconnect', function() { - it('should call close on the provided connection', function () { + it('should call close on the provided connection', function() { Fudd._disconnect(connection, callbackSpy); expect(connection.close.callCount).to.equal(1); }); }); describe('_createChannel', function() { - it('should call back with the error from createChannel', function () { + it('should call back with the error from createChannel', function() { var expectedError = new Error('connection is borked'); Fudd._createChannel(connection, callbackSpy); connection.createChannel.callArgWith(0, expectedError); expect(callbackSpy.args[0]).to.eql([expectedError]); }); - it('should call back with the originating connection and the channel from createChannel', function () { + it('should call back with the originating connection and the channel from createChannel', function() { Fudd._createChannel(connection, callbackSpy); connection.createChannel.callArgWith(0, null, 'this is a fake channel'); expect(callbackSpy.args[0]).to.eql([null, connection, 'this is a fake channel']);