From c1e3f269bb72a168604946f39bbc2788722fee89 Mon Sep 17 00:00:00 2001 From: blah238 Date: Fri, 26 Jun 2015 18:25:07 -0500 Subject: [PATCH] Reimplement as a plugin for Bookshelf/Knex 0.8.x - Changed constructor signature to require Bookshelf instance as first argument, and made `root` an optional property of the second `options` argument - Added Manager.plugin() method to be used with Bookshelf.plugin() (exported on main index.js module) - Exposes self as `manager` property on Bookshelf instance when instantiated - Replaced Manager.manage() and Manager.manages() with manager.register() to improve compatibility with Bookshelf Registry plugin - Removed `hooker` dependency and manager.debug() method - Use NPM devDependencies and peerDependencies instead of dependencies since it is intended to be used as a plugin now - Changed test database from MySQL to SQLite for easier testing setup - Updated README.md - Bumped version to 0.1.0 (not fully backwards-compatible) - Add JSHint/JSCS configs --- .jscs.json | 7 ++ .jshintrc | 3 + README.md | 41 +++++++ index.js | 2 +- lib/manager.js | 170 +++++++++-------------------- package.json | 19 ++-- test/.jshintrc | 4 + test/databases/mysql.js | 10 -- test/databases/test.js | 11 -- test/manager.create.js | 84 ++++++-------- test/manager.fetch.js | 85 +++++++-------- test/manager.forge.js | 11 +- test/manager.get.js | 105 +++++++++--------- test/manager.js | 57 +++------- test/manager.manage.js | 23 ---- test/manager.plugin.js | 15 +++ test/manager.register.js | 52 +++++++++ test/manager.save.js | 76 ++++++------- test/models/car.js | 10 +- test/models/cars.js | 8 +- test/models/color.js | 8 +- test/models/dealer.js | 6 +- test/models/feature.js | 6 +- test/models/features.js | 8 +- test/models/make.js | 8 +- test/models/makes.js | 6 +- test/models/model.js | 6 +- test/models/models.js | 6 +- test/models/spec.js | 6 +- test/models/specs.js | 6 +- test/models/type.js | 6 +- test/support/bootstrap.database.js | 14 ++- test/support/bootstrap.fixtures.js | 6 +- test/support/bootstrap.js | 6 +- test/support/bootstrap.manager.js | 8 ++ test/support/bootstrap.models.js | 13 +++ test/support/bootstrap.tables.js | 130 +++++++++++----------- test/support/manager.js | 6 - 38 files changed, 504 insertions(+), 544 deletions(-) create mode 100644 .jscs.json create mode 100644 .jshintrc create mode 100644 test/.jshintrc delete mode 100644 test/databases/mysql.js delete mode 100644 test/databases/test.js delete mode 100644 test/manager.manage.js create mode 100644 test/manager.plugin.js create mode 100644 test/manager.register.js create mode 100644 test/support/bootstrap.manager.js create mode 100644 test/support/bootstrap.models.js delete mode 100644 test/support/manager.js diff --git a/.jscs.json b/.jscs.json new file mode 100644 index 0000000..96c3f0c --- /dev/null +++ b/.jscs.json @@ -0,0 +1,7 @@ +{ + "preset": "node-style-guide", + "requireCamelCaseOrUpperCaseIdentifiers": "ignoreProperties", + "maximumLineLength": null, + "requireTrailingComma": null, + "disallowTrailingComma": true +} diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..c1f2978 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,3 @@ +{ + "node": true +} diff --git a/README.md b/README.md index 6d4dce3..aae28eb 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,46 @@ > Model & Collection manager for [Bookshelf.js][1] to make it easy to create & > save deep, nested JSON structures from API requests. +## Installation + + npm install bookshelf-manager --save + +## Usage + + 1. Register as a plugin in Bookshelf: + + ```javascript + bookshelf.plugin('bookshelf-manager'); + ``` + + - Optionally, you can pass in an object with a `root` property to read models from a specified directory: + + ```javascript + bookshelf.plugin('bookshelf-manager', { root: 'path/to/models' }); + ``` + + 2. Register individual models (not required if you passed in a `root` model directory as above): + + ```javascript + bookshelf.manager.register(model, modelName); + ``` + + - Note: Also compatible with models registered with the [Bookshelf Registry](https://github.com/tgriesser/bookshelf/wiki/Plugin:-Model-Registry) plugin. + + 3. Use the methods on `bookshelf.manager` to create, fetch, and save models or collections with support for deeply-nested attributes. E.g.: + + ```javascript + return bookshelf.manager.create('car', { + features: [ + { name: 'ABS', cost: '1250' }, + { name: 'GPS', cost: '500' } + ], + quantity: 1 + }).then(function(car) { + // created car should now have the associated features + }); + ``` + ## API @@ -15,6 +55,7 @@ ## Changelog +- v0.1.0 - Reimplement as a plugin for Bookshelf/Knex 0.8.x - v0.0.10 - Enforce `belongsToMany` IDs - v0.0.9 - Destroy removed `hasMany` models - v0.0.8 - Fetch empty collections diff --git a/index.js b/index.js index c762781..2dc14e5 100644 --- a/index.js +++ b/index.js @@ -1 +1 @@ -module.exports = require('./lib/manager'); +module.exports = require('./lib/manager').plugin; diff --git a/lib/manager.js b/lib/manager.js index 78d9a90..f4d27e6 100644 --- a/lib/manager.js +++ b/lib/manager.js @@ -1,43 +1,38 @@ -var Bookshelf = require('bookshelf'); -var hooker = require('hooker'); var path = require('path'); var Promise = require('bluebird'); -var Manager = function(root, bookshelf) { - if (!root) { - throw new Error('Manager requires a path to model directory'); +function Manager(bookshelf, options) { + + if (!(arguments.length > 0 && bookshelf && bookshelf.VERSION)) { + throw new Error('Manager requires a Bookshelf instance'); } - this.root = path.normalize(root); + this.root = options && options.root ? path.normalize(options.root) : null; - if (bookshelf) { - this.initialize(bookshelf); - } else { - hooker.hook(Bookshelf, 'initialize', { - once: true, - post: this.initialize.bind(this) - }); - } + this.initialize(bookshelf); +} + +Manager.plugin = function(bookshelf, options) { + return new Manager(bookshelf, options); }; -Manager.manage = function(model) { - if (!Manager.manages(model)) { - Manager._managed.push(model); +Manager.prototype.register = function(model, name) { + + if (!(arguments.length >= 2 && model && typeof name === 'string')) { + throw new Error('Manager.register must be called with a model and a model name'); } - return model; -}; + var Model = this.get(model); -Manager.manages = function(model) { - if (!model instanceof Function) { - return false; + if (this.isModel(Model)) { + this.bookshelf.model(name, Model); + } else if (this.isCollection(Model)) { + this.bookshelf.collection(name, Model); } - return Manager._managed.indexOf(model) !== -1 + return Model; }; -Manager._managed = []; - Manager.prototype.initialize = function(bookshelf) { this.bookshelf = bookshelf; this.knex = this.bookshelf.knex; @@ -45,17 +40,12 @@ Manager.prototype.initialize = function(bookshelf) { bookshelf.plugin('registry'); - hooker.hook(bookshelf, ['collection', 'model'], function(name, value) { - if (!value) { - return hooker.preempt(this.get(name)); - } - }.bind(this)); + // Expose the Bookshelf Manager instance on the Bookshelf instance + bookshelf.manager = this; return this; }; -Manager.prototype._cache = {}; - Manager.prototype.create = function(name, properties) { var Model = this.get(name); var model = new Model(); @@ -66,76 +56,11 @@ Manager.prototype.create = function(name, properties) { }); }; -Manager.prototype.debug = function(debug) { - var level = 1; - var methods = [ - 'create', - 'fetch', - 'forge', - 'get', - 'load', - 'save', - 'saveCollection', - 'saveModel', - 'set', - 'setBelongsTo', - 'setBelongsToMany', - 'setCollection', - 'setHasMany', - 'setModel', - 'setScalar', - ]; - - var pre = function(name) { - var indent = new Array(level++).join(' '); - var sliced = Array.prototype.slice.call(arguments, 1); - var args = sliced.map(function(arg) { - if (this.isCollection(arg)) { - return '[Collection] (' + arg.length + ')'; - } - - if (this.isModel(arg)) { - return '[Model `' + arg.tableName + '@' + arg.id + '`]'; - } - - return (JSON.stringify(arg) || 'null').split('\n').join('\n' + indent + ' '); - }.bind(this)).join(',\n' + indent + ' '); - - console.log(indent, '<' + name + '>', '\n' + indent + ' ', args); - }; - - var post = function(result, name) { - if (result && result.then) { - result.then(function() { - console.log(new Array(--level).join(' '), ''); - - return arguments[0]; - }); - }; - }; - - if (typeof debug === 'undefined') { - debug = true; - } - - if (debug) { - hooker.hook(this, methods, { - passName: true, - pre: pre, - post: post - }); - } else { - hooker.unhook(this, methods); - } - - return this; -}; - Manager.prototype.fetch = function(name, properties, related) { var model = this.forge(name, properties); return model.fetch({ - withRelated: related, + withRelated: related }); }; @@ -188,42 +113,45 @@ Manager.prototype.get = function(Model) { if (typeof Model === 'string') { name = Model; - if (this._cache[name]) { - return this._cache[name]; + Model = this.bookshelf.collection(name) || this.bookshelf.model(name); + + if (this.isModelOrCollection(Model)) { + return Model; } - var file = path.join(this.root, name); + if (this.root) { + + var file = path.join(this.root, name); - try { - Model = require(file); - } catch (e) { - throw new Error('Could not find module `' + name + '` at `' + file + '.js`'); + try { + Model = require(file); + } catch (e) { + throw new Error('Could not find module `' + name + '` at `' + file + '.js`'); + } + } else { + throw new Error('No model named `' + name + '` has been registered and no model directory was specified'); } } - if (Manager.manages(Model)) { + if (!this.isModelOrCollection(Model)) { Model = Model(this.bookshelf); } - if (!this.isModel(Model) && !this.isCollection(Model)) { - throw new Error('Expected a String, Model, Collection, or a Managed Model/Collection, got: ' + typeof Model); + if (!this.isModelOrCollection(Model)) { + throw new Error('Expected a String, Model, or Collection, got: ' + typeof Model); } if (this.isCollection(Model) && typeof Model.prototype.model === 'string') { Model.prototype.model = this.get(Model.prototype.model); } - if (name) { - if (this.isModel(Model)) { - this._cache[name] = this.bookshelf.model(name, Model); - } else if (this.isCollection(Model)) { - this._cache[name] = this.bookshelf.collection(name, Model); - } - } - return Model; }; +Manager.prototype.isModelOrCollection = function(model) { + return (this.isModel(model) || this.isCollection(model)); +}; + Manager.prototype.isModel = function(model) { if (!model || this.isCollection(model)) { return false; @@ -276,7 +204,7 @@ Manager.prototype.saveModel = function(model, properties) { console.error(error.stack); throw error; }); -} +}; Manager.prototype.set = function(model, properties) { if (this.isModel(model)) { @@ -291,7 +219,7 @@ Manager.prototype.set = function(model, properties) { Manager.prototype.setModel = function(model, properties) { var promises = []; - properties = properties || {}; + properties = (typeof properties === 'object' && !Array.isArray(properties) && properties !== null) ? properties : {}; if (model.isNew() && properties && properties.id) { promises.push(function() { @@ -300,12 +228,12 @@ Manager.prototype.setModel = function(model, properties) { }); }.bind(this)); } else { - promises.push(function () { + promises.push(function() { return model; }); } - function setProperties (propertyType) { + function setProperties(propertyType) { Object.keys(properties).forEach(function(key) { var value = properties[key]; @@ -326,7 +254,7 @@ Manager.prototype.setModel = function(model, properties) { setProperties.bind(this)('scalar'); - promises.push(function (result) { + promises.push(function(result) { return (result.isNew() || result.hasChanged()) ? result.save() : result; }); diff --git a/package.json b/package.json index 48dc9c4..018c0de 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bookshelf-manager", - "version": "0.0.10", + "version": "0.1.0", "description": "Easily wire up models to APIs with supported for complex, nested saving.", "main": "index.js", "scripts": { @@ -23,13 +23,16 @@ "url": "https://github.com/ericclemmons/bookshelf-manager/issues" }, "devDependencies": { - "mocha": "~1.17.1", - "mysql": "~2.1.0" + "bluebird": "^2.9.30", + "bookshelf": "^0.8.1", + "deep-diff": "^0.3.2", + "knex": "^0.8.6", + "mocha": "^2.2.5", + "sqlite3": "^3.0.8" }, - "dependencies": { - "bookshelf": "~0.6.4", - "bluebird": "~1.0.7", - "hooker": "^0.2.3", - "deep-diff": "^0.1.4" + "peerDependencies": { + "bluebird": "2.x", + "bookshelf": "^0.8.0", + "knex": "^0.8.0" } } diff --git a/test/.jshintrc b/test/.jshintrc new file mode 100644 index 0000000..e26f0d4 --- /dev/null +++ b/test/.jshintrc @@ -0,0 +1,4 @@ +{ + "extends": "../.jshintrc", + "mocha": true +} diff --git a/test/databases/mysql.js b/test/databases/mysql.js deleted file mode 100644 index f40f650..0000000 --- a/test/databases/mysql.js +++ /dev/null @@ -1,10 +0,0 @@ -var Bookshelf = require('bookshelf'); - -var MySql = Bookshelf.initialize({ - client: 'mysql', - connection: { - user: 'root', - } -}); - -module.exports = MySql; diff --git a/test/databases/test.js b/test/databases/test.js deleted file mode 100644 index d9de68b..0000000 --- a/test/databases/test.js +++ /dev/null @@ -1,11 +0,0 @@ -var Bookshelf = require('bookshelf'); - -var Test = Bookshelf.initialize({ - client: 'mysql', - connection: { - user: 'root', - database: 'bookshelf_manager_test', - } -}); - -module.exports = Test; diff --git a/test/manager.create.js b/test/manager.create.js index f167180..2208f97 100644 --- a/test/manager.create.js +++ b/test/manager.create.js @@ -1,62 +1,56 @@ var assert = require('assert'); -var Promise = require('bluebird'); var Bootstrap = require('./support/bootstrap'); -var manager = require('./support/manager'); describe('manager', function() { describe('.create', function() { - beforeEach(function(done) { - Bootstrap.database().then(function() { - return Bootstrap.tables(); - }).then(function() { - done(); - }); + var manager; + + beforeEach(function() { + manager = Bootstrap.manager(Bootstrap.database()); + Bootstrap.models(manager); + return Bootstrap.tables(manager); }); - it('should create a new model', function(done) { - manager.create('car').then(function(car) { + it('should create a new model', function() { + return manager.create('car').then(function(car) { assert.ok(manager.isModel(car), 'Car should be a Model'); assert.ok(car.id, 'Car should have ID 1'); - done(); }); }); - it('should create a new collection', function(done) { - manager.create('cars').then(function(cars) { + it('should create a new collection', function() { + return manager.create('cars').then(function(cars) { assert.ok(manager.isCollection(cars), 'Car should be a Collection'); - done(); }); }); - it('should create a new, populated model', function(done) { - manager.create('car', { + it('should create a new, populated model', function() { + return manager.create('car', { quantity: 1 }).then(function(car) { assert.equal(1, car.id, 'Car should have ID 1'); assert.equal(1, car.get('quantity'), 'Car should have quantity of 1'); - done(); }); - }) + }); - it('should create a new, populated collection', function(done) { - manager.create('cars', [ + it('should create a new, populated collection', function() { + return manager.create('cars', [ { quantity: 1 }, - { quantity: 2 }, + { quantity: 2 } ]).then(function(cars) { cars.sortBy('quantity'); assert.equal(2, cars.length, 'Cars collection should have 2 Car models'); assert.equal(2, cars.pluck('quantity').length, 'Quantities should be set'); - done(); }); - }) + }); - it('should create a model within a new model (belongsTo)', function(done) { - manager.create('car', { + it('should create a model within a new model (belongsTo)', function() { + return manager.create('car', { color: { name: 'White', - hex_value: '#fff', + hex_value: '#fff' }, quantity: 1 }).then(function(car) { @@ -65,36 +59,34 @@ describe('manager', function() { assert.equal(1, car.related('color').id, 'Color should have ID 1, not ' + car.related('color').id); assert.equal('White', car.related('color').get('name'), 'Color name should be White'); assert.equal('#fff', car.related('color').get('hex_value'), 'Color hex_value should be #fff'); - done(); - }) + }); }); - it('should modify an existing nested model', function(done) { - manager.create('color', { + it('should modify an existing nested model', function() { + return manager.create('color', { name: 'White', - hex_value: '#fff', + hex_value: '#fff' }).then(function(color) { - manager.create('car', { + return manager.create('car', { color: { id: color.id, name: 'Grey', - hex_value: '#666', + hex_value: '#666' }, quantity: 2 }).then(function(car) { assert.equal(color.id, car.related('color').id, 'Color ID should stay the same, not ' + car.related('color').id); assert.equal('Grey', car.related('color').get('name'), 'Color name should be Grey'); assert.equal('#666', car.related('color').get('hex_value'), 'Color hex_value should be #666'); - done(); }); }); }); - it('should create models within a nested collection (belongsToMany)', function(done) { - manager.create('car', { + it('should create models within a nested collection (belongsToMany)', function() { + return manager.create('car', { features: [ { name: 'ABS', cost: '1250' }, - { name: 'GPS', cost: '500' }, + { name: 'GPS', cost: '500' } ], quantity: 1 }).then(function(car) { @@ -103,15 +95,14 @@ describe('manager', function() { assert.equal(1, car.id, 'Car should have ID 1'); assert.equal(2, car.related('features').length, 'There should be 2 features'); assert.equal(2, car.related('features').pluck('name').length, 'There should be 2 names'); - done(); }); }); - it('should create models within a nested collection (hasMany)', function(done) { - manager.create('make', { + it('should create models within a nested collection (hasMany)', function() { + return manager.create('make', { models: [ { name: 'X3' }, - { name: 'X5' }, + { name: 'X5' } ] }).then(function(make) { make.related('models').sortBy('name'); @@ -122,12 +113,11 @@ describe('manager', function() { assert.ok(make.related('models').at(1).id, 'Model #2 should have ID, not ' + make.related('models').at(1).id); assert.equal('X3', make.related('models').at(0).get('name'), 'Model #1 name should be X3, not ' + make.related('models').at(0).get('name')); assert.equal('X5', make.related('models').at(1).get('name'), 'Model #2 name should be X5, not ' + make.related('models').at(1).get('name')); - done(); }); }); - it('should create a deep object', function(done) { - manager.create('make', { + it('should create a deep object', function() { + return manager.create('make', { name: 'BMW', models: [ { @@ -138,7 +128,7 @@ describe('manager', function() { }, specs: [ { name: '4 door' }, - { name: 'v6' }, + { name: 'v6' } ] } ] @@ -163,13 +153,11 @@ describe('manager', function() { actual.related('models').at(0).related('type').name, result.related('models').at(0).related('type').name ); - - done(); }); }); }); - it('should set scalar attributes before saving new models', function () { + it('should set scalar attributes before saving new models', function() { var ValidatedModel = manager.get('model').extend({ initialize: function() { this.on('saving', this.validateSave); diff --git a/test/manager.fetch.js b/test/manager.fetch.js index fa2dd0f..06bfe2c 100644 --- a/test/manager.fetch.js +++ b/test/manager.fetch.js @@ -1,75 +1,66 @@ var assert = require('assert'); - var Bootstrap = require('./support/bootstrap'); -var manager = require('./support/manager'); describe('manager', function() { + var manager; + describe('.fetch', function() { - before(function(done) { - Bootstrap.database().then(function() { - return Bootstrap.tables(); - }).then(function() { - return Bootstrap.fixtures(); - }).then(function() { - done(); + before(function() { + manager = Bootstrap.manager(Bootstrap.database()); + Bootstrap.models(manager); + return Bootstrap.tables(manager) + .then(function() { + return Bootstrap.fixtures(manager); }); }); - it('should return a Model', function(done) { - manager + it('should return a Model', function() { + return manager .fetch('make', { name: 'BMW' }) .then(function(make) { assert.ok(make instanceof manager.bookshelf.Model); assert.equal('BMW', make.get('name')); - }) - .then(done.bind(this, null), done) - ; + }); }); - it('should return a Collection', function(done) { - manager + it('should return a Collection', function() { + return manager .fetch('makes') .then(function(makes) { assert.ok(makes instanceof manager.bookshelf.Collection); assert.equal(1, makes.length); assert.equal('BMW', makes.get(1).get('name')); - }) - .then(done.bind(this, null), done) - ; + }); }); describe('related', function() { - it('should return nested Models', function(done) { - manager - .fetch('make', { name: 'BMW' }, [ - 'models', - 'models.specs', - 'models.type', - 'dealers', - 'dealers.cars', - 'dealers.cars.color', - 'dealers.cars.model', - 'dealers.cars.features', - 'dealers.cars.model.type', - ]).then(function(make) { - var json = make.toJSON(); - - // console.log(JSON.stringify(json, null, 2)); - - assert.equal('BMW', json.name); - assert.equal('X5', json.models[0].name); - assert.equal(2, json.models[0].specs.length); - assert.equal('Crossover', json.models[0].type.name); - assert.equal('Houston', json.dealers[0].name); - assert.equal('Grey', json.dealers[0].cars[0].color.name); - assert.equal('X5', json.dealers[0].cars[0].model.name); - assert.equal(2, json.dealers[0].cars[0].features.length); + it('should return nested Models', function() { + return manager + .fetch('make', { name: 'BMW' }, [ + 'models', + 'models.specs', + 'models.type', + 'dealers', + 'dealers.cars', + 'dealers.cars.color', + 'dealers.cars.model', + 'dealers.cars.features', + 'dealers.cars.model.type' + ]) + .then(function(make) { + var json = make.toJSON(); - done(); - }) - ; + assert.equal('BMW', json.name); + assert.equal('X5', json.models[0].name); + assert.equal(2, json.models[0].specs.length); + assert.equal('Crossover', json.models[0].type.name); + assert.equal('Houston', json.dealers[0].name); + assert.equal('Grey', json.dealers[0].cars[0].color.name); + assert.equal('X5', json.dealers[0].cars[0].model.name); + assert.equal(2, json.dealers[0].cars[0].features.length); + }); }); }); }); diff --git a/test/manager.forge.js b/test/manager.forge.js index 179680e..4880060 100644 --- a/test/manager.forge.js +++ b/test/manager.forge.js @@ -1,15 +1,14 @@ var assert = require('assert'); var Bootstrap = require('./support/bootstrap'); -var manager = require('./support/manager'); - describe('manager', function() { describe('.forge', function() { - beforeEach(function(done) { - return Bootstrap.database().then(function() { - done(); - }); + var manager; + + before(function() { + manager = Bootstrap.manager(Bootstrap.database()); + Bootstrap.models(manager); }); it('should create a new Model in memory', function() { diff --git a/test/manager.get.js b/test/manager.get.js index 96b6f3f..3c48162 100644 --- a/test/manager.get.js +++ b/test/manager.get.js @@ -1,75 +1,82 @@ var assert = require('assert'); var path = require('path'); -var Promise = require('bluebird'); +var Manager = require('../lib/manager'); var Bootstrap = require('./support/bootstrap'); -var Manager = require('../lib/manager'); -var manager = require('./support/manager'); -var Test = require('./databases/test'); - -var ManagedModel = Manager.manage(function(Bookshelf) { - return Bookshelf.Model.extend({ - table: 'managed_model' - }); -}); describe('manager', function() { describe('.get', function() { - before(function(done) { - Bootstrap.database().then(function() { - done(); + var manager, bookshelf; + + describe('if no root was specified', function() { + before(function() { + bookshelf = Bootstrap.database(); + manager = new Manager(bookshelf); + Bootstrap.models(manager); }); - }); - it('should throw an error if not initialized', function() { - var manager = new Manager(path.join(__dirname, 'models')); - var expected = 'Manager has not been initialized with instance of Bookshelf'; + describe('with a name', function() { + describe('if the model hasn\'t been registered yet', function() { + it('should throw an error', function() { + assert.throws(function() { manager.get('fake'); }, 'No model named `fake` has been registered and no model directory was specified'); + }); + }); - assert.throws(function() { manager.create('make'); }, expected); - assert.throws(function() { manager.get('make'); }, expected); - assert.throws(function() { manager.fetch('make'); }, expected); - assert.throws(function() { manager.forge('make'); }, expected); - assert.throws(function() { manager.save('make'); }, expected); - }); + describe('if the model has been registered', function() { + it('should return the Model', function() { + assert.ok(manager.get('make').prototype instanceof bookshelf.Model); + }); + }); + }); - it('should throw an error if file not found', function() { - assert.throws(function() { manager.get('fake'); }, /Could not find module/); - }); + describe('with a Model', function() { + it('should return a Model', function() { + var Model = bookshelf.Model.extend({}); - it('should register in cache', function() { - assert.equal(manager.get('make'), manager._cache['make']); - assert.equal(manager.get('makes'), manager._cache['makes']); - assert.equal(manager.get('make'), Test.model('make')); - assert.equal(manager.get('makes'), Test.collection('makes')); - }); + assert.equal(Model, manager.get(Model)); + }); - describe('with a name', function() { - it('should return a Model', function() { - assert.ok(manager.get('make').prototype instanceof Test.Model); - }); + it('should return a Collection', function() { + var Collection = bookshelf.Collection.extend(); - it('should return a Collection', function() { - assert.ok(manager.get('makes').prototype instanceof Test.Collection); + assert.equal(Collection, manager.get(Collection)); + }); }); }); - describe('with a Model', function() { - it('should return a Model', function() { - var Model = Test.Model.extend({}); + describe('if root was specified', function() { + + before(function() { + bookshelf = Bootstrap.database(); + manager = Bootstrap.manager(bookshelf); + }); - assert.equal(Model, manager.get(Model)); + it('should throw an error if file not found', function() { + assert.throws(function() { manager.get('fake'); }, /Could not find module/); }); - it('should return a Collection', function() { - var Collection = Test.Collection.extend(); + describe('with a name', function() { + it('should return a Model', function() { + assert.ok(manager.get('make').prototype instanceof bookshelf.Model); + }); - assert.equal(Collection, manager.get(Collection)); + it('should return a Collection', function() { + assert.ok(manager.get('makes').prototype instanceof bookshelf.Collection); + }); }); - }); - describe('with a managed Model', function() { - it('should return a Model for Bookshelf instance', function() { - assert.ok(manager.get(ManagedModel).prototype instanceof Test.Model); + describe('with a Model', function() { + it('should return a Model', function() { + var Model = bookshelf.Model.extend({}); + + assert.equal(Model, manager.get(Model)); + }); + + it('should return a Collection', function() { + var Collection = bookshelf.Collection.extend(); + + assert.equal(Collection, manager.get(Collection)); + }); }); }); }); diff --git a/test/manager.js b/test/manager.js index 76d7164..6e38672 100644 --- a/test/manager.js +++ b/test/manager.js @@ -1,55 +1,32 @@ var assert = require('assert'); -var Bookshelf = require('bookshelf'); -var path = require('path'); +var fs = require('fs'); +var Bootstrap = require('./support/bootstrap'); var Manager = require('../lib/manager'); -var Test = require('./databases/test'); describe('Manager', function() { - describe('when instantiated', function() { - it('should require path as first argument', function() { + describe('constructor', function() { + it('should require a Bookshelf instance as the first argument', function() { assert.throws(function() { - new Manager(); - }, 'Manager requires a path to model directory'); - }); - - it('should accept a Bookshelf instance as second argument', function() { - var manager = new Manager(path.join(__dirname, 'models'), Test); - - assert.equal(Test, manager.bookshelf); - }); - - it('should initialize after Bookshelf only once', function() { - var manager = new Manager(path.join(__dirname, 'models')); - - assert.ok(manager.root); - assert.ok(!manager.bookshelf); - assert.ok(!manager.knex); - assert.ok(!manager.schema); + return new Manager(); + }, /Manager requires a Bookshelf instance/); - var first = Bookshelf.initialize({ - client: 'mysql', - connection: { user: 'root' } - }); - - assert.ok(manager.bookshelf); - assert.ok(manager.knex); - assert.ok(manager.schema); + assert.throws(function() { + return new Manager({ invalid: 'object' }); + }, /Manager requires a Bookshelf instance/); - var second = Bookshelf.initialize({ - client: 'mysql', - connection: { user: 'root' } + assert.doesNotThrow(function() { + return new Manager(Bootstrap.database()); }); - - assert.equal(first, manager.bookshelf); }); - }); - describe('.initialize', function() { - it('should be fluent', function() { - var manager = new Manager(path.join(__dirname, 'models')); + describe('if second options argument is specified', function() { - assert.equal(manager, manager.initialize(Test)); + it('should set the root model directory on the manager instance if provided on the options argument', function() { + var manager = Bootstrap.manager(Bootstrap.database()); + assert(manager.root); + assert(fs.lstatSync(manager.root).isDirectory()); + }); }); }); }); diff --git a/test/manager.manage.js b/test/manager.manage.js deleted file mode 100644 index 95b1e7f..0000000 --- a/test/manager.manage.js +++ /dev/null @@ -1,23 +0,0 @@ -var assert = require('assert'); - -var Manager = require('../lib/manager'); - -var ManagedModel = Manager.manage(function(Bookshelf) { - return Bookshelf.Model.extend({ - table: 'fake' - }); -}); - -describe('Manager', function() { - describe('.manage', function() { - it('should return function', function() { - assert.equal('function', typeof Manager.manage(ManagedModel)); - }); - }); - - describe ('.manages', function() { - it('should be managing a model', function() { - assert.ok(Manager.manages(ManagedModel)); - }); - }); -}); diff --git a/test/manager.plugin.js b/test/manager.plugin.js new file mode 100644 index 0000000..2111814 --- /dev/null +++ b/test/manager.plugin.js @@ -0,0 +1,15 @@ +var assert = require('assert'); + +var Bootstrap = require('./support/bootstrap'); +var Manager = require('../lib/manager'); + +describe('Manager', function() { + describe('.plugin', function() { + it('should instantiate and return a new Manager instance', function() { + var bookshelf = Bootstrap.database(); + bookshelf.plugin(Manager.plugin); + var manager = bookshelf.manager; + assert.equal(manager.bookshelf, bookshelf); + }); + }); +}); diff --git a/test/manager.register.js b/test/manager.register.js new file mode 100644 index 0000000..d8bbc6a --- /dev/null +++ b/test/manager.register.js @@ -0,0 +1,52 @@ +var assert = require('assert'); +var Bootstrap = require('./support/bootstrap'); +var Manager = require('../lib/manager'); + +describe('manager', function() { + + var manager; + var Model; + + beforeEach(function() { + manager = new Manager(Bootstrap.database()); + + Model = function(Bookshelf) { + return Bookshelf.Model.extend({ + table: 'fake' + }); + }; + }); + + describe('.register', function() { + it('should return function', function() { + assert.equal('function', typeof manager.register(Model, 'fake')); + }); + + it('must be called with both a Model and a model name', function() { + assert.throws(function() { + return manager.register(); + }, /Manager.register must be called with a model and a model name/); + + assert.throws(function() { + return manager.register(Model); + }, /Manager.register must be called with a model and a model name/); + + assert.throws(function() { + return manager.register('fake'); + }, /Manager.register must be called with a model and a model name/); + }); + + it('should register the model in the Bookshelf registry', function() { + manager.register(Model, 'fake'); + assert.ok(manager.bookshelf.model('fake').prototype instanceof manager.bookshelf.Model); + }); + + it('should not allow re-registering the same model name', function() { + manager.register(Model, 'fake'); + assert.throws(function() { + return manager.register(Model, 'fake'); + }, /fake is already defined in the registry/); + }); + + }); +}); diff --git a/test/manager.save.js b/test/manager.save.js index 7458149..7860dd4 100644 --- a/test/manager.save.js +++ b/test/manager.save.js @@ -1,19 +1,18 @@ var assert = require('assert'); -var Promise = require('bluebird'); var deep = require('deep-diff'); var Bootstrap = require('./support/bootstrap'); -var manager = require('./support/manager'); describe('manager', function() { describe('.save', function() { - before(function(done) { - Bootstrap.database().then(function() { - return Bootstrap.tables(); - }).then(function() { - return Bootstrap.fixtures(); - }).then(function() { - done(); + var manager; + + before(function() { + manager = Bootstrap.manager(Bootstrap.database()); + Bootstrap.models(manager); + return Bootstrap.tables(manager) + .then(function() { + return Bootstrap.fixtures(manager); }); }); @@ -24,25 +23,24 @@ describe('manager', function() { assert.ok(promise.then instanceof Function, 'Expected Function. `then` is ' + typeof promise.then); }); - it('should save a new model', function(done) { + it('should save a new model', function() { var car = manager.forge('car'); - manager.save(car).then(function(car) { + return manager.save(car).then(function(car) { assert.equal(3, car.id, 'Car should have an ID of 3, not ' + car.id); - done(); }); }); - it('should save an existing model with same ID', function(done) { + it('should save an existing model with same ID', function() { var Make = manager.get('make'); var original = new Make({ - name: 'Ford', + name: 'Ford' }); - manager.save(original).then(function() { + return manager.save(original).then(function() { return manager.save(new Make(), { id: original.id, - name: 'Chevy', + name: 'Chevy' }); }).then(function(make) { assert.equal(original.id, make.id, 'Should have overriden original model ID'); @@ -50,47 +48,44 @@ describe('manager', function() { return manager.fetch('makes'); }).then(function(makes) { assert.equal(2, makes.length, 'Should only have 2 makes, not ' + makes.length); - done(); }); }); - it('should modify the model', function(done) { - manager.fetch('car', { id: 1 }).then(function(car) { + it('should modify the model', function() { + return manager.fetch('car', { id: 1 }).then(function(car) { assert.equal(1, car.get('quantity'), 'Car #1 should start with quantity of 1'); return manager.save(car, { - quantity: 2, + quantity: 2 }); }).then(function(car) { assert.equal(2, car.get('quantity'), 'Car #1 should end with quantity of 2'); - done(); }); }); - it('should modify a nested model', function(done) { - manager.fetch('car', { id: 1 }, 'color').then(function(car) { + it('should modify a nested model', function() { + return manager.fetch('car', { id: 1 }, 'color').then(function(car) { assert.equal(1, car.related('color').id); assert.equal('Grey', car.related('color').get('name')); return manager.save(car, { color: { id: 1, - name: 'Dark Grey', + name: 'Dark Grey' } }); }).then(function(car) { return car.fetch({ - withRelated: 'color', + withRelated: 'color' }); }).then(function(car) { assert.equal(1, car.related('color').id); assert.equal('Dark Grey', car.related('color').get('name')); - done(); }); }); - it('should modify a deep nested model', function(done) { - manager.fetch('car', { id: 1 }, 'model.type').then(function(car) { + it('should modify a deep nested model', function() { + return manager.fetch('car', { id: 1 }, 'model.type').then(function(car) { assert.equal('Crossover', car.related('model').related('type').get('name')); return manager.save(car, { @@ -104,16 +99,15 @@ describe('manager', function() { }); }).then(function(car) { return car.fetch({ - withRelated: 'model.type', + withRelated: 'model.type' }); }).then(function(car) { assert.equal('SUV', car.related('model').related('type').get('name')); - done(); }); }); - it('should ignore _pivot_ keys', function(done) { - manager.fetch('car', { id: 1 }, 'features').then(function(car) { + it('should ignore _pivot_ keys', function() { + return manager.fetch('car', { id: 1 }, 'features').then(function(car) { var feature = car.related('features').at(0); var json = feature.toJSON(); @@ -122,12 +116,11 @@ describe('manager', function() { return manager.save(feature, json); }).then(function(feature) { assert.equal('GPSv2', feature.get('name')); - done(); }); }); - it('should orphan models in collection', function(done) { - manager.fetch('car', { id: 1 }, 'features').then(function(car) { + it('should orphan models in collection', function() { + return manager.fetch('car', { id: 1 }, 'features').then(function(car) { assert.equal(2, car.related('features').length, 'Car should have 2 existing features'); return manager.save(car, { @@ -135,15 +128,14 @@ describe('manager', function() { features: [] }).then(function(car) { assert.equal(0, car.related('features').length, 'Car should have all features removed, found: ' + car.related('features').toJSON()); - done(); }); }); }); - it('should support original fetched response', function(done) { + it('should support original fetched response', function() { var expected; - manager + return manager .fetch('make', { name: 'BMW' }, [ 'models', 'models.specs', @@ -153,7 +145,7 @@ describe('manager', function() { 'dealers.cars.color', 'dealers.cars.model', 'dealers.cars.features', - 'dealers.cars.model.type', + 'dealers.cars.model.type' ]).then(function(make) { expected = make.toJSON(); @@ -166,9 +158,7 @@ describe('manager', function() { return manager.knex('models_specs').select(); }).then(function(results) { assert.equal(2, results.length, 'Expected only 2 rows in `models_specs`, not ' + results.length); - done(); - }) - ; - }) + }); + }); }); }); diff --git a/test/models/car.js b/test/models/car.js index 67b9efe..a2dde46 100644 --- a/test/models/car.js +++ b/test/models/car.js @@ -1,11 +1,9 @@ -var Manager = require('../../lib/manager'); - -var Car = Manager.manage(function(Bookshelf) { +var Car = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'cars', defaults: { - quantity: 0, + quantity: 0 }, color: function() { @@ -22,8 +20,8 @@ var Car = Manager.manage(function(Bookshelf) { features: function() { return this.belongsToMany('feature'); - }, + } }); -}); +}; module.exports = Car; diff --git a/test/models/cars.js b/test/models/cars.js index 2834eec..22f4bf4 100644 --- a/test/models/cars.js +++ b/test/models/cars.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Cars = Manager.manage(function(Bookshelf) { +var Cars = function(Bookshelf) { return Bookshelf.Collection.extend({ - model: 'car', + model: 'car' }); -}); +}; module.exports = Cars; diff --git a/test/models/color.js b/test/models/color.js index 691d8bf..989ec23 100644 --- a/test/models/color.js +++ b/test/models/color.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Color = Manager.manage(function(Bookshelf) { +var Color = function(Bookshelf) { return Bookshelf.Model.extend({ - tableName: 'colors', + tableName: 'colors' }); -}); +}; module.exports = Color; diff --git a/test/models/dealer.js b/test/models/dealer.js index b4de160..e19eac9 100644 --- a/test/models/dealer.js +++ b/test/models/dealer.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Dealer = Manager.manage(function(Bookshelf) { +var Dealer = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'dealers', @@ -12,6 +10,6 @@ var Dealer = Manager.manage(function(Bookshelf) { return this.hasMany('car', 'dealer_id'); } }); -}); +}; module.exports = Dealer; diff --git a/test/models/feature.js b/test/models/feature.js index b757df2..533cd63 100644 --- a/test/models/feature.js +++ b/test/models/feature.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Feature = Manager.manage(function(Bookshelf) { +var Feature = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'features', @@ -8,6 +6,6 @@ var Feature = Manager.manage(function(Bookshelf) { return this.belongsToMany('car'); } }); -}); +}; module.exports = Feature; diff --git a/test/models/features.js b/test/models/features.js index 8f56ac0..e3d37d8 100644 --- a/test/models/features.js +++ b/test/models/features.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Features = Manager.manage(function(Bookshelf) { +var Features = function(Bookshelf) { return Bookshelf.Collection.extend({ - model: 'feature', + model: 'feature' }); -}); +}; module.exports = Features; diff --git a/test/models/make.js b/test/models/make.js index faa152f..993914d 100644 --- a/test/models/make.js +++ b/test/models/make.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Make = Manager.manage(function(Bookshelf) { +var Make = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'makes', @@ -10,8 +8,8 @@ var Make = Manager.manage(function(Bookshelf) { dealers: function() { return this.hasMany('dealer', 'make_id'); - }, + } }); -}); +}; module.exports = Make; diff --git a/test/models/makes.js b/test/models/makes.js index 5cfca7c..7f74f11 100644 --- a/test/models/makes.js +++ b/test/models/makes.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Makes = Manager.manage(function(Bookshelf) { +var Makes = function(Bookshelf) { return Bookshelf.Collection.extend({ model: 'make' }); -}); +}; module.exports = Makes; diff --git a/test/models/model.js b/test/models/model.js index 23d1ec5..675a837 100644 --- a/test/models/model.js +++ b/test/models/model.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Model = Manager.manage(function(Bookshelf) { +var Model = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'models', @@ -16,6 +14,6 @@ var Model = Manager.manage(function(Bookshelf) { return this.belongsTo('type'); } }); -}); +}; module.exports = Model; diff --git a/test/models/models.js b/test/models/models.js index f78f818..473e8ab 100644 --- a/test/models/models.js +++ b/test/models/models.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Test = Manager.manage(function(Bookshelf) { +var Models = function(Bookshelf) { return Bookshelf.Collection.extend({ model: 'model' }); -}); +}; module.exports = Models; diff --git a/test/models/spec.js b/test/models/spec.js index 4a3c50f..16094df 100644 --- a/test/models/spec.js +++ b/test/models/spec.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Spec = Manager.manage(function(Bookshelf) { +var Spec = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'specs', @@ -8,6 +6,6 @@ var Spec = Manager.manage(function(Bookshelf) { return this.belongsToMany('model'); } }); -}); +}; module.exports = Spec; diff --git a/test/models/specs.js b/test/models/specs.js index 1f640d8..33b1a19 100644 --- a/test/models/specs.js +++ b/test/models/specs.js @@ -1,9 +1,7 @@ -var Manager = require('../../lib/manager'); - -var Specs = Manager.manage(function(Bookshelf) { +var Specs = function(Bookshelf) { return Bookshelf.Collection.extend({ model: 'spec' }); -}); +}; module.exports = Specs; diff --git a/test/models/type.js b/test/models/type.js index 1e2dff9..f137c09 100644 --- a/test/models/type.js +++ b/test/models/type.js @@ -1,6 +1,4 @@ -var Manager = require('../../lib/manager'); - -var Type = Manager.manage(function(Bookshelf) { +var Type = function(Bookshelf) { return Bookshelf.Model.extend({ tableName: 'types', @@ -8,6 +6,6 @@ var Type = Manager.manage(function(Bookshelf) { return this.belongsTo('model'); } }); -}); +}; module.exports = Type; diff --git a/test/support/bootstrap.database.js b/test/support/bootstrap.database.js index 1e8a209..1ff4cb6 100644 --- a/test/support/bootstrap.database.js +++ b/test/support/bootstrap.database.js @@ -1,9 +1,11 @@ -var MySql = require('../databases/mysql'); +var Bookshelf = require('bookshelf'); +var Knex = require('knex'); module.exports = function() { - return MySql.knex.raw('DROP DATABASE IF EXISTS bookshelf_manager_test') - .then(function() { - return MySql.knex.raw('CREATE DATABASE bookshelf_manager_test') - }) - ; + return Bookshelf(Knex({ + client: 'sqlite3', + connection: { + filename: ':memory:' + } + })); }; diff --git a/test/support/bootstrap.fixtures.js b/test/support/bootstrap.fixtures.js index 0f653b9..ceeb7b7 100644 --- a/test/support/bootstrap.fixtures.js +++ b/test/support/bootstrap.fixtures.js @@ -1,11 +1,11 @@ var Promise = require('bluebird'); -var manager = require('./manager'); -module.exports = function() { +module.exports = function(manager) { + var make = manager.forge('make', { name: 'BMW' }); var model = manager.forge('model', { name: 'X5', cost: '50000.00' }); var type = manager.forge('type', { name: 'Crossover' }); - var specs = manager.forge('specs', [ { name: '4 door'}, { name: 'v6' } ]); + var specs = manager.forge('specs', [ { name: '4 door' }, { name: 'v6' } ]); var color = manager.forge('color', { name: 'Grey', hex_value: '#666' }); var dealer = manager.forge('dealer', { name: 'Houston', zip_code: '77002' }); var features = manager.forge('features', [ { name: 'GPS', cost: '500' }, { name: 'ABS', cost: '1250' }]); diff --git a/test/support/bootstrap.js b/test/support/bootstrap.js index 44b3a8c..5104a86 100644 --- a/test/support/bootstrap.js +++ b/test/support/bootstrap.js @@ -1,9 +1,9 @@ -var Promise = require('bluebird'); - var Bootstrap = { database: require('./bootstrap.database'), + manager: require('./bootstrap.manager'), + models: require('./bootstrap.models'), fixtures: require('./bootstrap.fixtures'), - tables: require('./bootstrap.tables'), + tables: require('./bootstrap.tables') }; module.exports = Bootstrap; diff --git a/test/support/bootstrap.manager.js b/test/support/bootstrap.manager.js new file mode 100644 index 0000000..bb22b6c --- /dev/null +++ b/test/support/bootstrap.manager.js @@ -0,0 +1,8 @@ +var path = require('path'); +var Manager = require('../../lib/manager'); + +module.exports = function(bookshelf) { + return new Manager(bookshelf, { + root: path.join(__dirname, '..', 'models') + }); +}; diff --git a/test/support/bootstrap.models.js b/test/support/bootstrap.models.js new file mode 100644 index 0000000..8834da9 --- /dev/null +++ b/test/support/bootstrap.models.js @@ -0,0 +1,13 @@ +var path = require('path'); +var fs = require('fs'); + +module.exports = function(manager) { + var sourceFolder = path.join(process.cwd(), '/test/models'); + var files = fs.readdirSync(sourceFolder); + + files.forEach(function(file) { + var model = require(path.join(sourceFolder, file)); + var modelId = path.basename(file, path.extname(file)); + manager.register(model, modelId); + }); +}; diff --git a/test/support/bootstrap.tables.js b/test/support/bootstrap.tables.js index b57c9c6..3b3c5ec 100644 --- a/test/support/bootstrap.tables.js +++ b/test/support/bootstrap.tables.js @@ -1,68 +1,76 @@ -var Promise = require('bluebird'); -var manager = require('./manager'); +module.exports = function(manager) { -module.exports = function() { - return Promise.all([ - manager.schema.createTable('cars', function(table) { + return manager.knex.transaction(function(trx) { + var schema = trx.schema; + return schema.createTableIfNotExists('cars', function(table) { table.increments('id'); table.integer('color_id'); table.integer('dealer_id'); table.integer('model_id'); table.integer('quantity'); - }), - - manager.schema.createTable('cars_features', function(table) { - table.increments('id'); - table.integer('car_id'); - table.integer('feature_id'); - }), - - manager.schema.createTable('colors', function(table) { - table.increments('id'); - table.string('name'); - table.string('hex_value'); - }), - - manager.schema.createTable('dealers', function(table) { - table.increments('id'); - table.integer('make_id'); - table.string('name'); - table.string('zip_code'); - }), - - manager.schema.createTable('features', function(table) { - table.increments('id'); - table.string('name'); - table.decimal('cost'); - }), - - manager.schema.createTable('makes', function(table) { - table.increments('id'); - table.string('name'); - }), - - manager.schema.createTable('models', function(table) { - table.increments('id'); - table.integer('make_id'); - table.integer('type_id'); - table.string('name'); - table.decimal('cost'); - }), - - manager.schema.createTable('models_specs', function(table) { - table.increments('id'); - table.integer('model_id'); - table.integer('spec_id'); - }), - - manager.schema.createTable('specs', function(table) { - table.increments('id'); - table.string('name'); - }), - - manager.schema.createTable('types', function(table) { - table.increments('id'); - table.string('name'); - }), - ]); + }) + .then(function() { + return schema.createTableIfNotExists('cars_features', function(table) { + table.increments('id'); + table.integer('car_id'); + table.integer('feature_id'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('colors', function(table) { + table.increments('id'); + table.string('name'); + table.string('hex_value'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('dealers', function(table) { + table.increments('id'); + table.integer('make_id'); + table.string('name'); + table.string('zip_code'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('features', function(table) { + table.increments('id'); + table.string('name'); + table.decimal('cost'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('makes', function(table) { + table.increments('id'); + table.string('name'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('models', function(table) { + table.increments('id'); + table.integer('make_id'); + table.integer('type_id'); + table.string('name'); + table.decimal('cost'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('models_specs', function(table) { + table.increments('id'); + table.integer('model_id'); + table.integer('spec_id'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('specs', function(table) { + table.increments('id'); + table.string('name'); + }); + }) + .then(function() { + return schema.createTableIfNotExists('types', function(table) { + table.increments('id'); + table.string('name'); + }); + }); + }); }; diff --git a/test/support/manager.js b/test/support/manager.js deleted file mode 100644 index a707cea..0000000 --- a/test/support/manager.js +++ /dev/null @@ -1,6 +0,0 @@ -var path = require('path'); - -var Manager = require('../../lib/manager'); -var Test = require('../databases/test'); - -module.exports = new Manager(path.join(__dirname, '..', 'models'), Test);