diff --git a/index.js b/index.js index 8760fab..2ce98f9 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,7 @@ module.exports = Barrels; /** * Barrels module - * @param {string} sourceFolder defaults to /test/fixtures + * @param {string} [sourceFolder] defaults to /test/fixtures */ function Barrels(sourceFolder) { if (!(this instanceof Barrels)) @@ -149,22 +149,35 @@ Barrels.prototype.populate = function(collections, done, autoAssociations) { var itemIndex = fixtureObjects.indexOf(item); for (var alias in that.associations[modelName]) { - if (that.associations[modelName][alias].required) { + var association = that.associations[modelName][alias]; + if (association.required) + { // With required associations present, the associated fixtures // must be already loaded, so we can map the ids - var collectionName = that.associations[modelName][alias].collection; // many-to-many - var associatedModelName = that.associations[modelName][alias].model; // one-to-many + var collectionName = association.collection; // many-to-many + var associatedModelName = association.model; // one-to-many + + // NOTE that [item[alias] - 1] and [item[alias][i] - 1] + // only works for auto-increment integers (or string numbers) + // the purpose it to keep auto-incremented integers + // equal to the first created batch, so the database can be + // recreated without higher numbers being created + // (which would breaking associations). - if ((_.isArray(item[alias]))&&(collectionName)) { + if ((_.isArray(item[alias])) && (collectionName)) { if (!that.idMap[collectionName]) return nextItem(new Error('Please provide a loading order acceptable for required associations')); for (var i = 0; i < item[alias].length; i++) { - item[alias][i] = that.idMap[collectionName][item[alias][i] - 1]; + if (_.isFinite(item[alias][i] - 1)) { + item[alias][i] = that.idMap[collectionName][item[alias][i] - 1]; + } } } else if (associatedModelName) { if (!that.idMap[associatedModelName]) return nextItem(new Error('Please provide a loading order acceptable for required associations')); - item[alias] = that.idMap[associatedModelName][item[alias] - 1]; + if (_.isFinite(item[alias - 1])) { + item[alias] = that.idMap[associatedModelName][item[alias] - 1]; + } } } else if (autoAssociations) { // The order is not important, so we can strip diff --git a/package.json b/package.json index 18f2dfb..50baafe 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ }, "main": "index.js", "scripts": { - "test": "NODE_ENV=test mocha -R spec" + "test": "mocha test/index.test.js -R spec", + "test:string": "mocha test/string.test.js -R spec", + "test:object": "mocha test/object.test.js -R spec" }, "repository": { "type": "git", diff --git a/test/fixtures/Categories.js b/test/fixtures/int-id/Categories.js similarity index 100% rename from test/fixtures/Categories.js rename to test/fixtures/int-id/Categories.js diff --git a/test/fixtures/customers.json b/test/fixtures/int-id/customers.json similarity index 100% rename from test/fixtures/customers.json rename to test/fixtures/int-id/customers.json diff --git a/test/fixtures/models/Categories.js b/test/fixtures/int-id/models/Categories.js similarity index 100% rename from test/fixtures/models/Categories.js rename to test/fixtures/int-id/models/Categories.js diff --git a/test/fixtures/models/Products.js b/test/fixtures/int-id/models/Products.js similarity index 100% rename from test/fixtures/models/Products.js rename to test/fixtures/int-id/models/Products.js diff --git a/test/fixtures/models/Regions.js b/test/fixtures/int-id/models/Regions.js similarity index 100% rename from test/fixtures/models/Regions.js rename to test/fixtures/int-id/models/Regions.js diff --git a/test/fixtures/models/Sellers.js b/test/fixtures/int-id/models/Sellers.js similarity index 100% rename from test/fixtures/models/Sellers.js rename to test/fixtures/int-id/models/Sellers.js diff --git a/test/fixtures/models/Tags.js b/test/fixtures/int-id/models/Tags.js similarity index 100% rename from test/fixtures/models/Tags.js rename to test/fixtures/int-id/models/Tags.js diff --git a/test/fixtures/products.json b/test/fixtures/int-id/products.json similarity index 100% rename from test/fixtures/products.json rename to test/fixtures/int-id/products.json diff --git a/test/fixtures/regions.json b/test/fixtures/int-id/regions.json similarity index 100% rename from test/fixtures/regions.json rename to test/fixtures/int-id/regions.json diff --git a/test/fixtures/sellers.json b/test/fixtures/int-id/sellers.json similarity index 100% rename from test/fixtures/sellers.json rename to test/fixtures/int-id/sellers.json diff --git a/test/fixtures/tags.json b/test/fixtures/int-id/tags.json similarity index 100% rename from test/fixtures/tags.json rename to test/fixtures/int-id/tags.json diff --git a/test/fixtures/object-id/Categories.js b/test/fixtures/object-id/Categories.js new file mode 100644 index 0000000..af7e3d5 --- /dev/null +++ b/test/fixtures/object-id/Categories.js @@ -0,0 +1,14 @@ +module.exports = [ + { + id: '507f1f77bcf86cd799439011', + name: 'Clothes' + }, + { + id: '507f191e810c19729de860ea', + name: "Shoes" + }, + { + id: '56799fa7fdafa4f9402ebb06', + "name": 'Accessories' + } +] diff --git a/test/fixtures/object-id/customers.json b/test/fixtures/object-id/customers.json new file mode 100644 index 0000000..98c2bbe --- /dev/null +++ b/test/fixtures/object-id/customers.json @@ -0,0 +1,12 @@ +[ + { + "id": "56799fa7fdafa4f9402ebb07", + "name": "Walter White", + "email": "walter@heisenberg.com" + }, + { + "id": "56799fa7fdafa4f9402ebb08", + "name": "John Appleseed", + "email": "appleseed@me.com" + } +] diff --git a/test/fixtures/object-id/models/Categories.js b/test/fixtures/object-id/models/Categories.js new file mode 100644 index 0000000..7ce38a6 --- /dev/null +++ b/test/fixtures/object-id/models/Categories.js @@ -0,0 +1,17 @@ +/** + * Categories + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'category' + } + } +}; diff --git a/test/fixtures/object-id/models/Products.js b/test/fixtures/object-id/models/Products.js new file mode 100644 index 0000000..34a5925 --- /dev/null +++ b/test/fixtures/object-id/models/Products.js @@ -0,0 +1,30 @@ +/** + * Products + */ + +module.exports = { + attributes: { + customId: { + type: 'string', + primaryKey: true + }, + name: 'string', + category: { + model: 'categories' + }, + tags: { + collection: 'tags', + via: 'products', + dominant: true + }, + seller: { + model: 'sellers', + required: true + }, + regions: { + collection: 'regions', + via: 'products', + required: true + } + } +}; diff --git a/test/fixtures/object-id/models/Regions.js b/test/fixtures/object-id/models/Regions.js new file mode 100644 index 0000000..e305543 --- /dev/null +++ b/test/fixtures/object-id/models/Regions.js @@ -0,0 +1,20 @@ +/** + * Region + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'regions' + }, + name: { + type: 'string' + } + } +}; diff --git a/test/fixtures/object-id/models/Sellers.js b/test/fixtures/object-id/models/Sellers.js new file mode 100644 index 0000000..16ef550 --- /dev/null +++ b/test/fixtures/object-id/models/Sellers.js @@ -0,0 +1,17 @@ +/** + * Sellers + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + name: { + type: 'string', + required: true + } + } +}; diff --git a/test/fixtures/object-id/models/Tags.js b/test/fixtures/object-id/models/Tags.js new file mode 100644 index 0000000..23effe6 --- /dev/null +++ b/test/fixtures/object-id/models/Tags.js @@ -0,0 +1,17 @@ +/** + * Tags + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'tags' + } + } +}; diff --git a/test/fixtures/object-id/products.json b/test/fixtures/object-id/products.json new file mode 100644 index 0000000..ccd7565 --- /dev/null +++ b/test/fixtures/object-id/products.json @@ -0,0 +1,46 @@ +[ + { + "customId": "56799fa7fdafa4f9402ebb17", + "title": "Leather Jacket", + "category": "507f1f77bcf86cd799439011", + "tags": [ + "56799fa7fdafa4f9402ebb13", + "56799fa7fdafa4f9402ebb14", + "56799fa7fdafa4f9402ebb15" + ], + "seller": "56799fa7fdafa4f9402ebb12", + "regions": [ + "56799fa7fdafa4f9402ebb09", + "56799fa7fdafa4f9402ebb10" + ] + }, + { + "customId": "56799fa7fdafa4f9402ebb18", + "title": "Driving Shoes", + "category": "507f191e810c19729de860ea", + "tags": [ + "56799fa7fdafa4f9402ebb14", + "56799fa7fdafa4f9402ebb15" + ], + "seller": "56799fa7fdafa4f9402ebb12", + "regions": [ + "56799fa7fdafa4f9402ebb10", + "56799fa7fdafa4f9402ebb11" + ] + }, + { + "customId": "56799fa7fdafa4f9402ebb19", + "title": "Aviator Sunglasses", + "category": "56799fa7fdafa4f9402ebb06", + "tags": [ + "56799fa7fdafa4f9402ebb15", + "56799fa7fdafa4f9402ebb16" + ], + "seller": "56799fa7fdafa4f9402ebb12", + "regions": [ + "56799fa7fdafa4f9402ebb09", + "56799fa7fdafa4f9402ebb10", + "56799fa7fdafa4f9402ebb11" + ] + } +] diff --git a/test/fixtures/object-id/regions.json b/test/fixtures/object-id/regions.json new file mode 100644 index 0000000..ef536af --- /dev/null +++ b/test/fixtures/object-id/regions.json @@ -0,0 +1,14 @@ +[ + { + "id": "56799fa7fdafa4f9402ebb09", + "name": "midwest" + }, + { + "id": "56799fa7fdafa4f9402ebb10", + "name": "southwest" + }, + { + "id": "56799fa7fdafa4f9402ebb11", + "name": "pacific" + } +] diff --git a/test/fixtures/object-id/sellers.json b/test/fixtures/object-id/sellers.json new file mode 100644 index 0000000..d002e61 --- /dev/null +++ b/test/fixtures/object-id/sellers.json @@ -0,0 +1,6 @@ +[ + { + "id": "56799fa7fdafa4f9402ebb12", + "name": "Clark Kent" + } +] diff --git a/test/fixtures/object-id/tags.json b/test/fixtures/object-id/tags.json new file mode 100644 index 0000000..1c10a4e --- /dev/null +++ b/test/fixtures/object-id/tags.json @@ -0,0 +1,18 @@ +[ + { + "id": "56799fa7fdafa4f9402ebb13", + "name": "black" + }, + { + "id": "56799fa7fdafa4f9402ebb14", + "name": "casual" + }, + { + "id": "56799fa7fdafa4f9402ebb15", + "name": "leather" + }, + { + "id": "56799fa7fdafa4f9402ebb16", + "name": "summer" + } +] diff --git a/test/fixtures/string-id/Categories.js b/test/fixtures/string-id/Categories.js new file mode 100644 index 0000000..445b284 --- /dev/null +++ b/test/fixtures/string-id/Categories.js @@ -0,0 +1,14 @@ +module.exports = [ + { + id: '1', + name: 'Clothes' + }, + { + id: '2', + name: "Shoes" + }, + { + id: '3', + "name": 'Accessories' + } +] diff --git a/test/fixtures/string-id/customers.json b/test/fixtures/string-id/customers.json new file mode 100644 index 0000000..6980cd5 --- /dev/null +++ b/test/fixtures/string-id/customers.json @@ -0,0 +1,12 @@ +[ + { + "id": "1", + "name": "Walter White", + "email": "walter@heisenberg.com" + }, + { + "id": "2", + "name": "John Appleseed", + "email": "appleseed@me.com" + } +] diff --git a/test/fixtures/string-id/models/Categories.js b/test/fixtures/string-id/models/Categories.js new file mode 100644 index 0000000..7ce38a6 --- /dev/null +++ b/test/fixtures/string-id/models/Categories.js @@ -0,0 +1,17 @@ +/** + * Categories + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'category' + } + } +}; diff --git a/test/fixtures/string-id/models/Products.js b/test/fixtures/string-id/models/Products.js new file mode 100644 index 0000000..34a5925 --- /dev/null +++ b/test/fixtures/string-id/models/Products.js @@ -0,0 +1,30 @@ +/** + * Products + */ + +module.exports = { + attributes: { + customId: { + type: 'string', + primaryKey: true + }, + name: 'string', + category: { + model: 'categories' + }, + tags: { + collection: 'tags', + via: 'products', + dominant: true + }, + seller: { + model: 'sellers', + required: true + }, + regions: { + collection: 'regions', + via: 'products', + required: true + } + } +}; diff --git a/test/fixtures/string-id/models/Regions.js b/test/fixtures/string-id/models/Regions.js new file mode 100644 index 0000000..e305543 --- /dev/null +++ b/test/fixtures/string-id/models/Regions.js @@ -0,0 +1,20 @@ +/** + * Region + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'regions' + }, + name: { + type: 'string' + } + } +}; diff --git a/test/fixtures/string-id/models/Sellers.js b/test/fixtures/string-id/models/Sellers.js new file mode 100644 index 0000000..16ef550 --- /dev/null +++ b/test/fixtures/string-id/models/Sellers.js @@ -0,0 +1,17 @@ +/** + * Sellers + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + name: { + type: 'string', + required: true + } + } +}; diff --git a/test/fixtures/string-id/models/Tags.js b/test/fixtures/string-id/models/Tags.js new file mode 100644 index 0000000..23effe6 --- /dev/null +++ b/test/fixtures/string-id/models/Tags.js @@ -0,0 +1,17 @@ +/** + * Tags + */ + +module.exports = { + attributes: { + id: { + type: 'string', + primaryKey: true, + required: true + }, + products: { + collection: 'products', + via: 'tags' + } + } +}; diff --git a/test/fixtures/string-id/products.json b/test/fixtures/string-id/products.json new file mode 100644 index 0000000..f525981 --- /dev/null +++ b/test/fixtures/string-id/products.json @@ -0,0 +1,46 @@ +[ + { + "customId": "1", + "title": "Leather Jacket", + "category": "1", + "tags": [ + "1", + "2", + "3" + ], + "seller": "1", + "regions": [ + "1", + "2" + ] + }, + { + "customId": "2", + "title": "Driving Shoes", + "category": "2", + "tags": [ + "2", + "3" + ], + "seller": "1", + "regions": [ + "2", + "3" + ] + }, + { + "customId": "3", + "title": "Aviator Sunglasses", + "category": "3", + "tags": [ + "3", + "4" + ], + "seller": "1", + "regions": [ + "1", + "2", + "3" + ] + } +] diff --git a/test/fixtures/string-id/regions.json b/test/fixtures/string-id/regions.json new file mode 100644 index 0000000..dde6d5d --- /dev/null +++ b/test/fixtures/string-id/regions.json @@ -0,0 +1,14 @@ +[ + { + "id": "1", + "name": "midwest" + }, + { + "id": "2", + "name": "southwest" + }, + { + "id": "3", + "name": "pacific" + } +] diff --git a/test/fixtures/string-id/sellers.json b/test/fixtures/string-id/sellers.json new file mode 100644 index 0000000..d5438ce --- /dev/null +++ b/test/fixtures/string-id/sellers.json @@ -0,0 +1,6 @@ +[ + { + "id": "1", + "name": "Clark Kent" + } +] diff --git a/test/fixtures/string-id/tags.json b/test/fixtures/string-id/tags.json new file mode 100644 index 0000000..9d33a0d --- /dev/null +++ b/test/fixtures/string-id/tags.json @@ -0,0 +1,18 @@ +[ + { + "id": "1", + "name": "black" + }, + { + "id": "2", + "name": "casual" + }, + { + "id": "3", + "name": "leather" + }, + { + "id": "4", + "name": "summer" + } +] diff --git a/test/index.test.js b/test/index.test.js index 86f02ba..296dd5d 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -6,7 +6,9 @@ var should = require('should'); var Sails = require('sails'); var Barrels = require('../'); -var barrels = new Barrels(); +var path = require('path'); +var fixtureFolder = path.join(process.cwd(), 'test/fixtures/int-id'); +var barrels = new Barrels(fixtureFolder); describe('Barrels', function() { var fixtures = barrels.data; @@ -34,8 +36,7 @@ describe('Barrels', function() { before(function(done) { Sails.lift({ paths: { - models: require('path').join(process.cwd(), - 'test/fixtures/models') + models: path.join(fixtureFolder, 'models') }, connections: { test: { diff --git a/test/object.test.js b/test/object.test.js new file mode 100644 index 0000000..1b81b5e --- /dev/null +++ b/test/object.test.js @@ -0,0 +1,261 @@ +'use strict'; + +/** + * Dependencies + */ +var should = require('should'); +var Sails = require('sails'); +var Barrels = require('../'); +var path = require('path'); +var fixtureFolder = path.join(process.cwd(), 'test/fixtures/object-id'); +var barrels = new Barrels(fixtureFolder); + +describe('Barrels with string IDs', function() +{ + var fixtures = barrels.data; + + // Populate DB with fixtures + describe('populate()', function() + { + before(function(done) + { + Sails.lift({ + paths: { + models: path.join(fixtureFolder, 'models') + }, + connections: { + test: { + adapter: 'sails-memory' + } + }, + models: { + connection: 'test', + migrate: 'drop' + }, + hooks: { + grunt: false + } + }, function(err, sails) + { + done(err); + }); + }); + + after(function(done) + { + Sails.lower(done); + }); + + it('should have string for IDs', function(done) + { + sails.models['sellers'].attributes['id'].type.should.be.eql('string'); + done(); + }); + + describe('populate(cb)', function() + { + before(function(done) + { + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['categories', 'tags', 'products'], function(err) + { + if (err) + return done(err); + + done(); + }, false); + }, false); + }); + + it('should populate the DB with products and categories', function(done) + { + Categories.find().exec(function(err, categories) + { + if (err) + return done(err); + + var gotCategories = (fixtures['categories'].length > 0); + var categoriesAreInTheDb = (categories.length === fixtures['categories'].length); + should(gotCategories && categoriesAreInTheDb).be.ok; + + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + categories.length.should.be.eql(products.length, 'Categories and products should have equal amount of entries!'); + + done(); + }); + }); + }); + + it('should assign a category to each product', function(done) + { + Products.find().populate('category').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.category.name).not.be.empty; + + nextProduct(); + }, done); + }); + }); + + it('should assign at least two tags to each product', function(done) + { + Products.find().populate('tags').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.tags.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + + it('should assign at least two regions to each product', function(done) + { + Products.find().populate('regions').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.regions.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + }); + + describe('populate(cb, false)', function() + { + before(function(done) + { + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['categories', 'products', 'tags'], function(err) + { + if (err) + return done(err); + + done(); + }, false); + }, false); + }); + + it('should keep the associations-related fields', function(done) + { + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + product.category.should.be.a.Number; + product.tags.should.be.an.Array; + + nextProduct(); + }, done); + }); + }); + + it('should always populate required associations', function(done) + { + Products.find().populate('regions').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.regions.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + + }); + + describe('populate(modelList, cb)', function() + { + before(function(done) + { + Products.destroy().exec(function(err) + { + if (err) + return done(err); + + Categories.destroy().exec(function(err) + { + if (err) + return done(err); + + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['products', 'tags'], function(err) + { + if (err) + return done(err); + + done(); + }, false); + }, false); + }); + }); + }); + + it('should populate products but not categories', function(done) + { + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + products.length.should.be.greaterThan(1); + }); + + Categories.find().exec(function(err, categories) + { + if (err) + return done(err); + + categories.length.should.be.eql(0); + }); + + done(); + }); + }); + + it('should ask for specific order while populating models with required associations', function(done) { + barrels.populate(['products'], function(err) { + should(err.message).be.eql('Please provide a loading order acceptable for required associations'); + + done(); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/string.test.js b/test/string.test.js new file mode 100644 index 0000000..2b19799 --- /dev/null +++ b/test/string.test.js @@ -0,0 +1,263 @@ +'use strict'; + +/** + * Dependencies + */ +var should = require('should'); +var Sails = require('sails'); +var Barrels = require('../'); +var path = require('path'); +var fixtureFolder = path.join(process.cwd(), 'test/fixtures/string-id'); +var barrels = new Barrels(fixtureFolder); + +describe('Barrels with string IDs', function() +{ + var fixtures = barrels.data; + + // Populate DB with fixtures + describe('populate()', function() + { + before(function(done) + { + Sails.lift({ + paths: { + models: path.join(fixtureFolder, 'models') + }, + connections: { + test: { + adapter: 'sails-memory' + } + }, + models: { + connection: 'test', + migrate: 'drop' + }, + hooks: { + grunt: false + } + }, function(err, sails) + { + done(err); + }); + }); + + after(function(done) + { + Sails.lower(done); + }); + + it('should have string for IDs', function(done) + { + sails.models['sellers'].attributes['id'].type.should.be.eql('string'); + done(); + }); + + describe('populate(cb)', function() + { + before(function(done) + { + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['categories', 'products', 'tags'], function(err) + { + if (err) + return done(err); + + done(); + }); + }); + }); + + it('should populate the DB with products and categories', function(done) + { + Categories.find().exec(function(err, categories) + { + if (err) + return done(err); + + var gotCategories = (fixtures['categories'].length > 0); + var categoriesAreInTheDb = (categories.length === fixtures['categories'].length); + should(gotCategories && categoriesAreInTheDb).be.ok; + + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + categories.length.should.be.eql(products.length, 'Categories and products should have equal amount of entries!'); + + done(); + }); + }); + }); + + it('should assign a category to each product', function(done) + { + Products.find().populate('category').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.category.name).not.be.empty; + + nextProduct(); + }, done); + }); + }); + + it('should assign at least two tags to each product', function(done) + { + Products.find().populate('tags').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.tags.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + + it('should assign at least two regions to each product', function(done) + { + Products.find().populate('regions').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.regions.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + }); + + describe('populate(cb, false)', function() + { + before(function(done) + { + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['categories', 'products', 'tags'], function(err) + { + if (err) + return done(err); + + done(); + }, false); + }, false); + }); + + it('should keep the associations-related fields', function(done) + { + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + product.category.should.be.a.Number; + product.tags.should.be.an.Array; + + nextProduct(); + }, done); + }); + }); + + it('should always populate required associations', function(done) + { + Products.find().populate('regions').exec(function(err, products) + { + if (err) + return done(err); + + async.each(products, function(product, nextProduct) + { + should(product.regions.length).be.greaterThan(1); + + nextProduct(); + }, done); + }); + }); + + }); + + describe('populate(modelList, cb)', function() + { + before(function(done) + { + Products.destroy().exec(function(err) + { + if (err) + return done(err); + + Categories.destroy().exec(function(err) + { + if (err) + return done(err); + + barrels.populate(['sellers', 'regions'], function(err) + { + if (err) + return done(err); + + barrels.populate(['products', 'tags'], function(err) + { + if (err) + return done(err); + + done(); + }); + }); + }); + }); + }); + + it('should populate products but not categories', function(done) + { + Products.find().exec(function(err, products) + { + if (err) + return done(err); + + products.length.should.be.greaterThan(1); + }); + + Categories.find().exec(function(err, categories) + { + if (err) + return done(err); + + categories.length.should.be.eql(0); + }); + + done(); + }); + }); + + it('should ask for specific order while populating models with required associations', function(done) + { + barrels.populate(['products'], function(err) + { + should(err.message).be.eql('Please provide a loading order acceptable for required associations'); + + done(); + }); + }); + }); +}); \ No newline at end of file