Skip to content

Commit

Permalink
Merge pull request balderdashy#1039 from tjwebb/multiple-adapter-tests
Browse files Browse the repository at this point in the history
Test and Refactor Multiple Adapter logic
  • Loading branch information
tjwebb committed Jun 4, 2015
2 parents 519ec20 + b07ce6f commit 2e0cea8
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 81 deletions.
69 changes: 21 additions & 48 deletions lib/waterline/core/dictionary.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* Module Dependencies
*/

var _ = require('lodash');

/**
Expand All @@ -11,73 +7,50 @@ var _ = require('lodash');
* @param {Array} ordered
* @return {Object}
* @api public
*
* Manages a 'dictionary' object of the following structure:
* {
* CONNECTION: {
* METHOD: ADAPTER_NAME
* }
* }
*/

var Dictionary = module.exports = function(connections, ordered) {

// Build up a dictionary of methods for the collection's adapters and which connection
// they will run on.
this.dictionary = {};

// Build the Dictionary
this._build(connections);

// Smash together Dictionary methods into a single level
var dictionary = this._smash(ordered);

return dictionary;
this.dictionary = this._build(connections);
return this._smash(ordered);
};

/**
* Build Dictionary
* Build Dictionary. This maps adapter methods to the effective connection
* for which the method is pertinent.
*
* @param {Object} connections
* @api private
*/

Dictionary.prototype._build = function _build(connections) {
var self = this;
return _.mapValues(connections, function (connection, connectionName) {
var adapter = connection._adapter || { };

Object.keys(connections).forEach(function(conn) {
var connection = connections[conn];
var methods = {};
var adapter = connection._adapter || {};

Object.keys(adapter).forEach(function(key) {
methods[key] = conn;
return _.mapValues(adapter, function (method) {
return connectionName;
});

self.dictionary[conn] = _.cloneDeep(methods);
});

};

/**
* Combine Dictionary into a single level object.
*
* Appends methods from other adapters onto the left most connection adapter.
* Appends methods from other adapters onto the left most connection adapter,
* but does not override any existing methods defined in the leftmost adapter.
*
* @param {Array} ordered
* @return {Object}
* @api private
*/

Dictionary.prototype._smash = function _smash(ordered) {
var self = this;

// Ensure Ordered is defined
ordered = ordered || [];

// Smash the methods together into a single layer object using the lodash merge
// functionality.
var adapter = {};

// Reverse the order of connections so we will start at the end merging objects together
ordered.reverse();

ordered.forEach(function(adapterName) {
adapter = _.merge(adapter, self.dictionary[adapterName]);
});
var mergeArguments = _.map((ordered || [ ]).reverse(), function (adapterName) {
return this.dictionary[adapterName];
}, this);

return adapter;
return _.merge.apply(null, mergeArguments);
};
91 changes: 58 additions & 33 deletions test/integration/Collection.multipleAdapters.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,41 @@
var Waterline = require('../../lib/waterline'),
assert = require('assert');
var Waterline = require('../../lib/waterline');
var assert = require('assert');
var _ = require('lodash');

describe('Waterline Collection', function() {
var User, status = 0;
var User;
var status = 0;
var adapter_1 = {
identity: 'foo',
registerConnection: function(connection, collections, cb) {
status++;
cb();
},
baseMethod: function () {
return 'base foo';
}
};

before(function(done) {


var adapter_1 = {
identity: 'foo',
registerConnection: function(connection, collections, cb) {
status++;
cb();
}
};

var adapter_2 = {
identity: 'bar',
registerConnection: function(connection, collections, cb) {
status++;
cb();
}
};

var Model = Waterline.Collection.extend({
attributes: {},
connection: ['my_foo', 'my_bar'],
tableName: 'tests'
});
var adapter_2 = {
identity: 'bar',
registerConnection: function(connection, collections, cb) {
status++;
cb();
},
baseMethod: function () {
return 'base bar';
},
customMethod: function () {
return 'custom bar'
}
};
var Model = Waterline.Collection.extend({
attributes: {},
connection: ['my_foo', 'my_bar'],
tableName: 'tests'
});

before(function(done) {
var waterline = new Waterline();
waterline.loadCollection(Model);

Expand All @@ -41,17 +48,35 @@ describe('Waterline Collection', function() {
}
};

waterline.initialize({ adapters: { 'foo': adapter_1, 'bar': adapter_2 }, connections: connections }, function(err, colls) {
if(err) return done(err);
User = colls.collections.tests;
done();
});
waterline.initialize({
adapters: {
'foo': adapter_1,
'bar': adapter_2
},
connections: connections
},
function(err, colls) {
if (err) return done(err);
User = colls.collections.tests;
done();
}
);
});

describe('multiple adapters', function() {

it('should call registerCollection on all adapters', function() {
assert(status == 2);
assert.equal(status, 2);
});

it('should expose an adapter\'s custom methods', function () {
assert(_.isFunction(User.customMethod));
assert.equal(User.customMethod(), 'custom bar');
});

it('should give precedence to adapters earlier in the list', function () {
assert(_.isFunction(User.baseMethod));
assert.equal(User.baseMethod(), 'base foo');
});

});
Expand Down

0 comments on commit 2e0cea8

Please sign in to comment.