不要怂,就是干,撸起袖子干!

Commit 89c96808 by Daniel Durante

Cleaned up buster specs, should do a lot less connections per spec now for those…

… MySQL users, cleaned up bits and pieces of code within lib/ as well.
1 parent 194a42c2
...@@ -82,7 +82,9 @@ module.exports = (function() { ...@@ -82,7 +82,9 @@ module.exports = (function() {
read: Pooling.Pool({ read: Pooling.Pool({
name: 'sequelize-read', name: 'sequelize-read',
create: function (done) { create: function (done) {
if (reads >= self.config.replication.read.length) reads = 0; if (reads >= self.config.replication.read.length) {
reads = 0
}
var config = self.config.replication.read[reads++]; var config = self.config.replication.read[reads++];
connect.call(self, function (err, connection) { connect.call(self, function (err, connection) {
...@@ -168,11 +170,12 @@ module.exports = (function() { ...@@ -168,11 +170,12 @@ module.exports = (function() {
query.done(function() { query.done(function() {
self.pendingQueries--; self.pendingQueries--;
if (self.pool) self.pool.release(query.client); if (self.pool) {
else { self.pool.release(query.client);
} else {
if (self.pendingQueries === 0) { if (self.pendingQueries === 0) {
setTimeout(function() { setTimeout(function() {
self.pendingQueries === 0 && self.disconnect.call(self); self.pendingQueries === 0 && self.disconnect.call(self)
}, 100); }, 100);
} }
} }
...@@ -180,16 +183,16 @@ module.exports = (function() { ...@@ -180,16 +183,16 @@ module.exports = (function() {
if (!this.pool) { if (!this.pool) {
query.run(sql); query.run(sql);
} } else {
else {
this.pool.acquire(function(err, client) { this.pool.acquire(function(err, client) {
if (err) return query.emit('error', err); if (err) {
return query.emit('error', err)
}
query.client = client; query.client = client
query.run(sql); query.run(sql)
return; return;
}, undefined, options.type); }, undefined, options.type)
} }
return query; return query;
...@@ -209,8 +212,10 @@ module.exports = (function() { ...@@ -209,8 +212,10 @@ module.exports = (function() {
}; };
ConnectorManager.prototype.disconnect = function() { ConnectorManager.prototype.disconnect = function() {
if (this.client) disconnect.call(this, this.client); if (this.client) {
return; disconnect.call(this, this.client)
}
return
}; };
...@@ -265,12 +270,12 @@ module.exports = (function() { ...@@ -265,12 +270,12 @@ module.exports = (function() {
switch(err.code) { switch(err.code) {
case 'ECONNREFUSED': case 'ECONNREFUSED':
case 'ER_ACCESS_DENIED_ERROR': case 'ER_ACCESS_DENIED_ERROR':
emitter.emit('error', new Error("Failed to authenticate for MySQL. Please double check your settings.")) emitter.emit('error', 'Failed to authenticate for MySQL. Please double check your settings.')
break break
case 'ENOTFOUND': case 'ENOTFOUND':
case 'EHOSTUNREACH': case 'EHOSTUNREACH':
case 'EINVAL': case 'EINVAL':
emitter.emit('error', new Error("Failed to find MySQL server. Please double check your settings.")) emitter.emit('error', 'Failed to find MySQL server. Please double check your settings.')
break break
} }
} }
...@@ -295,7 +300,7 @@ module.exports = (function() { ...@@ -295,7 +300,7 @@ module.exports = (function() {
} }
var validateConnection = function(client) { var validateConnection = function(client) {
return client && client.state != 'disconnected' return client && client.state !== 'disconnected'
} }
var enqueue = function(queueItem, options) { var enqueue = function(queueItem, options) {
...@@ -342,8 +347,6 @@ module.exports = (function() { ...@@ -342,8 +347,6 @@ module.exports = (function() {
} }
var afterQuery = function(queueItem) { var afterQuery = function(queueItem) {
var self = this
dequeue.call(this, queueItem) dequeue.call(this, queueItem)
transferQueuedItems.call(this, this.maxConcurrentQueries - this.activeQueue.length) transferQueuedItems.call(this, this.maxConcurrentQueries - this.activeQueue.length)
disconnectIfNoConnections.call(this) disconnectIfNoConnections.call(this)
......
...@@ -77,12 +77,12 @@ module.exports = (function() { ...@@ -77,12 +77,12 @@ module.exports = (function() {
if (!!err) { if (!!err) {
switch(err.code) { switch(err.code) {
case 'ECONNREFUSED': case 'ECONNREFUSED':
emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings.")) emitter.emit('error', 'Failed to authenticate for PostgresSQL. Please double check your settings.')
break break
case 'ENOTFOUND': case 'ENOTFOUND':
case 'EHOSTUNREACH': case 'EHOSTUNREACH':
case 'EINVAL': case 'EINVAL':
emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings.")) emitter.emit('error', 'Failed to find PostgresSQL server. Please double check your settings.')
break break
default: default:
emitter.emit('error', err) emitter.emit('error', err)
......
...@@ -22,7 +22,7 @@ module.exports = (function() { ...@@ -22,7 +22,7 @@ module.exports = (function() {
this.database = db = new sqlite3.Database(self.sequelize.options.storage || ':memory:', function(err) { this.database = db = new sqlite3.Database(self.sequelize.options.storage || ':memory:', function(err) {
if (err) { if (err) {
if (err.code === "SQLITE_CANTOPEN") { if (err.code === "SQLITE_CANTOPEN") {
emitter.emit('error', new Error("Failed to find SQL server. Please double check your settings.")) emitter.emit('error', 'Failed to find SQL server. Please double check your settings.')
} }
} }
......
const fs = require("fs") const fs = require("fs")
, moment = require("moment") , moment = require("moment")
var Utils = require("./utils") var Utils = require(__dirname + "/utils")
, Migration = require("./migration") , Migration = require(__dirname + "/migration")
, DataTypes = require("./data-types") , DataTypes = require(__dirname + "/data-types")
module.exports = (function() { module.exports = (function() {
var Migrator = function(sequelize, options) { var Migrator = function(sequelize, options) {
...@@ -45,7 +45,7 @@ module.exports = (function() { ...@@ -45,7 +45,7 @@ module.exports = (function() {
if (err) { if (err) {
emitter.emit('error', err) emitter.emit('error', err)
} else { } else {
var chainer = new Utils.QueryChainer var chainer = new Utils.QueryChainer()
, from = migrations[0] , from = migrations[0]
if (options.method === 'down') { if (options.method === 'down') {
...@@ -188,7 +188,7 @@ module.exports = (function() { ...@@ -188,7 +188,7 @@ module.exports = (function() {
var self = this; var self = this;
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer; var chainer = new Utils.QueryChainer()
var addMigration = function(filename) { var addMigration = function(filename) {
self.options.logging('Adding migration script at ' + filename) self.options.logging('Adding migration script at ' + filename)
var migration = new Migration(self, filename) var migration = new Migration(self, filename)
......
var Utils = require("./utils") var Utils = require(__dirname + "/utils")
module.exports = (function() { module.exports = (function() {
var QueryChainer = function(emitters) { var QueryChainer = function(emitters) {
......
var Utils = require('./utils') var Utils = require(__dirname + '/utils')
, DataTypes = require('./data-types') , DataTypes = require(__dirname + '/data-types')
, SQLiteQueryInterface = require('./dialects/sqlite/query-interface') , SQLiteQueryInterface = require(__dirname + '/dialects/sqlite/query-interface')
module.exports = (function() { module.exports = (function() {
var QueryInterface = function(sequelize) { var QueryInterface = function(sequelize) {
......
...@@ -380,6 +380,6 @@ var Utils = module.exports = { ...@@ -380,6 +380,6 @@ var Utils = module.exports = {
} }
} }
Utils.CustomEventEmitter = require("./emitters/custom-event-emitter") Utils.CustomEventEmitter = require(__dirname + "/emitters/custom-event-emitter")
Utils.QueryChainer = require("./query-chainer") Utils.QueryChainer = require(__dirname + "/query-chainer")
Utils.Lingo = require("lingo") Utils.Lingo = require("lingo")
/* jshint camelcase: false */ /* jshint camelcase: false */
if (typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , Sequelize = require('../../index')
, Sequelize = require('../../index') , DataTypes = require(__dirname + "/../../lib/data-types")
, dialect = Helpers.getTestDialect() , dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 500 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
before(function(done) { before(function(done) {
Helpers.initTests({ this.sequelize = sequelize
dialect: dialect, Helpers.clearDatabase(this.sequelize, done)
beforeComplete: function(sequelize) {
this.sequelize = sequelize
}.bind(this),
onComplete: done
})
}) })
describe('general usage', function() { describe('general usage', function() {
before(function(done) { before(function(done) {
this.User = this.sequelize.define('User', { var self = this
username: Helpers.Sequelize.STRING, self.User = this.sequelize.define('User', {
username: DataTypes.STRING,
enabled: { enabled: {
type: Helpers.Sequelize.BOOLEAN, type: Helpers.Sequelize.BOOLEAN,
defaultValue: true defaultValue: true
} }
}) })
this.Task = this.sequelize.define('Task', {
title: Helpers.Sequelize.STRING self.Task = this.sequelize.define('Task', {
title: DataTypes.STRING
}) })
this.sequelize.sync({ force: true }).success(done) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
}) })
it('adds the foreign key', function(done) { it('adds the foreign key', function(done) {
...@@ -44,6 +44,7 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -44,6 +44,7 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
it("underscores the foreign key", function(done) { it("underscores the foreign key", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }, {underscored: true}) var Task = this.sequelize.define('Task', { title: Sequelize.STRING }, {underscored: true})
Task.belongsTo(this.User) Task.belongsTo(this.User)
expect(Task.attributes.user_id).toEqual("INTEGER") expect(Task.attributes.user_id).toEqual("INTEGER")
done() done()
...@@ -97,13 +98,15 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -97,13 +98,15 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
var self = this var self = this
this.Task.belongsTo(this.User, {as: 'User'}) this.Task.belongsTo(this.User, {as: 'User'})
this.sequelize.sync({ force: true }).success(function() { self.User.sync({ force: true }).success(function() {
self.User.create({username: 'asd'}).success(function(u) { self.Task.sync({ force: true }).success(function() {
self.Task.create({title: 'a task'}).success(function(t) { self.User.create({username: 'asd'}).success(function(u) {
t.setUser(u).success(function() { self.Task.create({title: 'a task'}).success(function(t) {
t.getUser().success(function(user) { t.setUser(u).success(function() {
expect(user.username).toEqual('asd') t.getUser().success(function(user) {
done() expect(user.username).toEqual('asd')
done()
})
}) })
}) })
}) })
...@@ -115,13 +118,15 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -115,13 +118,15 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
var self = this var self = this
this.Task.belongsTo(this.User, {as: 'User'}) this.Task.belongsTo(this.User, {as: 'User'})
this.sequelize.sync({ force: true }).success(function() { self.User.sync({ force: true }).success(function() {
self.User.create({username: 'asd', enabled: false}).success(function(u) { self.Task.sync({ force: true }).success(function() {
self.Task.create({title: 'a task'}).success(function(t) { self.User.create({username: 'asd', enabled: false}).success(function(u) {
t.setUser(u).success(function() { self.Task.create({title: 'a task'}).success(function(t) {
t.getUser({where: {enabled: true}}).success(function(user) { t.setUser(u).success(function() {
expect(user).toEqual(null) t.getUser({where: {enabled: true}}).success(function(user) {
done() expect(user).toEqual(null)
done()
})
}) })
}) })
}) })
...@@ -158,20 +163,20 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -158,20 +163,20 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
Task.belongsTo(User) Task.belongsTo(User)
this.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { Task.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) { User.create({ username: 'foo' }).success(function(user) {
task.setUserXYZ(user).success(function() { Task.create({ title: 'task' }).success(function(task) {
task.getUserXYZ().success(function(user) { task.setUserXYZ(user).success(function() {
expect(user).not.toEqual(null) task.getUserXYZ().success(function(user) {
expect(user).not.toEqual(null)
task.setUserXYZ(null).success(function() { task.setUserXYZ(null).success(function() {
task.getUserXYZ().success(function(user) { task.getUserXYZ().success(function(user) {
expect(user).toEqual(null) expect(user).toEqual(null)
done() done()
})
}) })
}) })
}) })
}) })
}) })
...@@ -181,20 +186,26 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -181,20 +186,26 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
describe("Foreign key constraints", function() { describe("Foreign key constraints", function() {
it("are not enabled by default", function(done) { before(function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) this.Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: Sequelize.STRING }) this.User = this.sequelize.define('User', { username: DataTypes.STRING })
done()
Task.belongsTo(User) })
this.sequelize.sync({ force: true }).success(function() { it("are not enabled by default", function(done) {
User.create({ username: 'foo' }).success(function(user) { var self = this
Task.create({ title: 'task' }).success(function(task) { self.Task.belongsTo(self.User)
task.setUser(user).success(function() {
user.destroy().success(function() { self.User.sync({ force: true }).success(function() {
Task.findAll().success(function(tasks) { self.Task.sync({ force: true }).success(function() {
expect(tasks.length).toEqual(1) self.User.create({ username: 'foo' }).success(function(user) {
done() self.Task.create({ title: 'task' }).success(function(task) {
task.setUser(user).success(function() {
user.destroy().success(function() {
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
}) })
}) })
}) })
...@@ -204,19 +215,19 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -204,19 +215,19 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
it("can cascade deletes", function(done) { it("can cascade deletes", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.Task.belongsTo(self.User, {onDelete: 'cascade'})
Task.belongsTo(User, {onDelete: 'cascade'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { task.setUser(user).success(function() {
task.setUser(user).success(function() { user.destroy().success(function() {
user.destroy().success(function() { self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(0)
expect(tasks.length).toEqual(0) done()
done() })
}) })
}) })
}) })
...@@ -226,20 +237,20 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -226,20 +237,20 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
it("can restrict deletes", function(done) { it("can restrict deletes", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.Task.belongsTo(self.User, {onDelete: 'restrict'})
Task.belongsTo(User, {onDelete: 'restrict'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { task.setUser(user).success(function() {
task.setUser(user).success(function() { user.destroy().error(function() {
user.destroy().error(function() { // Should fail due to FK restriction
// Should fail due to FK restriction self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) done()
done() })
}) })
}) })
}) })
...@@ -249,27 +260,27 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -249,27 +260,27 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
it("can cascade updates", function(done) { it("can cascade updates", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.Task.belongsTo(self.User, {onUpdate: 'cascade'})
Task.belongsTo(User, {onUpdate: 'cascade'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { task.setUser(user).success(function() {
task.setUser(user).success(function() {
// Changing the id of a DAO requires a little dance since
// Changing the id of a DAO requires a little dance since // the `UPDATE` query generated by `save()` uses `id` in the
// the `UPDATE` query generated by `save()` uses `id` in the // `WHERE` clause
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) .success(function() {
.success(function() { self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) expect(tasks[0].UserId).toEqual(999)
expect(tasks[0].UserId).toEqual(999) done()
done() })
}) })
}) })
}) })
...@@ -279,27 +290,27 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -279,27 +290,27 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
it("can restrict updates", function(done) { it("can restrict updates", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.Task.belongsTo(self.User, {onUpdate: 'restrict'})
Task.belongsTo(User, {onUpdate: 'restrict'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { task.setUser(user).success(function() {
task.setUser(user).success(function() {
// Changing the id of a DAO requires a little dance since
// Changing the id of a DAO requires a little dance since // the `UPDATE` query generated by `save()` uses `id` in the
// the `UPDATE` query generated by `save()` uses `id` in the // `WHERE` clause
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) .error(function() {
.error(function() { // Should fail due to FK restriction
// Should fail due to FK restriction self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) done()
done() })
}) })
}) })
}) })
...@@ -311,8 +322,8 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -311,8 +322,8 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
describe("Association options", function() { describe("Association options", function() {
it('can specify data type for autogenerated relational keys', function(done) { it('can specify data type for autogenerated relational keys', function(done) {
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, dataTypes = [Sequelize.INTEGER, Sequelize.BIGINT, Sequelize.STRING] , dataTypes = [DataTypes.INTEGER, DataTypes.BIGINT, DataTypes.STRING]
, self = this , self = this
dataTypes.forEach(function(dataType) { dataTypes.forEach(function(dataType) {
...@@ -321,7 +332,7 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -321,7 +332,7 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
Task.belongsTo(User, { foreignKey: 'userId', keyType: dataType }) Task.belongsTo(User, { foreignKey: 'userId', keyType: dataType })
self.sequelize.sync({ force: true }).success(function() { Task.sync({ force: true }).success(function() {
expect(Task.rawAttributes.userId.type.toString()) expect(Task.rawAttributes.userId.type.toString())
.toEqual(dataType.toString()) .toEqual(dataType.toString())
...@@ -333,5 +344,4 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() { ...@@ -333,5 +344,4 @@ describe(Helpers.getTestDialectTeaser("BelongsTo"), function() {
}) })
}) })
}) })
}) })
/* jshint camelcase: false */
var buster = require("buster")
, Helpers = require('../buster-helpers')
, Sequelize = require('../../index')
, dialect = Helpers.getTestDialect()
, _ = require('lodash')
, moment = require('moment')
, DataTypes = require(__dirname + "/../../lib/data-types")
buster.spec.expose()
buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
describe(Helpers.getTestDialectTeaser("HasMany"), function() {
before(function(done) {
this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
})
describe('general usage', function() {
before(function(done) {
this.User = this.sequelize.define('User', { username: DataTypes.STRING })
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING })
var self = this
this.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
})
describe('mono-directional', function() {
it("adds the foreign key", function(done) {
this.User.hasMany(this.Task)
expect(this.Task.attributes.UserId).toEqual("INTEGER")
done()
})
it('adds the foreign key with underscore', function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING }, { underscored: true })
Task.hasMany(User)
expect(User.attributes.task_id).toBeDefined()
done()
})
it('uses the passed foreign key', function(done) {
this.User.hasMany(this.Task, { foreignKey: 'person_id' })
expect(this.Task.attributes.person_id).toEqual("INTEGER")
done()
})
it('defines getters and setters', function(done) {
this.User.hasMany(this.Task)
var u = this.User.build({username: 'asd'})
expect(u.setTasks).toBeDefined()
expect(u.getTasks).toBeDefined()
done()
})
it("defines getters and setters according to the 'as' option", function(done) {
this.User.hasMany(this.Task, {as: 'Tasks'})
var u = this.User.build({username: 'asd'})
expect(u.setTasks).toBeDefined()
expect(u.getTasks).toBeDefined()
done()
})
it("sets and gets associated objects", function(done) {
var self = this
this.User.hasMany(this.Task, { as: 'Tasks' })
this.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({username: 'name'}).success(function(user) {
self.Task.create({title: 'task1'}).success(function(task1) {
self.Task.create({title: 'task2'}).success(function(task2) {
user.setTasks([task1, task2]).success(function() {
user.getTasks().success(function(tasks) {
expect(tasks.length).toEqual(2)
user.getTasks({attributes: ['title']}).success(function(tasks) {
expect(tasks[0].selectedValues.title).toEqual('task1')
expect(tasks[0].selectedValues.id).not.toBeDefined()
done()
})
})
})
})
})
})
})
})
})
})
it("should allow selfAssociation to be single linked (only one DAO is created)", function(done) {
var oldLength = this.sequelize.daoFactoryManager.daos.length
, Comment = this.sequelize.define('Comment', { content: DataTypes.STRING })
Comment.belongsTo(Comment, {as: "Parent"});
Comment.hasMany(Comment, {as: 'Children', foreignKey: "ParentId", useJunctionTable: false})
expect(this.sequelize.daoFactoryManager.daos.length).toEqual(oldLength + 1)
Comment.sync({force: true}).success(function() {
Comment.create({ content: 'parentComment' }).success(function(parent) {
Comment.create({ content: 'child1' }).success(function(child1) {
child1.setParent(parent).success(function() {
Comment.create({ content: 'child2' }).success(function(child2) {
child2.setParent(parent).success(function() {
Comment.find({where: { content: 'parentComment' }}).success(function(parent) {
parent.getChildren().success(function(children) {
expect(children.length).toEqual(2)
done()
})
})
})
})
})
})
})
})
})
it("should still use many to many for selfAssociation by default (two DAOs are created)", function(done) {
var oldLength = this.sequelize.daoFactoryManager.daos.length
, Comment = this.sequelize.define('Comment', { content: Sequelize.STRING })
Comment.belongsTo(Comment, {as: "Parent"})
Comment.hasMany(Comment, {as: 'Children'})
expect(this.sequelize.daoFactoryManager.daos.length).toEqual(oldLength + 2)
done();
})
describe('bi-directional', function() {
it('adds the foreign key', function(done) {
var self = this
this.Task.hasMany(this.User)
this.User.hasMany(this.Task)
expect(this.Task.attributes.UserId).not.toBeDefined()
expect(this.User.attributes.UserId).not.toBeDefined()
var daos = this.sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (self.Task.tableName + self.User.tableName))
})
daos.forEach(function(dao) {
expect(dao.attributes.UserId).toBeDefined()
expect(dao.attributes.TaskId).toBeDefined()
})
done()
})
it("adds the foreign key with underscores", function(done) {
var User = this.sequelize.define('User', { username: Helpers.Sequelize.STRING }, { underscored: true })
, Task = this.sequelize.define('Task', { title: Helpers.Sequelize.STRING })
Task.hasMany(User)
User.hasMany(Task)
expect(Task.attributes.user_id).not.toBeDefined()
expect(User.attributes.user_id).not.toBeDefined()
var daos = this.sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (Task.tableName + User.tableName))
})
daos.forEach(function(dao) {
expect(dao.attributes.user_id).toBeDefined()
expect(dao.attributes.TaskId).toBeDefined()
})
done()
})
it("uses the passed foreign keys", function(done) {
var self = this
this.User.hasMany(this.Task, { foreignKey: 'person_id' })
this.Task.hasMany(this.User, { foreignKey: 'work_item_id' })
var daos = this.sequelize.daoFactoryManager.daos.filter(function(dao) {
return (dao.tableName == (self.Task.tableName + self.User.tableName))
})
daos.forEach(function(dao) {
expect(dao.attributes.person_id).toBeDefined()
expect(dao.attributes.work_item_id).toBeDefined()
})
done()
})
it("defines getters and setters", function(done) {
this.User.hasMany(this.Task)
this.Task.hasMany(this.User)
var u = this.User.build({ username: 'asd' })
expect(u.setTasks).toBeDefined()
expect(u.getTasks).toBeDefined()
var t = this.Task.build({ title: 'foobar' })
expect(t.setUsers).toBeDefined()
expect(t.getUsers).toBeDefined()
done()
})
it("defines getters and setters according to the 'as' option", function(done) {
this.User.hasMany(this.Task, { as: 'Tasks' })
this.Task.hasMany(this.User, { as: 'Users' })
var u = this.User.build({ username: 'asd' })
expect(u.setTasks).toBeDefined()
expect(u.getTasks).toBeDefined()
var t = this.Task.build({ title: 'asd' })
expect(t.setUsers).toBeDefined()
expect(t.getUsers).toBeDefined()
done()
})
it("sets and gets the corrected associated objects", function(done) {
var self = this
var users = []
, tasks = []
this.User.hasMany(this.Task, {as: 'Tasks'})
this.Task.hasMany(this.User, {as: 'Users'})
this.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({username: 'name'}).success(function(user1) {
self.User.create({username: 'name2'}).success(function(user2) {
self.Task.create({title: 'task1'}).success(function(task1) {
self.Task.create({title: 'task2'}).success(function(task2) {
users.push(user1)
users.push(user2)
tasks.push(task1)
tasks.push(task2)
users[0].setTasks(tasks).success(function() {
users[0].getTasks().success(function(_tasks) {
expect(_tasks.length).toEqual(2)
tasks[1].setUsers(users).success(function() {
tasks[1].getUsers().success(function() {
expect(users.length).toEqual(2)
done()
})
})
})
})
})
})
})
})
})
})
})
})
it("build the connector daos name", function(done) {
var self = this
, Person = this.sequelize.define('Person', { name: Helpers.Sequelize.STRING })
Person.hasMany(Person, {as: 'Children'})
Person.hasMany(Person, {as: 'Friends'})
Person.hasMany(Person, {as: 'CoWorkers'})
Person.sync({force: true}).success(function() {
var daoNames = self.sequelize.daoFactoryManager.daos.map(function(dao) { return dao.tableName })
, expectation = ["Persons", "ChildrenPersons", "CoWorkersPersons", "FriendsPersons"]
expectation.forEach(function(ex) {
expect(daoNames.indexOf(ex) > -1).toBeTruthy()
})
done()
})
})
it("allows join table to be specified", function(done) {
var Child = this.sequelize.define('Child', { name: Helpers.Sequelize.STRING }, {underscore: true, freezeTableName: true})
, Parent = this.sequelize.define('Parent', { name: Helpers.Sequelize.STRING }, {underscore: true, freezeTableName: true})
, ParentJoin = this.sequelize.define('ParentRelationship', { parent_id: Helpers.Sequelize.INTEGER, child_id: Helpers.Sequelize.INTEGER }, {underscore: true, freezeTableName: true})
, parents = []
Parent.hasMany(Child, {as: 'Children', foreignKey: 'child_id', joinTableName: 'ParentRelationship'})
Child.hasMany(Parent, {as: 'Parents', foreignKey: 'parent_id', joinTableName: 'ParentRelationship'})
Parent.sync({ force: true }).success(function() {
Child.sync({ force: true }).success(function() {
Parent.create({name: 'mom'}).success(function(mom) {
parents.push(mom)
Parent.create({name: 'dad'}).success(function(dad) {
parents.push(dad)
Child.create({name: 'baby'}).success(function(baby) {
baby.setParents(parents).success(function(){
parents[0].getChildren().success(function(children){
expect(children).not.toBe(null)
expect(children.length).toBeDefined()
expect(children.length).toEqual(1)
expect(children[0]).toBeDefined()
expect(children[0].name).toEqual('baby')
done()
})
})
})
})
})
})
})
})
it("allows join table to be mapped and specified", function(done) {
var User = this.sequelize.define('User', { name: Helpers.Sequelize.STRING }, {underscore: true, freezeTableName: true})
, Company = this.sequelize.define('Company', { name: Helpers.Sequelize.STRING }, {underscore: true, freezeTableName: true})
, CompanyAccess = this.sequelize.define('CompanyAccess', { company_id: Helpers.Sequelize.INTEGER, user_id: Helpers.Sequelize.INTEGER, permission: Helpers.Sequelize.STRING }, {underscore: true, freezeTableName: true})
, companies = []
CompanyAccess.belongsTo(User, {as: 'User', foreignKey: 'user_id'})
CompanyAccess.belongsTo(Company, {as: 'Company', foreignKey: 'company_id'})
User.hasMany(Company, {as: 'Companies', foreignKey: 'user_id', joinTableName: 'CompanyAccess'})
Company.hasMany(User, {as: 'Users', foreignKey: 'company_id', joinTableName: 'CompanyAccess'})
User.sync({ force: true }).success(function() {
Company.sync({ force: true }).success(function() {
CompanyAccess.sync({ force: true }).success(function() {
Company.create({name: 'IBM'}).success(function(ibm) {
companies.push(ibm)
Company.create({name: 'EA'}).success(function(ea) {
companies.push(ea)
User.create({name: 'joe@ibm.com'}).success(function(joe) {
joe.setCompanies(companies).success(function(){
User.find({where: {name: 'joe@ibm.com'}}).success(function(joe) {
expect(joe).not.toEqual(null)
joe.getCompanies().success(function(comps) {
expect(comps).not.toEqual(null)
expect(comps.length).toEqual(2)
done()
})
})
})
})
})
})
})
})
})
})
it("gets and sets the connector daos", function(done) {
var Person = this.sequelize.define('Person', { name: Helpers.Sequelize.STRING })
Person.hasMany(Person, {as: 'Children'})
Person.hasMany(Person, {as: 'Friends'})
Person.hasMany(Person, {as: 'CoWorkers'})
Person.sync({ force: true }).success(function() {
Person.create({name: 'foobar'}).success(function(person) {
Person.create({name: 'friend'}).success(function(friend) {
person.setFriends([friend]).success(function() {
person.getFriends().success(function(friends) {
expect(friends.length).toEqual(1)
expect(friends[0].name).toEqual('friend')
done()
})
})
})
})
})
})
})
describe('(1:N)', function() {
describe('hasSingle', function() {
before(function(done) {
this.Article = this.sequelize.define('Article', {
'title': DataTypes.STRING
})
this.Label = this.sequelize.define('Label', {
'text': DataTypes.STRING
})
this.Article.hasMany(this.Label)
var self = this
this.Article.sync({ force: true }).success(function() {
self.Label.sync({ force: true }).success(done)
})
})
it('does not have any labels assigned to it initially', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
])
chainer.run().success(function(results, article, label1, label2) {
var chainer = new Sequelize.Utils.QueryChainer([
article.hasLabel(label1),
article.hasLabel(label2)
])
chainer.run().success(function(_, hasLabel1, hasLabel2) {
expect(hasLabel1).toBeFalse()
expect(hasLabel2).toBeFalse()
done()
})
})
})
it('answers true if the label has been assigned', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
])
chainer.run().success(function(results, article, label1, label2) {
var chainer = new Sequelize.Utils.QueryChainer([
[ article, 'addLabel', [ label1 ]],
[ article, 'hasLabel', [ label1 ]],
[ article, 'hasLabel', [ label2 ]]
])
chainer.runSerially()
.success(function(_, label1, hasLabel1, hasLabel2) {
expect(hasLabel1).toBeTrue()
expect(hasLabel2).toBeFalse()
done()
})
})
})
})
describe('hasAll', function() {
before(function(done) {
this.Article = this.sequelize.define('Article', {
'title': DataTypes.STRING
})
this.Label = this.sequelize.define('Label', {
'text': DataTypes.STRING
})
this.Article.hasMany(this.Label)
var self = this
this.Article.sync({ force: true }).success(function() {
self.Label.sync({ force: true }).success(done)
})
})
it('answers false if only some labels have been assigned', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
])
chainer.run().success(function(results, article, label1, label2) {
article.addLabel(label1).success(function() {
article.hasLabels([label1, label2]).success(function(result) {
expect(result).toBeFalse()
done()
})
})
})
})
it('answers true if all label have been assigned', function(done) {
var chainer = new Sequelize.Utils.QueryChainer([
this.Article.create({ title: 'Article' }),
this.Label.create({ text: 'Awesomeness' }),
this.Label.create({ text: 'Epicness' })
])
chainer.run().success(function(results, article, label1, label2) {
article.setLabels([label1, label2]).success(function() {
article.hasLabels([label1, label2]).success(function(result) {
expect(result).toBeTrue()
done()
})
})
})
})
})
describe('setAssociations', function() {
it("clears associations when passing null to the set-method", function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
Task.hasMany(User)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) {
task.setUsers([ user ]).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(1)
task.setUsers(null).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(0)
done()
})
})
})
})
})
})
})
})
})
})
it("clears associations when passing null to the set-method with omitNull set to true", function(done) {
this.sequelize.options.omitNull = true
var User = this.sequelize.define('User', { username: Sequelize.STRING })
, Task = this.sequelize.define('Task', { title: Sequelize.STRING })
Task.hasMany(User)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) {
task.setUsers([ user ]).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(1)
task.setUsers(null).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(0)
done()
})
})
})
})
})
})
})
})
})
describe("getting assocations with options", function() {
it('should treat the where object of associations as a first class citizen', function(done) {
var self = this
this.Article = this.sequelize.define('Article', {
'title': DataTypes.STRING
})
this.Label = this.sequelize.define('Label', {
'text': DataTypes.STRING,
'until': DataTypes.DATE
})
this.Article.hasMany(this.Label)
self.Article.sync({ force: true }).success(function() {
self.Label.sync({ force: true }).success(function() {
var chainer = new Sequelize.Utils.QueryChainer([
self.Article.create({ title: 'Article' }),
self.Label.create({ text: 'Awesomeness', until: '2014-01-01 01:00:00' }),
self.Label.create({ text: 'Epicness', until: '2014-01-03 01:00:00' })
])
chainer.run().success(function(results, article, label1, label2) {
article.setLabels([label1, label2]).success(function() {
article.getLabels({where: ['until > ?', moment('2014-01-02').toDate()]}).success(function(labels) {
expect(labels).toBeArray()
expect(labels.length).toEqual(1)
expect(labels[0].text).toEqual('Epicness')
done()
})
})
})
})
})
})
describe("generic options", function() {
before(function(done) {
var self = this
this.User = this.sequelize.define('User', { username: DataTypes.STRING })
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING, active: DataTypes.BOOLEAN })
this.User.hasMany(self.Task)
this.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
var chainer = new Sequelize.Utils.QueryChainer([
self.User.create({ username: 'John'}),
self.Task.create({ title: 'Get rich', active: true}),
self.Task.create({ title: 'Die trying', active: false})
])
chainer.run().success(function (results, john, task1, task2) {
john.setTasks([task1, task2]).success(done)
})
})
})
})
it("gets all associated objects when no options are passed", function(done) {
this.User.find({where: {username: 'John'}}).success(function(john) {
john.getTasks().success(function (tasks) {
expect(tasks.length).toEqual(2)
done()
})
})
})
it("only get objects that fulfill the options", function(done) {
this.User.find({ where: { username: 'John' } }).success(function(john) {
john.getTasks({ where: { active: true }, limit: 10, order: 'id DESC' }).success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
})
})
describe('optimizations using bulk create, destroy and update', function () {
before(function(done) {
var self = this
this.User = this.sequelize.define('User', { username: DataTypes.STRING }, {timestamps: false})
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING }, {timestamps: false})
this.User.hasMany(this.Task)
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
})
it('uses one UPDATE statement', function(done) {
var spy = this.spy()
, self = this
this.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task1' }).success(function(task1) {
self.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).on('sql', spy).on('sql', _.after(2, function(sql) { // We don't care about SELECt, only UPDAET
expect(sql).toMatch("UPDATE")
expect(sql).toMatch("IN (1,2)")
})).success(function () {
expect(spy).toHaveBeenCalledTwice() // Once for SELECT, once for UPDATE
done()
})
})
})
})
})
it('uses one UPDATE statement', function(done) {
var spy = this.spy()
, self = this
this.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task1' }).success(function(task1) {
self.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).success(function () {
user.setTasks(null).on('sql', spy).on('sql', _.after(2, function(sql) { // We don't care about SELECT, only UPDATE
expect(sql).toMatch("UPDATE")
expect(sql).toMatch("IN (1,2)")
})).success(function () {
expect(spy).toHaveBeenCalledTwice() // Once for SELECT, once for UPDATE
done()
})
})
})
})
})
})
})
})
describe('(N:M)', function() {
describe("getting assocations with options", function() {
before(function(done) {
var self = this
this.User = this.sequelize.define('User', { username: DataTypes.STRING })
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING, active: DataTypes.BOOLEAN })
self.User.hasMany(self.Task)
self.Task.hasMany(self.User)
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
var chainer = new Sequelize.Utils.QueryChainer([
self.User.create({ username: 'John'}),
self.Task.create({ title: 'Get rich', active: true}),
self.Task.create({ title: 'Die trying', active: false})
])
chainer.run().success(function(results, john, task1, task2) {
john.setTasks([task1, task2]).success(done)
})
})
})
})
it("gets all associated objects when no options are passed", function(done) {
this.User.find({where: {username: 'John'}}).success(function(john) {
john.getTasks().success(function (tasks) {
expect(tasks.length).toEqual(2)
done()
})
})
})
it("only get objects that fulfill the options", function(done) {
this.User.find({where: {username: 'John'}}).success(function(john) {
john.getTasks({where: {active: true}}).success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
it("only gets objects that fulfill options with a formatted value", function(done) {
this.User.find({where: {username: 'John'}}).success(function(john) {
john.getTasks({where: ['active = ?', true]}).success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
})
it("removes the reference id, which was added in the first place", function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasMany(Task)
expect(Task.attributes.UserId).toBeDefined()
Task.hasMany(User)
expect(Task.attributes.UserId).not.toBeDefined()
done()
})
it("adds three items to the query chainer when calling sync", function(done) {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasMany(Task)
Task.hasMany(User)
var add = this.spy()
this.stub(Sequelize.Utils, 'QueryChainer').returns({ add: add, runSerially: function(){} })
this.sequelize.sync({ force: true })
expect(add).toHaveBeenCalledThrice()
done()
})
describe('setAssociations', function() {
it("clears associations when passing null to the set-method", function(done) {
var User = this.sequelize.define('User', { username: Sequelize.STRING })
, Task = this.sequelize.define('Task', { title: Sequelize.STRING })
User.hasMany(Task)
Task.hasMany(User)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) {
task.setUsers([ user ]).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(1)
task.setUsers(null).success(function() {
task.getUsers().success(function(_users) {
expect(_users.length).toEqual(0)
done()
})
})
})
})
})
})
})
})
})
})
describe('optimizations using bulk create, destroy and update', function () {
before(function (done) {
this.User = this.sequelize.define('User', { username: DataTypes.STRING }, {timestamps: false})
this.Task = this.sequelize.define('Task', { title: DataTypes.STRING }, {timestamps: false})
this.User.hasMany(this.Task)
this.Task.hasMany(this.User)
var self = this
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
})
it('uses one insert into statement', function(done) {
var spy = this.spy()
, self = this
this.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task1' }).success(function(task1) {
self.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).on('sql', spy).on('sql', _.after(2, function(sql) {
expect(sql).toMatch("INSERT INTO")
expect(sql).toMatch("VALUES (1,1),(2,1)")
})).success(function () {
expect(spy).toHaveBeenCalledTwice() // Once for SELECT, once for INSERT into
done()
})
})
})
})
})
it('uses one delete from statement', function(done) {
var spy = this.spy()
, self = this
this.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task1' }).success(function(task1) {
self.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).success(function () {
user.setTasks(null).on('sql', spy).on('sql', _.after(2, function(sql) {
expect(sql).toMatch("DELETE FROM")
expect(sql).toMatch("IN (1,2)")
})).success(function () {
expect(spy).toHaveBeenCalledTwice() // Once for SELECT, once for DELETE
done()
})
})
})
})
})
})
}) // end optimization using bulk create, destroy and update
describe('join table creation', function () {
before(function (done) {
this.User = this.sequelize.define('User',
{ username: DataTypes.STRING },
{ tableName: 'users'}
)
this.Task = this.sequelize.define('Task',
{ title: DataTypes.STRING },
{ tableName: 'tasks' }
)
this.User.hasMany(this.Task,
{ joinTableName: 'user_has_tasks' }
)
this.Task.hasMany(this.User)
var self = this
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
})
it('uses the specified joinTableName or a reasonable default', function(done) {
for (var associationName in this.User.associations) {
expect(associationName).not.toEqual(this.User.tableName)
expect(associationName).not.toEqual(this.Task.tableName)
var joinTableName = this.User.associations[associationName].options.joinTableName
if (typeof joinTableName !== 'undefined') {
expect(joinTableName).toEqual(associationName)
}
var tableName = this.User.associations[associationName].options.tableName
if (typeof tableName !== 'undefined') {
expect(tableName).toEqual(associationName)
}
}
done()
})
})
})
describe("Foreign key constraints", function() {
before(function(done) {
this.sequelize.options = console.log
done()
})
it("are not enabled by default", function(done) {
var Task = this.sequelize.define('Task', { title: DataTypes.STRING })
, User = this.sequelize.define('User', { username: DataTypes.STRING })
User.hasMany(Task)
User.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
Task.create({ title: 'task' }).success(function(task) {
user.setTasks([task]).success(function() {
user.destroy().success(function() {
Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
})
})
})
})
})
it("can cascade deletes", function(done) {
var self = this
self.User.hasMany(self.Task, {onDelete: 'cascade'})
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task' }).success(function(task) {
user.setTasks([task]).success(function() {
user.destroy().success(function() {
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(0)
done()
})
})
})
})
})
})
})
})
it("can restrict deletes", function(done) {
var self = this
self.User.hasMany(self.Task, {onDelete: 'restrict'})
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task' }).success(function(task) {
user.setTasks([task]).success(function() {
user.destroy().error(function() {
// Should fail due to FK restriction
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
})
})
})
})
})
it("can cascade updates", function(done) {
var self = this
self.User.hasMany(self.Task, {onUpdate: 'cascade'})
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task' }).success(function(task) {
user.setTasks([task]).success(function() {
// Changing the id of a DAO requires a little dance since
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.success(function() {
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
expect(tasks[0].UserId).toEqual(999)
done()
})
})
})
})
})
})
})
})
it("can restrict updates", function(done) {
var self = this
self.User.hasMany(self.Task, {onUpdate: 'restrict'})
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.create({ username: 'foo' }).success(function(user) {
self.Task.create({ title: 'task' }).success(function(task) {
user.setTasks([task]).success(function() {
// Changing the id of a DAO requires a little dance since
// the `UPDATE` query generated by `save()` uses `id` in the
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
user.QueryInterface.update(user, tableName, {id: 999}, user.id)
.error(function() {
// Should fail due to FK restriction
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
})
})
})
})
})
})
})
})
describe("Association options", function() {
it('can specify data type for autogenerated relational keys', function(done) {
var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, dataTypes = [DataTypes.INTEGER, Sequelize.BIGINT, DataTypes.STRING]
, self = this
dataTypes.forEach(function(dataType) {
var tableName = 'TaskXYZ_' + dataType.toString()
, Task = self.sequelize.define(tableName, { title: DataTypes.STRING })
User.hasMany(Task, { foreignKey: 'userId', keyType: dataType })
User.sync({ force: true }).success(function() {
expect(Task.rawAttributes.userId.type.toString())
.toEqual(dataType.toString())
dataTypes.splice(dataTypes.indexOf(dataType), 1)
if (!dataTypes.length) {
done()
}
})
})
})
})
})
/* jshint camelcase: false */ /* jshint camelcase: false */
if (typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , Sequelize = require('../../index')
, Sequelize = require('../../index') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , _ = require('lodash')
, _ = require('lodash') , moment = require('moment')
, moment = require('moment')
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 500 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
describe(Helpers.getTestDialectTeaser("HasMany"), function() { describe(Helpers.getTestDialectTeaser("HasMany"), function() {
before(function(done) { before(function(done) {
var self = this var self = this
self.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, done)
dialect: dialect,
beforeComplete: function(sequelize) { self.sequelize = sequelize },
onComplete: done
})
}) })
describe('general usage', function() { describe('general usage', function() {
...@@ -850,6 +846,9 @@ describe(Helpers.getTestDialectTeaser("HasMany"), function() { ...@@ -850,6 +846,9 @@ describe(Helpers.getTestDialectTeaser("HasMany"), function() {
}) })
describe("Foreign key constraints", function() { describe("Foreign key constraints", function() {
before(function(done) {
Helpers.clearDatabase(this.sequelize, done) // Constraints need this for some reason...
})
it("are not enabled by default", function(done) { it("are not enabled by default", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var Task = this.sequelize.define('Task', { title: Sequelize.STRING })
......
/* jshint camelcase: false */ /* jshint camelcase: false */
if (typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Sequelize = require("../../index") , dialect = Helpers.getTestDialect()
, Helpers = require('../buster-helpers') , DataTypes = require(__dirname + "/../../lib/data-types")
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1500 buster.testRunner.timeout = 1500
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
describe(Helpers.getTestDialectTeaser("HasOne"), function() { describe(Helpers.getTestDialectTeaser("HasOne"), function() {
before(function(done) { before(function(done) {
var self = this this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
Helpers.initTests({
dialect: dialect,
beforeComplete: function(sequelize) { self.sequelize = sequelize },
onComplete: done
})
}) })
describe('general usage', function() { describe('general usage', function() {
before(function(done) { before(function(done) {
this.User = this.sequelize.define('User', { username: Helpers.Sequelize.STRING }) this.User = this.sequelize.define('User', { username: DataTypes.STRING })
this.Task = this.sequelize.define('Task', { title: Helpers.Sequelize.STRING }) this.Task = this.sequelize.define('Task', { title: DataTypes.STRING })
this.sequelize.sync({ force: true }).success(done) var self = this
this.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(done)
})
}) })
it("adds the foreign key", function(done) { it("adds the foreign key", function(done) {
...@@ -34,8 +32,8 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -34,8 +32,8 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("adds an underscored foreign key", function(done) { it("adds an underscored foreign key", function(done) {
var User = this.sequelize.define('User', { username: Helpers.Sequelize.STRING }, {underscored: true}) var User = this.sequelize.define('User', { username: DataTypes.STRING }, {underscored: true})
, Task = this.sequelize.define('Task', { title: Helpers.Sequelize.STRING }) , Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasOne(Task) User.hasOne(Task)
expect(Task.attributes.user_id).toEqual("INTEGER") expect(Task.attributes.user_id).toEqual("INTEGER")
...@@ -43,8 +41,8 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -43,8 +41,8 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("uses the passed foreign key", function(done) { it("uses the passed foreign key", function(done) {
var User = this.sequelize.define('User', { username: Helpers.Sequelize.STRING }, {underscored: true}) var User = this.sequelize.define('User', { username: DataTypes.STRING }, {underscored: true})
, Task = this.sequelize.define('Task', { title: Helpers.Sequelize.STRING }) , Task = this.sequelize.define('Task', { title: DataTypes.STRING })
User.hasOne(Task, {foreignKey: 'person_id'}) User.hasOne(Task, {foreignKey: 'person_id'})
expect(Task.attributes.person_id).toEqual("INTEGER") expect(Task.attributes.person_id).toEqual("INTEGER")
...@@ -85,16 +83,18 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -85,16 +83,18 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
var self = this var self = this
this.User.hasOne(this.Task, {as: 'Task'}) this.User.hasOne(this.Task, {as: 'Task'})
this.sequelize.sync({ force: true }).success(function() { this.User.sync({ force: true }).success(function() {
self.User.create({username: 'name'}).success(function(user) { self.Task.sync({ force: true }).success(function() {
self.Task.create({title: 'snafu'}).success(function(task) { self.User.create({username: 'name'}).success(function(user) {
user.setTask(task).on('success', function() { self.Task.create({title: 'snafu'}).success(function(task) {
user.getTask().on('success', function(task2) { user.setTask(task).on('success', function() {
expect(task.title).toEqual(task2.title) user.getTask().on('success', function(task2) {
user.getTask({attributes: ['title']}).on('success', function(task2) { expect(task.title).toEqual(task2.title)
expect(task2.selectedValues.title).toEqual('snafu') user.getTask({attributes: ['title']}).on('success', function(task2) {
expect(task2.selectedValues.id).not.toBeDefined() expect(task2.selectedValues.title).toEqual('snafu')
done() expect(task2.selectedValues.id).not.toBeDefined()
done()
})
}) })
}) })
}) })
...@@ -107,17 +107,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -107,17 +107,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
var self = this var self = this
this.User.hasOne(this.Task, {as: 'Task'}) this.User.hasOne(this.Task, {as: 'Task'})
this.sequelize.sync({ force: true }).success(function() { this.User.sync({ force: true }).success(function() {
self.User.create({username: 'name'}).success(function(user) { self.Task.sync({ force: true }).success(function() {
self.Task.create({title: 'snafu'}).success(function(task1) { self.User.create({username: 'name'}).success(function(user) {
self.Task.create({title: 'another task'}).success(function(task2) { self.Task.create({title: 'snafu'}).success(function(task1) {
user.setTask(task1).success(function() { self.Task.create({title: 'another task'}).success(function(task2) {
user.getTask().success(function(_task) { user.setTask(task1).success(function() {
expect(task1.title).toEqual(_task.title) user.getTask().success(function(_task) {
user.setTask(task2).success(function() { expect(task1.title).toEqual(_task.title)
user.getTask().success(function(_task2) { user.setTask(task2).success(function() {
expect(task2.title).toEqual(_task2.title) user.getTask().success(function(_task2) {
done() expect(task2.title).toEqual(_task2.title)
done()
})
}) })
}) })
}) })
...@@ -152,17 +154,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -152,17 +154,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
describe('getAssocation', function() { describe('getAssocation', function() {
it('should be able to handle a where object that\'s a first class citizen.', function(done) { it('should be able to handle a where object that\'s a first class citizen.', function(done) {
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING, status: Sequelize.STRING }) , Task = this.sequelize.define('TaskXYZ', { title: DataTypes.STRING, status: DataTypes.STRING })
User.hasOne(Task) User.hasOne(Task)
this.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { Task.sync({ force: true }).success(function() {
Task.create({ title: 'task', status: 'inactive' }).success(function(task) { User.create({ username: 'foo' }).success(function(user) {
user.setTaskXYZ(task).success(function() { Task.create({ title: 'task', status: 'inactive' }).success(function(task) {
user.getTaskXYZ({where: ['status = ?', 'active']}).success(function(task) { user.setTaskXYZ(task).success(function() {
expect(task).toEqual(null) user.getTaskXYZ({where: ['status = ?', 'active']}).success(function(task) {
done() expect(task).toEqual(null)
done()
})
}) })
}) })
}) })
...@@ -173,25 +177,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -173,25 +177,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
describe('setAssociation', function() { describe('setAssociation', function() {
it('clears the association if null is passed', function(done) { it('clears the association if null is passed', function(done) {
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, Task = this.sequelize.define('TaskXYZ', { title: Sequelize.STRING }) , Task = this.sequelize.define('TaskXYZ', { title: DataTypes.STRING })
User.hasOne(Task) User.hasOne(Task)
this.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) { Task.sync({ force: true }).success(function() {
Task.create({ title: 'task' }).success(function(task) { User.create({ username: 'foo' }).success(function(user) {
user.setTaskXYZ(task).success(function() { Task.create({ title: 'task' }).success(function(task) {
user.getTaskXYZ().success(function(task) { user.setTaskXYZ(task).success(function() {
expect(task).not.toEqual(null) user.getTaskXYZ().success(function(task) {
expect(task).not.toEqual(null)
user.setTaskXYZ(null).success(function() {
user.getTaskXYZ().success(function(task) { user.setTaskXYZ(null).success(function() {
expect(task).toEqual(null) user.getTaskXYZ().success(function(task) {
done() expect(task).toEqual(null)
done()
})
}) })
})
})
}) })
}) })
}) })
...@@ -201,20 +207,35 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -201,20 +207,35 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
describe("Foreign key constraints", function() { describe("Foreign key constraints", function() {
it("are not enabled by default", function(done) { before(function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) Helpers.initTests({
dialect: dialect,
User.hasOne(Task) beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
self.Task = sequelize.define('Task', { title: DataTypes.STRING })
self.User = sequelize.define('User', { username: DataTypes.STRING })
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
})
this.sequelize.sync({ force: true }).success(function() { it("are not enabled by default", function(done) {
User.create({ username: 'foo' }).success(function(user) { var self = this
Task.create({ title: 'task' }).success(function(task) { self.User.hasOne(self.Task)
user.setTask(task).success(function() {
user.destroy().success(function() { self.User.sync({ force: true }).success(function() {
Task.findAll().success(function(tasks) { self.Task.sync({ force: true }).success(function() {
expect(tasks.length).toEqual(1) self.User.create({ username: 'foo' }).success(function(user) {
done() self.Task.create({ title: 'task' }).success(function(task) {
user.setTask(task).success(function() {
user.destroy().success(function() {
self.Task.findAll().success(function(tasks) {
expect(tasks.length).toEqual(1)
done()
})
}) })
}) })
}) })
...@@ -224,19 +245,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -224,19 +245,19 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("can cascade deletes", function(done) { it("can cascade deletes", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.User.hasOne(self.Task, {onDelete: 'cascade'})
User.hasOne(Task, {onDelete: 'cascade'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { user.setTask(task).success(function() {
user.setTask(task).success(function() { user.destroy().success(function() {
user.destroy().success(function() { self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(0)
expect(tasks.length).toEqual(0) done()
done() })
}) })
}) })
}) })
...@@ -246,20 +267,20 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -246,20 +267,20 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("can restrict deletes", function(done) { it("can restrict deletes", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.User.hasOne(self.Task, {onDelete: 'restrict'})
User.hasOne(Task, {onDelete: 'restrict'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { user.setTask(task).success(function() {
user.setTask(task).success(function() { user.destroy().error(function() {
user.destroy().error(function() { // Should fail due to FK restriction
// Should fail due to FK restriction self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) done()
done() })
}) })
}) })
}) })
...@@ -269,27 +290,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -269,27 +290,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("can cascade updates", function(done) { it("can cascade updates", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.User.hasOne(self.Task, {onUpdate: 'cascade'})
User.hasOne(Task, {onUpdate: 'cascade'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { user.setTask(task).success(function() {
user.setTask(task).success(function() {
// Changing the id of a DAO requires a little dance since
// Changing the id of a DAO requires a little dance since // the `UPDATE` query generated by `save()` uses `id` in the
// the `UPDATE` query generated by `save()` uses `id` in the // `WHERE` clause
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) .success(function() {
.success(function() { self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) expect(tasks[0].UserId).toEqual(999)
expect(tasks[0].UserId).toEqual(999) done()
done() })
}) })
}) })
}) })
...@@ -299,27 +320,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -299,27 +320,27 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
it("can restrict updates", function(done) { it("can restrict updates", function(done) {
var Task = this.sequelize.define('Task', { title: Sequelize.STRING }) var self = this
, User = this.sequelize.define('User', { username: Sequelize.STRING }) self.User.hasOne(self.Task, {onUpdate: 'restrict'})
User.hasOne(Task, {onUpdate: 'restrict'}) self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).success(function() { self.User.create({ username: 'foo' }).success(function(user) {
User.create({ username: 'foo' }).success(function(user) { self.Task.create({ title: 'task' }).success(function(task) {
Task.create({ title: 'task' }).success(function(task) { user.setTask(task).success(function() {
user.setTask(task).success(function() {
// Changing the id of a DAO requires a little dance since
// Changing the id of a DAO requires a little dance since // the `UPDATE` query generated by `save()` uses `id` in the
// the `UPDATE` query generated by `save()` uses `id` in the // `WHERE` clause
// `WHERE` clause
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory)
var tableName = user.QueryInterface.QueryGenerator.addSchema(user.__factory) user.QueryInterface.update(user, tableName, {id: 999}, user.id)
user.QueryInterface.update(user, tableName, {id: 999}, user.id) .error(function() {
.error(function() { // Should fail due to FK restriction
// Should fail due to FK restriction self.Task.findAll().success(function(tasks) {
Task.findAll().success(function(tasks) { expect(tasks.length).toEqual(1)
expect(tasks.length).toEqual(1) done()
done() })
}) })
}) })
}) })
...@@ -327,22 +348,21 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() { ...@@ -327,22 +348,21 @@ describe(Helpers.getTestDialectTeaser("HasOne"), function() {
}) })
}) })
}) })
}) })
describe("Association options", function() { describe("Association options", function() {
it('can specify data type for autogenerated relational keys', function(done) { it('can specify data type for autogenerated relational keys', function(done) {
var User = this.sequelize.define('UserXYZ', { username: Sequelize.STRING }) var User = this.sequelize.define('UserXYZ', { username: DataTypes.STRING })
, dataTypes = [Sequelize.INTEGER, Sequelize.BIGINT, Sequelize.STRING] , dataTypes = [DataTypes.INTEGER, DataTypes.BIGINT, DataTypes.STRING]
, self = this , self = this
dataTypes.forEach(function(dataType) { dataTypes.forEach(function(dataType) {
var tableName = 'TaskXYZ_' + dataType.toString() var tableName = 'TaskXYZ_' + dataType.toString()
, Task = self.sequelize.define(tableName, { title: Sequelize.STRING }) , Task = self.sequelize.define(tableName, { title: DataTypes.STRING })
User.hasOne(Task, { foreignKey: 'userId', keyType: dataType }) User.hasOne(Task, { foreignKey: 'userId', keyType: dataType })
self.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
expect(Task.rawAttributes.userId.type.toString()) expect(Task.rawAttributes.userId.type.toString())
.toEqual(dataType.toString()) .toEqual(dataType.toString())
......
if (typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , Sequelize = require('../../index')
, Sequelize = require('../../index') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
describe(Helpers.getTestDialectTeaser("Mixin"), function() { describe(Helpers.getTestDialectTeaser("Mixin"), function() {
before(function(done) { before(function(done) {
Helpers.initTests({ this.sequelize = sequelize
dialect: dialect, Helpers.clearDatabase(this.sequelize, done)
beforeComplete: function(sequelize) {
this.sequelize = sequelize
}.bind(this),
onComplete: done
})
}) })
describe('Mixin', function() { describe('Mixin', function() {
var DAOFactory = require("../../lib/dao-factory") var DAOFactory = require("../../lib/dao-factory")
it("adds the mixed-in functions to the dao", function() { it("adds the mixed-in functions to the dao", function(done) {
expect(DAOFactory.prototype.hasOne).toBeDefined() expect(DAOFactory.prototype.hasOne).toBeDefined()
expect(DAOFactory.prototype.hasMany).toBeDefined() expect(DAOFactory.prototype.hasMany).toBeDefined()
expect(DAOFactory.prototype.belongsTo).toBeDefined() expect(DAOFactory.prototype.belongsTo).toBeDefined()
done()
}) })
}) })
describe('getAssociation', function() { describe('getAssociation', function() {
it('returns the respective part of the association for 1:1 associations', function() { it('returns the respective part of the association for 1:1 associations', function(done) {
var User = this.sequelize.define('User', {}) var User = this.sequelize.define('User', {})
var Task = this.sequelize.define('Task', {}) var Task = this.sequelize.define('Task', {})
...@@ -37,6 +34,7 @@ describe(Helpers.getTestDialectTeaser("Mixin"), function() { ...@@ -37,6 +34,7 @@ describe(Helpers.getTestDialectTeaser("Mixin"), function() {
Task.belongsTo(User) Task.belongsTo(User)
expect(User.getAssociation(Task).target).toEqual(Task) expect(User.getAssociation(Task).target).toEqual(Task)
done()
}) })
it('can handle multiple associations just fine', function(done) { it('can handle multiple associations just fine', function(done) {
......
...@@ -6,7 +6,7 @@ module.exports = { ...@@ -6,7 +6,7 @@ module.exports = {
pool: { maxConnections: 5, maxIdleTime: 30000}, pool: { maxConnections: 5, maxIdleTime: 30000},
rand: function() { rand: function() {
return parseInt(Math.random() * 999) return parseInt(Math.random() * 999, 10)
}, },
//make maxIdleTime small so that tests exit promptly //make maxIdleTime small so that tests exit promptly
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , semver = require("semver")
, semver = require("semver") , Helpers = require('./buster-helpers')
, CustomEventEmitter = require("../lib/emitters/custom-event-emitter") , config = require(__dirname + "/config/config")
, Helpers = require('./buster-helpers') , dialect = Helpers.getTestDialect()
, config = require(__dirname + "/config/config")
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
...@@ -27,15 +24,7 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() { ...@@ -27,15 +24,7 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() {
, d = domain.create() , d = domain.create()
d.on('error', function(err){ d.on('error', function(err){
var msg = 'Failed to find SQL server. Please double check your settings.' expect(err).toMatch(/Failed to find (.*?) Please double check your settings\./)
if (dialect === "postgres" || dialect === "postgres-native") {
msg = 'Failed to find PostgresSQL server. Please double check your settings.'
}
else if (dialect === "mysql") {
msg = 'Failed to find MySQL server. Please double check your settings.'
}
expect(err.message).toEqual(msg)
d.remove(sequelize.query) d.remove(sequelize.query)
done() done()
}) })
...@@ -65,35 +54,28 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() { ...@@ -65,35 +54,28 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() {
, d = domain.create() , d = domain.create()
d.on('error', function(err){ d.on('error', function(err){
var msg = 'Failed to authenticate for SQL. Please double check your settings.' expect(err).toMatch(/^Failed to authenticate/)
if (dialect === "postgres" || dialect === "postgres-native") { d.remove(sequelize)
msg = 'Failed to authenticate for PostgresSQL. Please double check your settings.'
}
else if (dialect === "mysql") {
msg = 'Failed to authenticate for MySQL. Please double check your settings.'
}
expect(err.message).toEqual(msg)
d.remove(sequelize.query)
done() done()
}) })
d.run(function(){ d.run(function(){
d.add(sequelize.query) d.add(sequelize)
sequelize.query('select 1 as hello') sequelize.query('select 1 as hello')
.success(function(){}) .success(function(){})
}) })
}) })
it('when we don\'t have a valid dialect.', function() { it('when we don\'t have a valid dialect.', function(done) {
Helpers.assertException(function() { expect(function() {
new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {host: '0.0.0.1', port: config[dialect].port, dialect: undefined}) new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {host: '0.0.0.1', port: config[dialect].port, dialect: undefined})
}.bind(this), 'The dialect undefined is not supported.') }).toThrow('Error', 'The dialect undefined is not supported.')
done()
}) })
}) })
describe('Instantiation with a URL string', function() { describe('Instantiation with a URL string', function() {
it('should accept username, password, host, port, and database', function() { it('should accept username, password, host, port, and database', function(done) {
var sequelize = new Sequelize('mysql://user:pass@example.com:9821/dbname') var sequelize = new Sequelize('mysql://user:pass@example.com:9821/dbname')
var config = sequelize.config var config = sequelize.config
var options = sequelize.options var options = sequelize.options
...@@ -105,44 +87,49 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() { ...@@ -105,44 +87,49 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() {
expect(config.username).toEqual('user') expect(config.username).toEqual('user')
expect(config.password).toEqual('pass') expect(config.password).toEqual('pass')
expect(config.port).toEqual(9821) expect(config.port).toEqual(9821)
done()
}) })
it('should work with no authentication options', function() { it('should work with no authentication options', function(done) {
var sequelize = new Sequelize('mysql://example.com:9821/dbname') var sequelize = new Sequelize('mysql://example.com:9821/dbname')
var config = sequelize.config var config = sequelize.config
expect(config.username).toEqual(undefined) expect(config.username).toEqual(undefined)
expect(config.password).toEqual(null) expect(config.password).toEqual(null)
done()
}) })
it('should use the default port when no other is specified', function() { it('should use the default port when no other is specified', function(done) {
var sequelize = new Sequelize('mysql://example.com/dbname') var sequelize = new Sequelize('mysql://example.com/dbname')
var config = sequelize.config var config = sequelize.config
// The default port should be set // The default port should be set
expect(config.port).toEqual(3306) expect(config.port).toEqual(3306)
done()
}) })
}) })
describe('Intantiation with arguments', function() { describe('Intantiation with arguments', function() {
it('should accept two parameters (database, username)', function() { it('should accept two parameters (database, username)', function(done) {
var sequelize = new Sequelize('dbname', 'root') var sequelize = new Sequelize('dbname', 'root')
var config = sequelize.config var config = sequelize.config
expect(config.database).toEqual('dbname') expect(config.database).toEqual('dbname')
expect(config.username).toEqual('root') expect(config.username).toEqual('root')
done()
}) })
it('should accept three parameters (database, username, password)', function() { it('should accept three parameters (database, username, password)', function(done) {
var sequelize = new Sequelize('dbname', 'root', 'pass') var sequelize = new Sequelize('dbname', 'root', 'pass')
var config = sequelize.config var config = sequelize.config
expect(config.database).toEqual('dbname') expect(config.database).toEqual('dbname')
expect(config.username).toEqual('root') expect(config.username).toEqual('root')
expect(config.password).toEqual('pass') expect(config.password).toEqual('pass')
done()
}) })
it('should accept four parameters (database, username, password, options)', function() { it('should accept four parameters (database, username, password, options)', function(done) {
var sequelize = new Sequelize('dbname', 'root', 'pass', { port: 999 }) var sequelize = new Sequelize('dbname', 'root', 'pass', { port: 999 })
var config = sequelize.config var config = sequelize.config
...@@ -150,6 +137,7 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() { ...@@ -150,6 +137,7 @@ describe(Helpers.getTestDialectTeaser("Configuration"), function() {
expect(config.username).toEqual('root') expect(config.username).toEqual('root')
expect(config.password).toEqual('pass') expect(config.password).toEqual('pass')
expect(config.port).toEqual(999) expect(config.port).toEqual(999)
done()
}) })
}) })
}) })
if(typeof require === 'function') { /* jshint camelcase: false */
const buster = require("buster") var buster = require("buster")
, Sequelize = require("../index") , Sequelize = require("../index")
, Helpers = require('./buster-helpers') , Helpers = require('./buster-helpers')
, _ = require('lodash') , _ = require('lodash')
, moment = require('moment') , moment = require('moment')
, dialect = Helpers.getTestDialect() , dialect = Helpers.getTestDialect()
} , DataTypes = require(__dirname + "/../lib/data-types")
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
, User = sequelize.define('User', {
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
data: DataTypes.STRING,
intVal: DataTypes.INTEGER,
theDate: DataTypes.DATE
})
before(function(done) { before(function(done) {
Helpers.initTests({ this.sequelize = sequelize
dialect: dialect, this.DataTypes = DataTypes
beforeComplete: function(sequelize, DataTypes) { this.User = User
this.DataTypes = DataTypes var self = this
this.sequelize = sequelize Helpers.clearDatabase(this.sequelize, function() {
this.User = sequelize.define('User', { self.User.sync({ force: true }).success(done)
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
data: DataTypes.STRING,
intVal: DataTypes.INTEGER,
theDate: DataTypes.DATE
})
}.bind(this),
onComplete: function() {
this.User.sync({ force: true }).success(done)
}.bind(this)
}) })
}) })
describe('constructor', function() { describe('constructor', function() {
it("uses the passed dao name as tablename if freezeTableName", function() { it("uses the passed dao name as tablename if freezeTableName", function(done) {
var User = this.sequelize.define('FrozenUser', {}, { freezeTableName: true }) var User = this.sequelize.define('FrozenUser', {}, { freezeTableName: true })
expect(User.tableName).toEqual('FrozenUser') expect(User.tableName).toEqual('FrozenUser')
done()
}) })
it("uses the pluralized dao name as tablename unless freezeTableName", function() { it("uses the pluralized dao name as tablename unless freezeTableName", function(done) {
var User = this.sequelize.define('SuperUser', {}, { freezeTableName: false }) var User = this.sequelize.define('SuperUser', {}, { freezeTableName: false })
expect(User.tableName).toEqual('SuperUsers') expect(User.tableName).toEqual('SuperUsers')
done()
}) })
it("uses checks to make sure dao factory isnt leaking on multiple define", function() { it("uses checks to make sure dao factory isnt leaking on multiple define", function(done) {
var User = this.sequelize.define('SuperUser', {}, { freezeTableName: false }) this.sequelize.define('SuperUser', {}, { freezeTableName: false })
var factorySize = this.sequelize.daoFactoryManager.all.length var factorySize = this.sequelize.daoFactoryManager.all.length
var User2 = this.sequelize.define('SuperUser', {}, { freezeTableName: false }) this.sequelize.define('SuperUser', {}, { freezeTableName: false })
var factorySize2 = this.sequelize.daoFactoryManager.all.length var factorySize2 = this.sequelize.daoFactoryManager.all.length
expect(factorySize).toEqual(factorySize2) expect(factorySize).toEqual(factorySize2)
done()
}) })
it("attaches class and instance methods", function() { it("attaches class and instance methods", function(done) {
var User = this.sequelize.define('UserWithClassAndInstanceMethods', {}, { var User = this.sequelize.define('UserWithClassAndInstanceMethods', {}, {
classMethods: { doSmth: function(){ return 1 } }, classMethods: { doSmth: function(){ return 1 } },
instanceMethods: { makeItSo: function(){ return 2}} instanceMethods: { makeItSo: function(){ return 2}}
...@@ -65,43 +67,46 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -65,43 +67,46 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(User.build().doSmth).not.toBeDefined() expect(User.build().doSmth).not.toBeDefined()
expect(User.build().makeItSo).toBeDefined() expect(User.build().makeItSo).toBeDefined()
expect(User.build().makeItSo()).toEqual(2) expect(User.build().makeItSo()).toEqual(2)
done()
}) })
it("throws an error if 2 autoIncrements are passed", function() { it("throws an error if 2 autoIncrements are passed", function(done) {
Helpers.assertException(function() { var self = this
this.sequelize.define('UserWithTwoAutoIncrements', { expect(function() {
self.sequelize.define('UserWithTwoAutoIncrements', {
userid: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, userid: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
userscore: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true } userscore: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }
}) })
}.bind(this), 'Invalid DAO definition. Only one autoincrement field allowed.') }).toThrow('Error', 'Invalid DAO definition. Only one autoincrement field allowed.')
done()
}) })
it('throws an error if a custom model-wide validation is not a function', function() { it('throws an error if a custom model-wide validation is not a function', function(done) {
Helpers.assertException(function() { var self = this
this.sequelize.define('Foo', { expect(function() {
field: { self.sequelize.define('Foo', {
type: Sequelize.INTEGER field: Sequelize.INTEGER
}
}, { }, {
validate: { validate: {
notFunction: 33 notFunction: 33
} }
}) })
}.bind(this), 'Members of the validate option must be functions. Model: Foo, error with validate member notFunction') }).toThrow('Error', 'Members of the validate option must be functions. Model: Foo, error with validate member notFunction')
done()
}) })
it('throws an error if a custom model-wide validation has the same name as a field', function() { it('throws an error if a custom model-wide validation has the same name as a field', function(done) {
Helpers.assertException(function() { var self = this
this.sequelize.define('Foo', { expect(function() {
field: { self.sequelize.define('Foo', {
type: Sequelize.INTEGER field: Sequelize.INTEGER
}
}, { }, {
validate: { validate: {
field: function() {} field: function() {}
} }
}) })
}.bind(this), 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field') }).toThrow('Error', 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field')
done()
}) })
}) })
...@@ -114,8 +119,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -114,8 +119,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
it("fills the objects with default values", function() { it("fills the objects with default values", function(done) {
var Task = this.sequelize.define('Task', { var Task = this.sequelize.define('TaskBuild', {
title: {type: Sequelize.STRING, defaultValue: 'a task!'}, title: {type: Sequelize.STRING, defaultValue: 'a task!'},
foo: {type: Sequelize.INTEGER, defaultValue: 2}, foo: {type: Sequelize.INTEGER, defaultValue: 2},
bar: {type: Sequelize.DATE}, bar: {type: Sequelize.DATE},
...@@ -127,10 +132,11 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -127,10 +132,11 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(Task.build().bar).toEqual(undefined) expect(Task.build().bar).toEqual(undefined)
expect(Task.build().foobar).toEqual('asd') expect(Task.build().foobar).toEqual('asd')
expect(Task.build().flag).toEqual(false) expect(Task.build().flag).toEqual(false)
done()
}) })
it("fills the objects with default values", function() { it("fills the objects with default values", function(done) {
var Task = this.sequelize.define('Task', { var Task = this.sequelize.define('TaskBuild', {
title: {type: Sequelize.STRING, defaultValue: 'a task!'}, title: {type: Sequelize.STRING, defaultValue: 'a task!'},
foo: {type: Sequelize.INTEGER, defaultValue: 2}, foo: {type: Sequelize.INTEGER, defaultValue: 2},
bar: {type: Sequelize.DATE}, bar: {type: Sequelize.DATE},
...@@ -142,92 +148,92 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -142,92 +148,92 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(Task.build().bar).toEqual(undefined) expect(Task.build().bar).toEqual(undefined)
expect(Task.build().foobar).toEqual('asd') expect(Task.build().foobar).toEqual('asd')
expect(Task.build().flag).toEqual(false) expect(Task.build().flag).toEqual(false)
done()
}) })
it("stores the the passed values in a special variable", function() { it("stores the the passed values in a special variable", function(done) {
var user = this.User.build({ username: 'John Wayne' }) var user = this.User.build({ username: 'John Wayne' })
expect(user.selectedValues).toEqual({ username: 'John Wayne' }) expect(user.selectedValues).toEqual({ username: 'John Wayne' })
done()
}) })
it("attaches getter and setter methods from attribute definition", function() { it("attaches getter and setter methods from attribute definition", function(done) {
var Product = this.sequelize.define('ProductWithSettersAndGetters1', { var Product = this.sequelize.define('ProductWithSettersAndGetters1', {
price: { price: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
get : function() { get : function() {
return 'answer = ' + this.getDataValue('price'); return 'answer = ' + this.getDataValue('price')
}, },
set : function(v) { set : function(v) {
return this.setDataValue('price', v + 42); return this.setDataValue('price', v + 42)
} }
} }
},{ })
});
expect(Product.build({price: 42}).price).toEqual('answer = 84');
var p = Product.build({price: 1}); expect(Product.build({price: 42}).price).toEqual('answer = 84')
var p = Product.build({price: 1})
expect(p.price).toEqual('answer = 43'); expect(p.price).toEqual('answer = 43');
p.price = 0; p.price = 0
expect(p.price).toEqual('answer = 42')
expect(p.price).toEqual('answer = 42'); // ah finally the right answer :-) done()
}) })
it("attaches getter and setter methods from options", function() { it("attaches getter and setter methods from options", function(done) {
var Product = this.sequelize.define('ProductWithSettersAndGetters2', { var Product = this.sequelize.define('ProductWithSettersAndGetters2', {
priceInCents: { priceInCents: Sequelize.INTEGER
type: Sequelize.INTEGER
}
},{ },{
setterMethods: { setterMethods: {
price: function(value) { price: function(value) {
this.dataValues.priceInCents = value * 100; this.dataValues.priceInCents = value * 100
} }
}, },
getterMethods: { getterMethods: {
price: function() { price: function() {
return '$' + (this.getDataValue('priceInCents') / 100); return '$' + (this.getDataValue('priceInCents') / 100)
}, },
priceInCents: function() { priceInCents: function() {
return this.dataValues.priceInCents; return this.dataValues.priceInCents
} }
} }
}); });
expect(Product.build({price: 20}).priceInCents).toEqual(20 * 100); expect(Product.build({price: 20}).priceInCents).toEqual(20 * 100)
expect(Product.build({priceInCents: 30 * 100}).price).toEqual('$' + 30); expect(Product.build({priceInCents: 30 * 100}).price).toEqual('$' + 30)
done()
}) })
it("attaches getter and setter methods from options only if not defined in attribute", function() { it("attaches getter and setter methods from options only if not defined in attribute", function(done) {
var Product = this.sequelize.define('ProductWithSettersAndGetters3', { var Product = this.sequelize.define('ProductWithSettersAndGetters3', {
price1: { price1: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
set : function(v) { this.setDataValue('price1', v * 10); } set : function(v) { this.setDataValue('price1', v * 10) }
}, },
price2: { price2: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
get : function(v) { return this.getDataValue('price2') * 10; } get : function() { return this.getDataValue('price2') * 10 }
} }
},{ },{
setterMethods: { setterMethods: {
price1: function(v) { this.setDataValue('price1', v * 100); } price1: function(v) { this.setDataValue('price1', v * 100) }
}, },
getterMethods: { getterMethods: {
price2: function() { return '$' + this.getDataValue('price2'); } price2: function() { return '$' + this.getDataValue('price2') }
} }
}); });
var p = Product.build({ price1: 1, price2: 2 }); var p = Product.build({ price1: 1, price2: 2 })
expect(p.price1).toEqual(10); expect(p.price1).toEqual(10)
expect(p.price2).toEqual(20); expect(p.price2).toEqual(20)
done()
}) })
}) })
describe('findOrCreate', function () { describe('findOrCreate', function () {
it("Returns instace if already existent. Single find field.", function (done) { it("Returns instace if already existent. Single find field.", function(done) {
var self = this, var self = this,
data = { data = {
username: 'Username' username: 'Username'
...@@ -240,13 +246,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -240,13 +246,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(_user.id).toEqual(user.id) expect(_user.id).toEqual(user.id)
expect(_user.username).toEqual('Username') expect(_user.username).toEqual('Username')
expect(created).toBeFalse() expect(created).toBeFalse()
done() done()
}) })
}) })
}) })
it("Returns instace if already existent. Multiple find fields.", function (done) { it("Returns instace if already existent. Multiple find fields.", function(done) {
var self = this, var self = this,
data = { data = {
username: 'Username', username: 'Username',
...@@ -259,26 +264,23 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -259,26 +264,23 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(_user.username).toEqual('Username') expect(_user.username).toEqual('Username')
expect(_user.data).toEqual('ThisIsData') expect(_user.data).toEqual('ThisIsData')
expect(created).toBeFalse() expect(created).toBeFalse()
done() done()
}) })
}) })
}) })
it("creates new instance with default value.", function (done) { it("creates new instance with default value.", function(done) {
var self = this, var data = {
data = {
username: 'Username' username: 'Username'
}, },
default_values = { default_values = {
data: 'ThisIsData' data: 'ThisIsData'
}; };
this.User.findOrCreate(data, default_values).success(function (user, created) { this.User.findOrCreate(data, default_values).success(function(user, created) {
expect(user.username).toEqual('Username') expect(user.username).toEqual('Username')
expect(user.data).toEqual('ThisIsData') expect(user.data).toEqual('ThisIsData')
expect(created).toBeTrue() expect(created).toBeTrue()
done() done()
}) })
}) })
...@@ -328,13 +330,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -328,13 +330,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
it("raises an error if created object breaks definition contraints", function(done) { it("raises an error if created object breaks definition contraints", function(done) {
var User = this.sequelize.define('UserWithNonNullSmth', { var UserNull = this.sequelize.define('UserWithNonNullSmth', {
username: { type: Sequelize.STRING, unique: true }, username: { type: Sequelize.STRING, unique: true },
smth: { type: Sequelize.STRING, allowNull: false } smth: { type: Sequelize.STRING, allowNull: false }
}) })
User.sync({ force: true }).success(function() { UserNull.sync({ force: true }).success(function() {
User.create({ username: 'foo', smth: null }).error(function(err) { UserNull.create({ username: 'foo', smth: null }).error(function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
Helpers.checkMatchForDialects(dialect, err.message, { Helpers.checkMatchForDialects(dialect, err.message, {
...@@ -343,8 +345,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -343,8 +345,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
postgres: /.*column "smth" violates not-null.*/ postgres: /.*column "smth" violates not-null.*/
}) })
User.create({ username: 'foo', smth: 'foo' }).success(function() { UserNull.create({ username: 'foo', smth: 'foo' }).success(function() {
User.create({ username: 'foo', smth: 'bar' }).error(function(err) { UserNull.create({ username: 'foo', smth: 'bar' }).error(function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
Helpers.checkMatchForDialects(dialect, err.message, { Helpers.checkMatchForDialects(dialect, err.message, {
...@@ -360,18 +362,20 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -360,18 +362,20 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
it('raises an error if you mess up the datatype', function() { it('raises an error if you mess up the datatype', function(done) {
Helpers.assertException(function() { var self = this
this.sequelize.define('UserBadDataType', { expect(function() {
self.sequelize.define('UserBadDataType', {
activity_date: Sequelize.DATe activity_date: Sequelize.DATe
}) })
}.bind(this), 'Unrecognized data type for field activity_date') }).toThrow('Error', 'Unrecognized data type for field activity_date')
Helpers.assertException(function() { expect(function() {
this.sequelize.define('UserBadDataType', { self.sequelize.define('UserBadDataType', {
activity_date: {type: Sequelize.DATe} activity_date: {type: Sequelize.DATe}
}) })
}.bind(this), 'Unrecognized data type for field activity_date') }).toThrow('Error', 'Unrecognized data type for field activity_date')
done()
}) })
it('sets a 64 bit int in bigint', function(done) { it('sets a 64 bit int in bigint', function(done) {
...@@ -436,7 +440,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -436,7 +440,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(sql.toUpperCase().indexOf("INSERT")).toBeGreaterThan(-1) expect(sql.toUpperCase().indexOf("INSERT")).toBeGreaterThan(-1)
done() done()
}) })
}) })
}) })
it('should only store the values passed in the whitelist', function(done) { it('should only store the values passed in the whitelist', function(done) {
...@@ -470,26 +474,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -470,26 +474,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
var self = this var self = this
, data = { title: 'Iliad' } , data = { title: 'Iliad' }
, dataTypes = [Sequelize.INTEGER, Sequelize.BIGINT] , dataTypes = [Sequelize.INTEGER, Sequelize.BIGINT]
, chain = new Sequelize.Utils.QueryChainer()
, chain2 = new Sequelize.Utils.QueryChainer()
, books = []
dataTypes.forEach(function(dataType, index) { dataTypes.forEach(function(dataType, index) {
var Book = self.sequelize.define('Book'+index, { books[index] = self.sequelize.define('Book'+index, {
id: { type: dataType, primaryKey: true, autoIncrement: true }, id: { type: dataType, primaryKey: true, autoIncrement: true },
title: Sequelize.TEXT title: Sequelize.TEXT
}) })
Book.sync({ force: true }).success(function() { })
Book
.create(data) books.forEach(function(b) {
.success(function(book) { chain.add(b.sync({ force: true }))
expect(book.title).toEqual(data.title) })
expect(book.author).toEqual(data.author)
expect(Book.rawAttributes.id.type.toString()) chain.run().success(function() {
.toEqual(dataTypes[index].toString()) books.forEach(function(b) {
chain2.add(b.create(data))
Book.drop() })
if (index >= dataTypes.length - 1) { chain2.run().success(function(results) {
done() results.forEach(function(book, index) {
} expect(book.title).toEqual(data.title)
}) expect(book.author).toEqual(data.author)
expect(books[index].rawAttributes.id.type.toString())
.toEqual(dataTypes[index].toString())
})
done()
}) })
}) })
}) })
...@@ -537,41 +548,39 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -537,41 +548,39 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
it('stores the current date in createdAt', function(done) { it('stores the current date in createdAt', function(done) {
this.User.create({ username: 'foo' }).success(function(user) { this.User.create({ username: 'foo' }).success(function(user) {
expect(parseInt(+user.createdAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+user.createdAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
done() done()
}) })
}) })
it('allows setting custom IDs', function (done) { it('allows setting custom IDs', function(done) {
var self = this
this.User.create({ id: 42 }).success(function (user) { this.User.create({ id: 42 }).success(function (user) {
expect(user.id).toEqual(42) expect(user.id).toEqual(42)
this.User.find(42).success(function (user) { self.User.find(42).success(function (user) {
expect(user).toBeDefined() expect(user).toBeDefined()
done() done()
}) })
}.bind(this)) })
}) })
describe('enums', function() { describe('enums', function() {
before(function(done) { it('correctly restores enum values', function(done) {
var self = this
this.Item = this.sequelize.define('Item', { this.Item = this.sequelize.define('Item', {
state: { type: Helpers.Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] } state: { type: Helpers.Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] }
}) })
this.sequelize.sync({ force: true }).success(function() { this.Item.sync({ force: true }).success(function() {
this.Item.create({ state: 'available' }).success(function(item) { self.Item.create({ state: 'available' }).success(function(item) {
this.item = item self.item = item
done() self.Item.find({ where: { state: 'available' }}).success(function(item) {
}.bind(this)) expect(item.id).toEqual(self.item.id)
}.bind(this)) done()
}) })
})
it('correctly restores enum values', function(done) { })
this.Item.find({ where: { state: 'available' }}).success(function(item) {
expect(item.id).toEqual(this.item.id)
done()
}.bind(this))
}) })
}) })
}) })
...@@ -586,10 +595,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -586,10 +595,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({where: {username: 'Paul'}}).success(function(users) { self.User.findAll({where: {username: 'Paul'}}).success(function(users) {
expect(users.length).toEqual(1) expect(users.length).toEqual(1)
expect(users[0].username).toEqual("Paul") expect(users[0].username).toEqual("Paul")
expect(users[0].secretValue).toBeNull() expect(users[0].secretValue).toBeNull()
done() done()
}) })
}) })
...@@ -603,13 +610,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -603,13 +610,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data, ['username']).success(function() { this.User.bulkCreate(data, ['username']).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[0].secretValue).toBeNull(); expect(users[0].secretValue).toBeNull();
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[1].secretValue).toBeNull(); expect(users[1].secretValue).toBeNull();
done() done()
}) })
}) })
...@@ -623,13 +627,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -623,13 +627,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[0].secretValue).toEqual('42') expect(users[0].secretValue).toEqual('42')
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[1].secretValue).toEqual('23') expect(users[1].secretValue).toEqual('23')
done() done()
}) })
}) })
...@@ -644,13 +645,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -644,13 +645,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[0].data).toEqual(quote) expect(users[0].data).toEqual(quote)
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[1].data).toEqual(quote) expect(users[1].data).toEqual(quote)
done() done()
}) })
}) })
...@@ -665,13 +663,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -665,13 +663,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[0].data).toEqual(quote) expect(users[0].data).toEqual(quote)
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[1].data).toEqual(quote) expect(users[1].data).toEqual(quote)
done() done()
}) })
}) })
...@@ -686,13 +681,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -686,13 +681,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[0].data).toEqual(json) expect(users[0].data).toEqual(json)
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[1].data).toEqual(json) expect(users[1].data).toEqual(json)
done() done()
}) })
}) })
...@@ -706,13 +698,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -706,13 +698,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(2) expect(users.length).toEqual(2)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(parseInt(+users[0].createdAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[0].createdAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(parseInt(+users[1].createdAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[1].createdAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
done() done()
}) })
}) })
...@@ -720,27 +709,27 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -720,27 +709,27 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
describe('enums', function() { describe('enums', function() {
before(function(done) { before(function(done) {
var self = this
this.Item = this.sequelize.define('Item', { this.Item = this.sequelize.define('Item', {
state: { type: Helpers.Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] }, state: { type: Helpers.Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] },
name: Sequelize.STRING name: Sequelize.STRING
}) })
this.sequelize.sync({ force: true }).success(function() { this.Item.sync({ force: true }).success(function() {
this.Item.bulkCreate([{state: 'in_cart', name: 'A'}, { state: 'available', name: 'B'}]).success(function() { self.Item.bulkCreate([{state: 'in_cart', name: 'A'}, { state: 'available', name: 'B'}]).success(function() {
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it('correctly restores enum values', function(done) { it('correctly restores enum values', function(done) {
this.Item.find({ where: { state: 'available' }}).success(function(item) { this.Item.find({ where: { state: 'available' }}).success(function(item) {
expect(item.name).toEqual('B') expect(item.name).toEqual('B')
done() done()
}.bind(this)) })
}) })
}) })
})
}) // - bulkCreate
describe('update', function() { describe('update', function() {
it('allows sql logging of updated statements', function(done) { it('allows sql logging of updated statements', function(done) {
...@@ -751,7 +740,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -751,7 +740,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
paranoid:true paranoid:true
}) })
this.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({ name: 'meg', bio: 'none' }).success(function(u) { User.create({ name: 'meg', bio: 'none' }).success(function(u) {
expect(u).toBeDefined() expect(u).toBeDefined()
expect(u).not.toBeNull() expect(u).not.toBeNull()
...@@ -798,26 +787,23 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -798,26 +787,23 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
{ username: 'Bob', secretValue: '43' }] { username: 'Bob', secretValue: '43' }]
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.update({username: 'Bill'}, {secretValue: '42'}).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).toEqual(3)
self.User.update({username: 'Bill'}, {secretValue: '42'}) expect(users[0].username).toEqual("Bill")
.success(function() { expect(users[1].username).toEqual("Bill")
self.User.findAll({order: 'id'}).success(function(users) { expect(users[2].username).toEqual("Bob")
expect(users.length).toEqual(3)
expect(users[0].username).toEqual("Bill")
expect(users[1].username).toEqual("Bill")
expect(users[2].username).toEqual("Bob")
expect(parseInt(+users[0].updatedAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[0].updatedAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
expect(parseInt(+users[1].updatedAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[1].updatedAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
done() done()
})
}) })
})
}) })
}) })
})
}) // - update
describe('destroy', function() { describe('destroy', function() {
it('deletes a record from the database if dao is not paranoid', function(done) { it('deletes a record from the database if dao is not paranoid', function(done) {
...@@ -825,7 +811,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -825,7 +811,8 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
name: Sequelize.STRING, name: Sequelize.STRING,
bio: Sequelize.TEXT bio: Sequelize.TEXT
}) })
this.sequelize.sync({ force: true }).success(function() {
User.sync({ force: true }).success(function() {
User.create({name: 'hallo', bio: 'welt'}).success(function(u) { User.create({name: 'hallo', bio: 'welt'}).success(function(u) {
User.all().success(function(users) { User.all().success(function(users) {
expect(users.length).toEqual(1) expect(users.length).toEqual(1)
...@@ -846,7 +833,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -846,7 +833,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
bio: Sequelize.TEXT bio: Sequelize.TEXT
}) })
this.sequelize.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.create({name: 'hallo', bio: 'welt'}).success(function(u) { User.create({name: 'hallo', bio: 'welt'}).success(function(u) {
User.all().success(function(users) { User.all().success(function(users) {
expect(users.length).toEqual(1) expect(users.length).toEqual(1)
...@@ -879,13 +866,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -879,13 +866,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
it('sets deletedAt to the current timestamp if paranoid is true', function(done) { it('sets deletedAt to the current timestamp if paranoid is true', function(done) {
var self = this var User = this.sequelize.define('ParanoidUser', {
, User = this.sequelize.define('ParanoidUser', { username: Sequelize.STRING,
username: Sequelize.STRING, secretValue: Sequelize.STRING,
secretValue: Sequelize.STRING, data: Sequelize.STRING,
data: Sequelize.STRING, intVal: { type: Sequelize.INTEGER, defaultValue: 1}
intVal: { type: Sequelize.INTEGER, defaultValue: 1} }, {
}, {
paranoid: true paranoid: true
}) })
, data = [{ username: 'Peter', secretValue: '42' }, , data = [{ username: 'Peter', secretValue: '42' },
...@@ -894,25 +880,24 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -894,25 +880,24 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.bulkCreate(data).success(function() { User.bulkCreate(data).success(function() {
User.destroy({secretValue: '42'}) User.destroy({secretValue: '42'}).success(function() {
.success(function() { User.findAll({order: 'id'}).success(function(users) {
User.findAll({order: 'id'}).success(function(users) { expect(users.length).toEqual(3)
expect(users.length).toEqual(3)
expect(users[0].username).toEqual("Peter") expect(users[0].username).toEqual("Peter")
expect(users[1].username).toEqual("Paul") expect(users[1].username).toEqual("Paul")
expect(users[2].username).toEqual("Bob") expect(users[2].username).toEqual("Bob")
expect(parseInt(+users[0].deletedAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[0].deletedAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
expect(parseInt(+users[1].deletedAt/5000)).toEqual(parseInt(+new Date()/5000)) expect(parseInt(+users[1].deletedAt/5000, 10)).toEqual(parseInt(+new Date()/5000, 10))
done() done()
})
}) })
})
}) })
}) })
}) })
}) // - destroy })
describe('special where conditions', function() { describe('special where conditions', function() {
before(function(done) { before(function(done) {
...@@ -1124,197 +1109,195 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1124,197 +1109,195 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
describe('find', function find() { describe('find', function() {
before(function(done) { describe('general / basic function', function() {
this.User.create({ before(function(done) {
username: 'barfooz' var self = this
}).success(function(user) { this.User.create({username: 'barfooz'}).success(function(user) {
this.UserPrimary = this.sequelize.define('UserPrimary', { self.UserPrimary = self.sequelize.define('UserPrimary', {
specialKey: { specialKey: {
type: this.DataTypes.STRING, type: self.DataTypes.STRING,
primaryKey: true primaryKey: true
} }
}) })
this.UserPrimary.sync({force: true}).success(function(primary){
this.UserPrimary.create({specialKey: 'a string'}).success(function(){
this.user = user
done()
}.bind(this))
}.bind(this))
}.bind(this))
})
it('doesn\'t throw an error when entering in a non integer value for a specified primary field', function(done) { self.UserPrimary.sync({force: true}).success(function() {
this.UserPrimary.find('a string').success(function(user) { self.UserPrimary.create({specialKey: 'a string'}).success(function() {
expect(user.specialKey).toEqual('a string') self.user = user
done() done()
})
})
})
}) })
})
it('doesn\'t throw an error when entering in a non integer value', function(done) { it('doesn\'t throw an error when entering in a non integer value for a specified primary field', function(done) {
this.User.find('a string value').success(function(user) { this.UserPrimary.find('a string').success(function(user) {
expect(user).toBeNull() expect(user.specialKey).toEqual('a string')
done() done()
})
}) })
})
it('returns a single dao', function(done) { it('doesn\'t throw an error when entering in a non integer value', function(done) {
this.User.find(this.user.id).success(function(user) { this.User.find('a string value').success(function(user) {
expect(Array.isArray(user)).toBeFalsy() expect(user).toBeNull()
expect(user.id).toEqual(this.user.id) done()
expect(user.id).toEqual(1) })
done() })
}.bind(this))
})
it('returns a single dao given a string id', function(done) { it('returns a single dao', function(done) {
this.User.find(this.user.id + '').success(function(user) { var self = this
expect(Array.isArray(user)).toBeFalsy() this.User.find(this.user.id).success(function(user) {
expect(user.id).toEqual(this.user.id) expect(Array.isArray(user)).toBeFalsy()
expect(user.id).toEqual(1) expect(user.id).toEqual(self.user.id)
done() expect(user.id).toEqual(1)
}.bind(this)) done()
}) })
})
it("should make aliased attributes available", function(done) { it('returns a single dao given a string id', function(done) {
this.User.find({ var self = this
where: { id: 1 }, this.User.find(this.user.id + '').success(function(user) {
attributes: ['id', ['username', 'name']] expect(Array.isArray(user)).toBeFalsy()
}).success(function(user) { expect(user.id).toEqual(self.user.id)
expect(user.name).toEqual('barfooz') expect(user.id).toEqual(1)
done() done()
})
}) })
})
it("should not try to convert boolean values if they are not selected", function (done) { it("should make aliased attributes available", function(done) {
var UserWithBoolean = this.sequelize.define('user', { this.User.find({
active: Sequelize.BOOLEAN where: { id: 1 },
attributes: ['id', ['username', 'name']]
}).success(function(user) {
expect(user.name).toEqual('barfooz')
done()
})
}) })
this.sequelize.sync({force: true}).success(function () { it("should not try to convert boolean values if they are not selected", function(done) {
UserWithBoolean.create({ active: true }).success(function (user) { var UserWithBoolean = this.sequelize.define('user', {
UserWithBoolean.find({ where: { id: user.id }, attributes: [ 'id' ] }).success(function (user) { active: Sequelize.BOOLEAN
expect(user.active).not.toBeDefined() })
done() UserWithBoolean.sync({force: true}).success(function () {
UserWithBoolean.create({ active: true }).success(function(user) {
UserWithBoolean.find({ where: { id: user.id }, attributes: [ 'id' ] }).success(function(user) {
expect(user.active).not.toBeDefined()
done()
})
}) })
}) })
}) })
})
it('finds a specific user via where option', function(done) { it('finds a specific user via where option', function(done) {
this.User.find({ where: { username: 'barfooz' } }).success(function(user) { this.User.find({ where: { username: 'barfooz' } }).success(function(user) {
expect(user.username).toEqual('barfooz') expect(user.username).toEqual('barfooz')
done() done()
})
}) })
})
it("doesn't find a user if conditions are not matching", function(done) { it("doesn't find a user if conditions are not matching", function(done) {
this.User.find({ where: { username: 'foo' } }).success(function(user) { this.User.find({ where: { username: 'foo' } }).success(function(user) {
expect(user).toBeNull() expect(user).toBeNull()
done() done()
})
}) })
})
it('allows sql logging', function(done) { it('allows sql logging', function(done) {
this.User.find({ where: { username: 'foo' } }) this.User.find({ where: { username: 'foo' } }).on('sql', function(sql) {
.on('sql', function(sql) {
expect(sql).toBeDefined() expect(sql).toBeDefined()
expect(sql.toUpperCase().indexOf("SELECT")).toBeGreaterThan(-1) expect(sql.toUpperCase().indexOf("SELECT")).toBeGreaterThan(-1)
done() done()
}) })
}) })
it('ignores passed limit option', function(done) { it('ignores passed limit option', function(done) {
this.User.find({ limit: 10 }).success(function(user) { this.User.find({ limit: 10 }).success(function(user) {
// it returns an object instead of an array // it returns an object instead of an array
expect(Array.isArray(user)).toBeFalsy() expect(Array.isArray(user)).toBeFalsy()
expect(user.hasOwnProperty('username')).toBeTruthy() expect(user.hasOwnProperty('username')).toBeTruthy()
done() done()
})
}) })
})
it('finds entries via primary keys', function(done) { it('finds entries via primary keys', function(done) {
var User = this.sequelize.define('UserWithPrimaryKey', { var User = this.sequelize.define('UserWithPrimaryKey', {
identifier: {type: Sequelize.STRING, primaryKey: true}, identifier: {type: Sequelize.STRING, primaryKey: true},
name: Sequelize.STRING name: Sequelize.STRING
})
User.sync({ force: true }).success(function() {
User.create({
identifier: 'an identifier',
name: 'John'
}).success(function(u) {
expect(u.id).not.toBeDefined()
User.find('an identifier').success(function(u2) {
expect(u2.identifier).toEqual('an identifier')
expect(u2.name).toEqual('John')
done()
})
})
})
}) })
User.sync({ force: true }).success(function() { it('returns the selected fields as instance.selectedValues', function(done) {
User.create({ var self = this
identifier: 'an identifier', this.User.create({
name: 'John' username: 'JohnXOXOXO'
}).success(function(u) { }).success(function() {
expect(u.id).not.toBeDefined() self.User.find({
where: { username: 'JohnXOXOXO' },
User.find('an identifier').success(function(u2) { attributes: ['username']
expect(u2.identifier).toEqual('an identifier') }).success(function(user) {
expect(u2.name).toEqual('John') expect(user.selectedValues).toEqual({ username: 'JohnXOXOXO' })
done() done()
}) })
}) })
}) })
})
it('returns the selected fields as instance.selectedValues', function(done) { it('returns the selected fields and all fields of the included table as instance.selectedValues', function(done) {
this.User.create({ var self = this
username: 'JohnXOXOXO' this.Mission = this.sequelize.define('Mission', {
}).success(function() { title: {type: Sequelize.STRING, defaultValue: 'a mission!!'},
this.User.find({ foo: {type: Sequelize.INTEGER, defaultValue: 2},
where: { username: 'JohnXOXOXO' }, })
attributes: ['username']
}).success(function(user) { this.Mission.belongsTo(this.User)
expect(user.selectedValues).toEqual({ username: 'JohnXOXOXO' }) this.User.hasMany(this.Mission)
done()
this.Mission.sync({ force: true }).success(function() {
self.Mission.create().success(function(mission) {
self.User.create({username: 'John DOE'}).success(function(user) {
mission.setUser(user).success(function() {
self.User.find({
where: { username: 'John DOE' },
attributes: ['username'],
include: [self.Mission]
}).success(function(user) {
expect(user.selectedValues).toEqual({ username: 'John DOE' })
done()
})
})
})
})
}) })
}.bind(this))
})
it('returns the selected fields and all fields of the included table as instance.selectedValues', function(done) {
this.Mission = this.sequelize.define('Mission', {
title: {type: Sequelize.STRING, defaultValue: 'a mission!!'},
foo: {type: Sequelize.INTEGER, defaultValue: 2},
}) })
this.Mission.belongsTo(this.User) it('always honors ZERO as primary key', function(_done) {
this.User.hasMany(this.Mission) var self = this
, permutations = [
this.sequelize.sync({ force: true }).complete(function() { 0,
this.Mission.create() '0',
.success(function(mission) { {where: {id: 0}},
this.User.create({ {where: {id: '0'}}
username: 'John DOE' ]
}).success(function(user) { , done = _.after(2 * permutations.length, _done);
mission.setUser(user)
.success(function() { this.User.bulkCreate([{username: 'jack'}, {username: 'jack'}]).success(function() {
this.User.find({
where: { username: 'John DOE' },
attributes: ['username'],
include: [this.Mission]
}).success(function(user) {
expect(user.selectedValues).toEqual({ username: 'John DOE' })
done()
})
}.bind(this))
}.bind(this))
}.bind(this))
}.bind(this))
})
it('always honors ZERO as primary key', function(_done) {
var permutations = [
0,
'0',
{where: {id: 0}},
{where: {id: '0'}}
]
, done = _.after(2 * permutations.length, _done);
this.User.create({username: 'jack'}).success(function (jack) {
this.User.create({username: 'jill'}).success(function (jill) {
permutations.forEach(function(perm) { permutations.forEach(function(perm) {
this.User.find(perm).done(function(err, user) { self.User.find(perm).done(function(err, user) {
expect(err).toBeNull(); expect(err).toBeNull();
expect(user).toBeNull(); expect(user).toBeNull();
done(); done();
...@@ -1322,54 +1305,73 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1322,54 +1305,73 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(s.indexOf(0)).not.toEqual(-1); expect(s.indexOf(0)).not.toEqual(-1);
done(); done();
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
describe('eager loading', function() { describe('eager loading', function() {
before(function() { before(function(done) {
var self = this
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING }) this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING }) this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Domain = this.sequelize.define('Domain', { ip: Sequelize.STRING })
this.Environment = this.sequelize.define('Environment', { name: Sequelize.STRING })
this.Environment
.belongsTo(this.Domain, { as: 'PrivateDomain', foreignKey: 'privateDomainId' })
.belongsTo(this.Domain, { as: 'PublicDomain', foreignKey: 'publicDomainId' })
this.init = function(callback) { this.init = function(callback) {
this.sequelize.sync({ force: true }).complete(function() { self.Task.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Worker.sync({ force: true }).success(function() {
this.Task.create({ title: 'homework' }).success(function(task) { self.Domain.sync({ force: true }).success(function() {
this.worker = worker self.Environment.sync({ force: true }).success(function() {
this.task = task self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
callback() self.worker = worker
}.bind(this)) self.task = task
}.bind(this)) callback()
}.bind(this)) })
}.bind(this) })
})
})
})
})
}
done()
}) })
describe('belongsTo', function() { describe('belongsTo', function() {
before(function(done) { before(function(done) {
var self = this
this.Task.belongsTo(this.Worker) this.Task.belongsTo(this.Worker)
this.init(function() { this.init(function() {
this.task.setWorker(this.worker).success(done) self.task.setWorker(self.worker).success(done)
}.bind(this)) })
}) })
it('throws an error about unexpected input if include contains a non-object', function() { it('throws an error about unexpected input if include contains a non-object', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ 1 ] }) expect(function() {
}.bind(this), 'Include unexpected. Element has to be either an instance of DAOFactory or an object.') self.Worker.find({ include: [ 1 ] })
}).toThrow('Error', 'Include unexpected. Element has to be either an instance of DAOFactory or an object.')
done()
}) })
it('throws an error about missing attributes if include contains an object with daoFactory', function() { it('throws an error about missing attributes if include contains an object with daoFactory', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ { daoFactory: this.Worker } ] }) expect(function() {
}.bind(this), 'Include malformed. Expected attributes: daoFactory, as!') self.Worker.find({ include: [ { daoFactory: self.Worker } ] })
}).toThrow('Error', 'Include malformed. Expected attributes: daoFactory, as!')
done()
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.find({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('returns the associated worker via task.worker', function(done) { it('returns the associated worker via task.worker', function(done) {
...@@ -1382,38 +1384,30 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1382,38 +1384,30 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(task.worker).toBeDefined() expect(task.worker).toBeDefined()
expect(task.worker.name).toEqual('worker') expect(task.worker.name).toEqual('worker')
done() done()
}.bind(this)) })
}) })
it('returns the private and public ip', function(done) { it('returns the private and public ip', function(done) {
var Domain = this.sequelize.define('Domain', { ip: Sequelize.STRING }) var self = this
var Environment = this.sequelize.define('Environment', { name: Sequelize.STRING }) this.Domain.create({ ip: '192.168.0.1' }).success(function(privateIp) {
self.Domain.create({ ip: '91.65.189.19' }).success(function(publicIp) {
Environment self.Environment.create({ name: 'environment' }).success(function(env) {
.belongsTo(Domain, { as: 'PrivateDomain', foreignKey: 'privateDomainId' }) env.setPrivateDomain(privateIp).success(function() {
.belongsTo(Domain, { as: 'PublicDomain', foreignKey: 'publicDomainId' }) env.setPublicDomain(publicIp).success(function() {
self.Environment.find({
this.sequelize.sync({ force: true }).complete(function() { where: { name: 'environment' },
Domain.create({ ip: '192.168.0.1' }).success(function(privateIp) { include: [
Domain.create({ ip: '91.65.189.19' }).success(function(publicIp) { { daoFactory: self.Domain, as: 'PrivateDomain' },
Environment.create({ name: 'environment' }).success(function(env) { { daoFactory: self.Domain, as: 'PublicDomain' }
env.setPrivateDomain(privateIp).success(function() { ]
env.setPublicDomain(publicIp).success(function() { }).complete(function(err, environment) {
Environment.find({ expect(err).toBeNull()
where: { name: 'environment' }, expect(environment).toBeDefined()
include: [ expect(environment.privateDomain).toBeDefined()
{ daoFactory: Domain, as: 'PrivateDomain' }, expect(environment.privateDomain.ip).toEqual('192.168.0.1')
{ daoFactory: Domain, as: 'PublicDomain' } expect(environment.publicDomain).toBeDefined()
] expect(environment.publicDomain.ip).toEqual('91.65.189.19')
}).complete(function(err, environment) { done()
expect(err).toBeNull()
expect(environment).toBeDefined()
expect(environment.privateDomain).toBeDefined()
expect(environment.privateDomain.ip).toEqual('192.168.0.1')
expect(environment.publicDomain).toBeDefined()
expect(environment.publicDomain.ip).toEqual('91.65.189.19')
done()
})
}) })
}) })
}) })
...@@ -1425,24 +1419,19 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1425,24 +1419,19 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
describe('hasOne', function() { describe('hasOne', function() {
before(function(done) { before(function(done) {
var self = this
this.Worker.hasOne(this.Task) this.Worker.hasOne(this.Task)
this.init(function() {
this.sequelize.sync({ force: true }).complete(function() { self.worker.setTask(self.task).success(done)
this.Worker.create({ name: 'worker' }).success(function(worker) { })
this.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker
this.task = task
this.worker.setTask(this.task).success(done)
}.bind(this))
}.bind(this))
}.bind(this))
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Task.find({ include: [ this.Worker ] }) expect(function() {
}.bind(this), 'Worker is not associated to Task!') self.Task.find({ include: [ self.Worker ] })
}).toThrow('Error', 'Worker is not associated to Task!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1455,36 +1444,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1455,36 +1444,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(worker.task).toBeDefined() expect(worker.task).toBeDefined()
expect(worker.task.title).toEqual('homework') expect(worker.task.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasOne with alias', function() { describe('hasOne with alias', function() {
before(function(done) { before(function(done) {
var self = this
this.Worker.hasOne(this.Task, { as: 'ToDo' }) this.Worker.hasOne(this.Task, { as: 'ToDo' })
this.init(function() {
this.sequelize.sync({ force: true }).complete(function() { self.worker.setToDo(self.task).success(done)
this.Worker.create({ name: 'worker' }).success(function(worker) { })
this.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker
this.task = task
this.worker.setToDo(this.task).success(done)
}.bind(this))
}.bind(this))
}.bind(this))
}) })
it('throws an error if included DaoFactory is not referenced by alias', function() { it('throws an error if included DaoFactory is not referenced by alias', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.find({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('throws an error if alias is not associated', function() { it('throws an error if alias is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ { daoFactory: this.Task, as: 'Work' } ] }) expect(function() {
}.bind(this), 'Task (Work) is not associated to Worker!') self.Worker.find({ include: [ { daoFactory: self.Task, as: 'Work' } ] })
}).toThrow('Error', 'Task (Work) is not associated to Worker!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1497,7 +1483,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1497,7 +1483,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(worker.toDo).toBeDefined() expect(worker.toDo).toBeDefined()
expect(worker.toDo.title).toEqual('homework') expect(worker.toDo.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) { it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
...@@ -1507,30 +1493,25 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1507,30 +1493,25 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}).complete(function(err, worker) { }).complete(function(err, worker) {
expect(worker.toDo.title).toEqual('homework') expect(worker.toDo.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasMany', function() { describe('hasMany', function() {
before(function(done) { before(function(done) {
var self = this
this.Worker.hasMany(this.Task) this.Worker.hasMany(this.Task)
this.init(function() {
this.sequelize.sync({ force: true }).complete(function() { self.worker.setTasks([ self.task ]).success(done)
this.Worker.create({ name: 'worker' }).success(function(worker) { })
this.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker
this.task = task
this.worker.setTasks([ this.task ]).success(done)
}.bind(this))
}.bind(this))
}.bind(this))
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Task.find({ include: [ this.Worker ] }) expect(function() {
}.bind(this), 'Worker is not associated to Task!') self.Task.find({ include: [ self.Worker ] })
}).toThrow('Error', 'Worker is not associated to Task!')
done()
}) })
it('returns the associated tasks via worker.tasks', function(done) { it('returns the associated tasks via worker.tasks', function(done) {
...@@ -1543,36 +1524,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1543,36 +1524,33 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(worker.tasks).toBeDefined() expect(worker.tasks).toBeDefined()
expect(worker.tasks[0].title).toEqual('homework') expect(worker.tasks[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasMany with alias', function() { describe('hasMany with alias', function() {
before(function(done) { before(function(done) {
var self = this
this.Worker.hasMany(this.Task, { as: 'ToDos' }) this.Worker.hasMany(this.Task, { as: 'ToDos' })
this.init(function() {
this.sequelize.sync({ force: true }).complete(function() { self.worker.setToDos([ self.task ]).success(done)
this.Worker.create({ name: 'worker' }).success(function(worker) { })
this.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker
this.task = task
this.worker.setToDos([ this.task ]).success(done)
}.bind(this))
}.bind(this))
}.bind(this))
}) })
it('throws an error if included DaoFactory is not referenced by alias', function() { it('throws an error if included DaoFactory is not referenced by alias', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.find({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('throws an error if alias is not associated', function() { it('throws an error if alias is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.find({ include: [ { daoFactory: this.Task, as: 'Work' } ] }) expect(function() {
}.bind(this), 'Task (Work) is not associated to Worker!') self.Worker.find({ include: [ { daoFactory: self.Task, as: 'Work' } ] })
}).toThrow('Error', 'Task (Work) is not associated to Worker!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1585,7 +1563,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1585,7 +1563,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(worker.toDos).toBeDefined() expect(worker.toDos).toBeDefined()
expect(worker.toDos[0].title).toEqual('homework') expect(worker.toDos[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) { it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
...@@ -1595,87 +1573,94 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1595,87 +1573,94 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}).complete(function(err, worker) { }).complete(function(err, worker) {
expect(worker.toDos[0].title).toEqual('homework') expect(worker.toDos[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
}) })
describe('queryOptions', function() { describe('queryOptions', function() {
before(function(done) { before(function(done) {
var self = this
this.User.create({ this.User.create({
username: 'barfooz' username: 'barfooz'
}).success(function(user) { }).success(function(user) {
this.user = user self.user = user
done() done()
}.bind(this)) })
}) })
it("should return a DAO when queryOptions are not set", function (done) { it("should return a DAO when queryOptions are not set", function(done) {
this.User.find({ where: { username: 'barfooz'}}).done(function (err, user) { var self = this
expect(user).toHavePrototype(this.User.DAO.prototype) this.User.find({ where: { username: 'barfooz'}}).done(function(err, user) {
expect(user).toHavePrototype(self.User.DAO.prototype)
done(); done()
}.bind(this)) })
}) })
it("should return a DAO when raw is false", function (done) { it("should return a DAO when raw is false", function(done) {
this.User.find({ where: { username: 'barfooz'}}, { raw: false }).done(function (err, user) { var self = this
expect(user).toHavePrototype(this.User.DAO.prototype) this.User.find({ where: { username: 'barfooz'}}, { raw: false }).done(function(err, user) {
expect(user).toHavePrototype(self.User.DAO.prototype)
done(); done()
}.bind(this)) })
}) })
it("should return raw data when raw is true", function (done) { it("should return raw data when raw is true", function(done) {
this.User.find({ where: { username: 'barfooz'}}, { raw: true }).done(function (err, user) { var self = this
expect(user).not.toHavePrototype(this.User.DAO.prototype) this.User.find({ where: { username: 'barfooz'}}, { raw: true }).done(function(err, user) {
expect(user).not.toHavePrototype(self.User.DAO.prototype)
expect(user).toBeObject() expect(user).toBeObject()
done()
done(); })
}.bind(this))
}) })
}) // - describe: queryOptions })
}) //- describe: find })
describe('findAll', function findAll() { describe('findAll', function() {
describe('eager loading', function() { describe('eager loading', function() {
before(function() {
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
})
describe('belongsTo', function() { describe('belongsTo', function() {
before(function(done) { before(function(done) {
var self = this
this.Task = this.sequelize.define('TaskBelongsTo', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Task.belongsTo(this.Worker) this.Task.belongsTo(this.Worker)
this.sequelize.sync({ force: true }).complete(function() { this.Worker.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Task.sync({ force: true }).success(function() {
this.Task.create({ title: 'homework' }).success(function(task) { self.Worker.create({ name: 'worker' }).success(function(worker) {
this.worker = worker self.Task.create({ title: 'homework' }).success(function(task) {
this.task = task self.worker = worker
self.task = task
this.task.setWorker(this.worker).success(done) self.task.setWorker(self.worker).success(done)
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
})
}) })
it('throws an error about unexpected input if include contains a non-object', function() { it('throws an error about unexpected input if include contains a non-object', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ 1 ] }) expect(function() {
}.bind(this), 'Include unexpected. Element has to be either an instance of DAOFactory or an object.') self.Worker.findAll({ include: [ 1 ] })
}).toThrow('Error', 'Include unexpected. Element has to be either an instance of DAOFactory or an object.')
done()
}) })
it('throws an error about missing attributes if include contains an object with daoFactory', function() { it('throws an error about missing attributes if include contains an object with daoFactory', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ { daoFactory: this.Worker } ] }) expect(function() {
}.bind(this), 'Include malformed. Expected attributes: daoFactory, as!') self.Worker.findAll({ include: [ { daoFactory: self.Worker } ] })
}).toThrow('Error', 'Include malformed. Expected attributes: daoFactory, as!')
done()
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.findAll({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('returns the associated worker via task.worker', function(done) { it('returns the associated worker via task.worker', function(done) {
...@@ -1688,30 +1673,36 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1688,30 +1673,36 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(tasks[0].worker).toBeDefined() expect(tasks[0].worker).toBeDefined()
expect(tasks[0].worker.name).toEqual('worker') expect(tasks[0].worker.name).toEqual('worker')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasOne', function() { describe('hasOne', function() {
before(function(done) { before(function(done) {
var self = this
this.Task = this.sequelize.define('TaskHasOne', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Worker.hasOne(this.Task) this.Worker.hasOne(this.Task)
this.Worker.sync({ force: true }).success(function() {
this.sequelize.sync({ force: true }).complete(function() { self.Task.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Worker.create({ name: 'worker' }).success(function(worker) {
this.Task.create({ title: 'homework' }).success(function(task) { self.Task.create({ title: 'homework' }).success(function(task) {
this.worker = worker self.worker = worker
this.task = task self.task = task
this.worker.setTask(this.task).success(done) self.worker.setTaskHasOne(self.task).success(done)
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
})
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Task.findAll({ include: [ this.Worker ] }) expect(function() {
}.bind(this), 'Worker is not associated to Task!') self.Task.findAll({ include: [ self.Worker ] })
}).toThrow('Error', 'Worker is not associated to Task!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1721,39 +1712,48 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1721,39 +1712,48 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}).complete(function(err, workers) { }).complete(function(err, workers) {
expect(err).toBeNull() expect(err).toBeNull()
expect(workers).toBeDefined() expect(workers).toBeDefined()
expect(workers[0].task).toBeDefined() expect(workers[0].taskHasOne).toBeDefined()
expect(workers[0].task.title).toEqual('homework') expect(workers[0].taskHasOne.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasOne with alias', function() { describe('hasOne with alias', function() {
before(function(done) { before(function(done) {
var self = this
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Worker.hasOne(this.Task, { as: 'ToDo' }) this.Worker.hasOne(this.Task, { as: 'ToDo' })
this.sequelize.sync({ force: true }).complete(function() { this.Worker.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Task.sync({ force: true }).success(function() {
this.Task.create({ title: 'homework' }).success(function(task) { self.Worker.create({ name: 'worker' }).success(function(worker) {
this.worker = worker self.Task.create({ title: 'homework' }).success(function(task) {
this.task = task self.worker = worker
self.task = task
this.worker.setToDo(this.task).success(done) self.worker.setToDo(self.task).success(done)
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
})
}) })
it('throws an error if included DaoFactory is not referenced by alias', function() { it('throws an error if included DaoFactory is not referenced by alias', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.findAll({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('throws an error if alias is not associated', function() { it('throws an error if alias is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ { daoFactory: this.Task, as: 'Work' } ] }) expect(function() {
}.bind(this), 'Task (Work) is not associated to Worker!') self.Worker.findAll({ include: [ { daoFactory: self.Task, as: 'Work' } ] })
}).toThrow('Error', 'Task (Work) is not associated to Worker!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1766,7 +1766,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1766,7 +1766,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(workers[0].toDo).toBeDefined() expect(workers[0].toDo).toBeDefined()
expect(workers[0].toDo.title).toEqual('homework') expect(workers[0].toDo.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) { it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
...@@ -1776,30 +1776,37 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1776,30 +1776,37 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}).complete(function(err, workers) { }).complete(function(err, workers) {
expect(workers[0].toDo.title).toEqual('homework') expect(workers[0].toDo.title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasMany', function() { describe('hasMany', function() {
before(function(done) { before(function(done) {
var self = this
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Worker.hasMany(this.Task) this.Worker.hasMany(this.Task)
this.sequelize.sync({ force: true }).complete(function() { this.Worker.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Task.sync({ force: true }).success(function() {
this.Task.create({ title: 'homework' }).success(function(task) { self.Worker.create({ name: 'worker' }).success(function(worker) {
this.worker = worker self.Task.create({ title: 'homework' }).success(function(task) {
this.task = task self.worker = worker
self.task = task
this.worker.setTasks([ this.task ]).success(done) self.worker.setTasks([ self.task ]).success(done)
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
})
}) })
it('throws an error if included DaoFactory is not associated', function() { it('throws an error if included DaoFactory is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Task.findAll({ include: [ this.Worker ] }) expect(function() {
}.bind(this), 'Worker is not associated to Task!') self.Task.findAll({ include: [ self.Worker ] })
}).toThrow('Error', 'Worker is not associated to Task!')
done()
}) })
it('returns the associated tasks via worker.tasks', function(done) { it('returns the associated tasks via worker.tasks', function(done) {
...@@ -1812,36 +1819,45 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1812,36 +1819,45 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(workers[0].tasks).toBeDefined() expect(workers[0].tasks).toBeDefined()
expect(workers[0].tasks[0].title).toEqual('homework') expect(workers[0].tasks[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('hasMany with alias', function() { describe('hasMany with alias', function() {
before(function(done) { before(function(done) {
var self = this
this.Task = this.sequelize.define('Task', { title: Sequelize.STRING })
this.Worker = this.sequelize.define('Worker', { name: Sequelize.STRING })
this.Worker.hasMany(this.Task, { as: 'ToDos' }) this.Worker.hasMany(this.Task, { as: 'ToDos' })
this.sequelize.sync({ force: true }).complete(function() { this.Worker.sync({ force: true }).success(function() {
this.Worker.create({ name: 'worker' }).success(function(worker) { self.Task.sync({ force: true }).success(function() {
this.Task.create({ title: 'homework' }).success(function(task) { self.Worker.create({ name: 'worker' }).success(function(worker) {
this.worker = worker self.Task.create({ title: 'homework' }).success(function(task) {
this.task = task self.worker = worker
self.task = task
this.worker.setToDos([ this.task ]).success(done) self.worker.setToDos([ self.task ]).success(done)
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
})
}) })
it('throws an error if included DaoFactory is not referenced by alias', function() { it('throws an error if included DaoFactory is not referenced by alias', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ this.Task ] }) expect(function() {
}.bind(this), 'Task is not associated to Worker!') self.Worker.findAll({ include: [ self.Task ] })
}).toThrow('Error', 'Task is not associated to Worker!')
done()
}) })
it('throws an error if alias is not associated', function() { it('throws an error if alias is not associated', function(done) {
Helpers.assertException(function() { var self = this
this.Worker.findAll({ include: [ { daoFactory: this.Task, as: 'Work' } ] }) expect(function() {
}.bind(this), 'Task (Work) is not associated to Worker!') self.Worker.findAll({ include: [ { daoFactory: self.Task, as: 'Work' } ] })
}).toThrow('Error', 'Task (Work) is not associated to Worker!')
done()
}) })
it('returns the associated task via worker.task', function(done) { it('returns the associated task via worker.task', function(done) {
...@@ -1854,7 +1870,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1854,7 +1870,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
expect(workers[0].toDos).toBeDefined() expect(workers[0].toDos).toBeDefined()
expect(workers[0].toDos[0].title).toEqual('homework') expect(workers[0].toDos[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) { it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
...@@ -1864,56 +1880,56 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1864,56 +1880,56 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}).complete(function(err, workers) { }).complete(function(err, workers) {
expect(workers[0].toDos[0].title).toEqual('homework') expect(workers[0].toDos[0].title).toEqual('homework')
done() done()
}.bind(this)) })
}) })
}) })
describe('queryOptions', function() { describe('queryOptions', function() {
before(function(done) { before(function(done) {
var self = this
this.User.create({ this.User.create({
username: 'barfooz' username: 'barfooz'
}).success(function(user) { }).success(function(user) {
this.user = user self.user = user
done() done()
}.bind(this)) })
}) })
it("should return a DAO when queryOptions are not set", function (done) { it("should return a DAO when queryOptions are not set", function(done) {
this.User.findAll({ where: { username: 'barfooz'}}).done(function (err, users) { var self = this
this.User.findAll({ where: { username: 'barfooz'}}).done(function(err, users) {
users.forEach(function (user) { users.forEach(function (user) {
expect(user).toHavePrototype(this.User.DAO.prototype) expect(user).toHavePrototype(self.User.DAO.prototype)
}, this) })
done()
})
done();
}.bind(this))
}) })
it("should return a DAO when raw is false", function (done) { it("should return a DAO when raw is false", function(done) {
this.User.findAll({ where: { username: 'barfooz'}}, { raw: false }).done(function (err, users) { var self = this
this.User.findAll({ where: { username: 'barfooz'}}, { raw: false }).done(function(err, users) {
users.forEach(function (user) { users.forEach(function (user) {
expect(user).toHavePrototype(this.User.DAO.prototype) expect(user).toHavePrototype(self.User.DAO.prototype)
}, this) })
done()
done(); })
}.bind(this))
}) })
it("should return raw data when raw is true", function (done) { it("should return raw data when raw is true", function(done) {
this.User.findAll({ where: { username: 'barfooz'}}, { raw: true }).done(function (err, users) { var self = this
users.forEach(function (user) { this.User.findAll({ where: { username: 'barfooz'}}, { raw: true }).done(function(err, users) {
expect(user).not.toHavePrototype(this.User.DAO.prototype) users.forEach(function(user) {
expect(user).not.toHavePrototype(self.User.DAO.prototype)
expect(users[0]).toBeObject() expect(users[0]).toBeObject()
}, this) })
done()
done(); })
}.bind(this))
}) })
}) // - describe: queryOptions })
}) })
describe('normal findAll', function() { describe('normal findAll', function() {
beforeEach(function(done) { before(function(done) {
var self = this var self = this
this.User.create({username: 'user', data: 'foobar', theDate: moment().toDate()}).success(function(user) { this.User.create({username: 'user', data: 'foobar', theDate: moment().toDate()}).success(function(user) {
self.User.create({username: 'user2', data: 'bar', theDate: moment().toDate()}).success(function(user2){ self.User.create({username: 'user2', data: 'bar', theDate: moment().toDate()}).success(function(user2){
...@@ -1982,10 +1998,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -1982,10 +1998,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
}) })
}) })
}) //- describe: findAll })
describe('findAndCountAll', function() { describe('findAndCountAll', function() {
beforeEach(function(done) { before(function(done) {
var self = this var self = this
this.User.bulkCreate([ this.User.bulkCreate([
{username: 'user', data: 'foobar'}, {username: 'user', data: 'foobar'},
...@@ -2046,7 +2062,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2046,7 +2062,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
describe('all', function() { describe('all', function() {
beforeEach(function(done) { before(function(done) {
this.User.bulkCreate([ this.User.bulkCreate([
{username: 'user', data: 'foobar'}, {username: 'user', data: 'foobar'},
{username: 'user2', data: 'bar'} {username: 'user2', data: 'bar'}
...@@ -2079,7 +2095,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2079,7 +2095,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
bio: Sequelize.TEXT bio: Sequelize.TEXT
}) })
this.sequelize.sync({ force: true }).success(function() { userKeys.sync({ force: true }).success(function() {
userKeys.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).success(function(u) { userKeys.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).success(function(u) {
expect(u.equals(u)).toBeTruthy() expect(u.equals(u)).toBeTruthy()
done() done()
...@@ -2092,7 +2108,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2092,7 +2108,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
describe('equalsOneOf', function() { describe('equalsOneOf', function() {
// sqlite can't handle multiple primary keys // sqlite can't handle multiple primary keys
if (dialect !== "sqlite") { if (dialect !== "sqlite") {
beforeEach(function(done) { before(function(done) {
this.userKey = this.sequelize.define('userKeys', { this.userKey = this.sequelize.define('userKeys', {
foo: {type: Sequelize.STRING, primaryKey: true}, foo: {type: Sequelize.STRING, primaryKey: true},
bar: {type: Sequelize.STRING, primaryKey: true}, bar: {type: Sequelize.STRING, primaryKey: true},
...@@ -2100,7 +2116,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2100,7 +2116,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
bio: Sequelize.TEXT bio: Sequelize.TEXT
}) })
this.sequelize.sync({ force: true }).success(done) this.userKey.sync({ force: true }).success(done)
}) })
it('determines equality if one is matching', function(done) { it('determines equality if one is matching', function(done) {
...@@ -2122,12 +2138,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2122,12 +2138,10 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
describe('count', function() { describe('count', function() {
it('counts all created objects', function(done) { it('counts all created objects', function(done) {
var self = this var self = this
this.User.create({username: 'user1'}).success(function() { this.User.bulkCreate([{username: 'user1'}, {username: 'user2'}]).success(function() {
self.User.create({username: 'user2'}).success(function() { self.User.count().success(function(count) {
self.User.count().success(function(count) { expect(count).toEqual(2)
expect(count).toEqual(2) done()
done()
})
}) })
}) })
}) })
...@@ -2155,6 +2169,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2155,6 +2169,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
describe('min', function() { describe('min', function() {
before(function(done) { before(function(done) {
var self = this
this.UserWithAge = this.sequelize.define('UserWithAge', { this.UserWithAge = this.sequelize.define('UserWithAge', {
age: Sequelize.INTEGER age: Sequelize.INTEGER
}) })
...@@ -2164,19 +2179,18 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2164,19 +2179,18 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
this.UserWithAge.sync({ force: true }).success(function(){ this.UserWithAge.sync({ force: true }).success(function(){
this.UserWithDec.sync({ force: true }).success(done) self.UserWithDec.sync({ force: true }).success(done)
}.bind(this)) })
}) })
it("should return the min value", function(done) { it("should return the min value", function(done) {
this.UserWithAge.create({ age: 2 }).success(function() { var self = this
this.UserWithAge.create({ age: 3 }).success(function() { this.UserWithAge.bulkCreate([{age: 3}, { age: 2 }]).success(function() {
this.UserWithAge.min('age').success(function(min) { self.UserWithAge.min('age').success(function(min) {
expect(min).toEqual(2) expect(min).toEqual(2)
done() done()
}) })
}.bind(this)) })
}.bind(this))
}) })
it('allows sql logging', function(done) { it('allows sql logging', function(done) {
...@@ -2188,19 +2202,19 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2188,19 +2202,19 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
it("should allow decimals in min", function(done){ it("should allow decimals in min", function(done){
this.UserWithDec.create({value: 3.5}).success(function(){ var self = this
this.UserWithDec.create({ value: 5.5 }).success(function(){ this.UserWithDec.bulkCreate([{value: 5.5}, {value: 3.5}]).success(function(){
this.UserWithDec.min('value').success(function(min){ self.UserWithDec.min('value').success(function(min){
expect(min).toEqual(3.5) expect(min).toEqual(3.5)
done() done()
}) })
}.bind(this)) })
}.bind(this))
}) })
}) //- describe: min })
describe('max', function() { describe('max', function() {
before(function(done) { before(function(done) {
var self = this
this.UserWithAge = this.sequelize.define('UserWithAge', { this.UserWithAge = this.sequelize.define('UserWithAge', {
age: Sequelize.INTEGER, age: Sequelize.INTEGER,
order: Sequelize.INTEGER order: Sequelize.INTEGER
...@@ -2211,39 +2225,38 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2211,39 +2225,38 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
}) })
this.UserWithAge.sync({ force: true }).success(function(){ this.UserWithAge.sync({ force: true }).success(function(){
this.UserWithDec.sync({ force: true }).success(done) self.UserWithDec.sync({ force: true }).success(done)
}.bind(this)) })
}) })
it("should return the max value for a field named the same as an SQL reserved keyword", function(done) { it("should return the max value for a field named the same as an SQL reserved keyword", function(done) {
this.UserWithAge.create({age: 3, order: 5}).success(function(){ var self = this
this.UserWithAge.max('order').success(function(max) { this.UserWithAge.bulkCreate([{age: 2, order: 3}, {age: 3, order: 5}]).success(function(){
self.UserWithAge.max('order').success(function(max) {
expect(max).toEqual(5) expect(max).toEqual(5)
done() done()
}) })
}.bind(this)) })
}) })
it("should return the max value", function(done) { it("should return the max value", function(done) {
this.UserWithAge.create({ age: 2 }).success(function() { var self = this
this.UserWithAge.create({ age: 3 }).success(function() { self.UserWithAge.bulkCreate([{age: 2}, {age: 3}]).success(function() {
this.UserWithAge.max('age').success(function(max) { self.UserWithAge.max('age').success(function(max) {
expect(max).toEqual(3) expect(max).toEqual(3)
done() done()
}) })
}.bind(this)) })
}.bind(this))
}) })
it("should allow decimals in max", function(done){ it("should allow decimals in max", function(done) {
this.UserWithDec.create({value: 3.5}).success(function(){ var self = this
this.UserWithDec.create({ value: 5.5 }).success(function(){ this.UserWithDec.bulkCreate([{value: 3.5}, {value: 5.5}]).success(function(){
this.UserWithDec.max('value').success(function(max){ self.UserWithDec.max('value').success(function(max){
expect(max).toEqual(5.5) expect(max).toEqual(5.5)
done() done()
}) })
}.bind(this)) })
}.bind(this))
}) })
it('allows sql logging', function(done) { it('allows sql logging', function(done) {
...@@ -2253,7 +2266,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2253,7 +2266,7 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
done() done()
}) })
}) })
}) //- describe: max })
describe('schematic support', function() { describe('schematic support', function() {
before(function(done){ before(function(done){
...@@ -2342,19 +2355,20 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2342,19 +2355,20 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
} }
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('references', function() { describe('references', function() {
before(function() { before(function(done) {
this.Author = this.sequelize.define('author', { firstName: Sequelize.STRING }) this.Author = this.sequelize.define('author', { firstName: Sequelize.STRING })
done()
}) })
describe("use of existing dao factory", function() { describe("use of existing dao factory", function() {
before(function() { before(function(done) {
this.Post = this.sequelize.define('post', { this.Post = this.sequelize.define('post', {
title: Sequelize.STRING, title: Sequelize.STRING,
authorId: { authorId: {
...@@ -2366,11 +2380,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2366,11 +2380,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.Author.hasMany(this.Post) this.Author.hasMany(this.Post)
this.Post.belongsTo(this.Author) this.Post.belongsTo(this.Author)
done()
}) })
it('references the author table', function(done) { it('references the author table', function(done) {
var self = this
this.Author.sync({ force: true }).success(function() { this.Author.sync({ force: true }).success(function() {
this.Post.sync({ force: true }).on('sql', function(sql) { self.Post.sync({ force: true }).on('sql', function(sql) {
if (dialect === 'postgres') { if (dialect === 'postgres') {
expect(sql).toMatch(/"authorId" INTEGER REFERENCES "authors" \("id"\)/) expect(sql).toMatch(/"authorId" INTEGER REFERENCES "authors" \("id"\)/)
} else if (dialect === 'mysql') { } else if (dialect === 'mysql') {
...@@ -2383,12 +2399,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2383,12 +2399,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
done() done()
}) })
}.bind(this)) })
}) })
}) })
describe('use of table name as string', function() { describe('use of table name as string', function() {
before(function() { before(function(done) {
this.Post = this.sequelize.define('post', { this.Post = this.sequelize.define('post', {
title: Sequelize.STRING, title: Sequelize.STRING,
authorId: { authorId: {
...@@ -2400,11 +2416,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2400,11 +2416,13 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.Author.hasMany(this.Post) this.Author.hasMany(this.Post)
this.Post.belongsTo(this.Author) this.Post.belongsTo(this.Author)
done()
}) })
it('references the author table', function(done) { it('references the author table', function(done) {
var self = this
this.Author.sync({ force: true }).success(function() { this.Author.sync({ force: true }).success(function() {
this.Post.sync({ force: true }).on('sql', function(sql) { self.Post.sync({ force: true }).on('sql', function(sql) {
if (dialect === 'postgres') { if (dialect === 'postgres') {
expect(sql).toMatch(/"authorId" INTEGER REFERENCES "authors" \("id"\)/) expect(sql).toMatch(/"authorId" INTEGER REFERENCES "authors" \("id"\)/)
} else if (dialect === 'mysql') { } else if (dialect === 'mysql') {
...@@ -2417,12 +2435,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2417,12 +2435,12 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
done() done()
}) })
}.bind(this)) })
}) })
}) })
describe('use of invalid table name', function() { describe('use of invalid table name', function() {
before(function() { before(function(done) {
this.Post = this.sequelize.define('post', { this.Post = this.sequelize.define('post', {
title: Sequelize.STRING, title: Sequelize.STRING,
authorId: { authorId: {
...@@ -2434,37 +2452,38 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -2434,37 +2452,38 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
this.Author.hasMany(this.Post) this.Author.hasMany(this.Post)
this.Post.belongsTo(this.Author) this.Post.belongsTo(this.Author)
done()
}) })
it("emits the error event as the referenced table name is invalid", function(done) { it("emits the error event as the referenced table name is invalid", function(done) {
this.timeout = 1500
var self = this
this.Author.sync({ force: true }).success(function() { this.Author.sync({ force: true }).success(function() {
this.Post self.Post.sync({ force: true }).success(function() {
.sync({ force: true }) if (dialect === 'sqlite') {
.success(function() { // sorry ... but sqlite is too stupid to understand whats going on ...
if (dialect === 'sqlite') { expect(1).toEqual(1)
// sorry ... but sqlite is too stupid to understand whats going on ...
expect(1).toEqual(1)
done()
} else {
// the parser should not end up here ...
expect(2).toEqual(1)
}
}).error(function(err) {
if (dialect === 'mysql') {
expect(err.message).toMatch(/ER_CANT_CREATE_TABLE/)
} else if (dialect === 'sqlite') {
// the parser should not end up here ... see above
expect(1).toEqual(2)
} else if (dialect === 'postgres') {
expect(err.message).toMatch(/relation "4uth0r5" does not exist/)
} else {
throw new Error('Undefined dialect!')
}
done() done()
}) } else {
}.bind(this)) // the parser should not end up here ...
expect(2).toEqual(1)
}
}).error(function(err) {
if (dialect === 'mysql') {
expect(err.message).toMatch(/ER_CANNOT_ADD_FOREIGN/)
} else if (dialect === 'sqlite') {
// the parser should not end up here ... see above
expect(1).toEqual(2)
} else if (dialect === 'postgres') {
expect(err.message).toMatch(/relation "4uth0r5" does not exist/)
} else {
throw new Error('Undefined dialect!')
}
done()
})
})
}) })
}) })
}) //- describe: references })
}) })
if (typeof require === 'function') { /* jshint camelcase: false */
const buster = require("buster") var buster = require("buster")
, Helpers = require('./buster-helpers') , Helpers = require('./buster-helpers')
, dialect = Helpers.getTestDialect() , dialect = Helpers.getTestDialect()
, Sequelize = require("../index") , config = require(__dirname + "/config/config")
, config = require(__dirname + "/config/config") , DataTypes = require(__dirname + "/../lib/data-types")
, _ = require('lodash') , _ = require('lodash')
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("DAO"), function() { describe(Helpers.getTestDialectTeaser("DAO"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
, User = sequelize.define('User', {
username: { type: DataTypes.STRING },
touchedAt: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
aNumber: { type: DataTypes.INTEGER },
bNumber: { type: DataTypes.INTEGER },
validateTest: {
type: DataTypes.INTEGER,
allowNull: true,
validate: {isInt: true}
},
validateCustom: {
type: DataTypes.STRING,
allowNull: true,
validate: {len: {msg: 'Length failed.', args: [1,20]}}
},
dateAllowNullTrue: {
type: DataTypes.DATE,
allowNull: true
}
})
before(function(done) { before(function(done) {
var self = this var self = this
Helpers.initTests({ self.sequelize = sequelize
dialect: dialect, self.User = User
beforeComplete: function(sequelize, DataTypes) { Helpers.clearDatabase(this.sequelize, function(){
self.sequelize = sequelize self.User.sync({ force: true }).success(done)
self.User = sequelize.define('User', {
username: { type: DataTypes.STRING },
touchedAt: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
aNumber: { type: DataTypes.INTEGER },
bNumber: { type: DataTypes.INTEGER },
validateTest: {
type: DataTypes.INTEGER,
allowNull: true,
validate: {isInt: true}
},
validateCustom: {
type: DataTypes.STRING,
allowNull: true,
validate: {len: {msg: 'Length failed.', args: [1,20]}}
},
dateAllowNullTrue: {
type: DataTypes.DATE,
allowNull: true
}
})
self.User2 = sequelize.define('User2', {
username: DataTypes.STRING,
updatedAt: DataTypes.DATE
}, {
timestamps: false
})
self.HistoryLog = sequelize.define('HistoryLog', {
someText: { type: DataTypes.STRING },
aNumber: { type: DataTypes.INTEGER },
aRandomId: { type: DataTypes.INTEGER }
})
self.ParanoidUser = sequelize.define('ParanoidUser', {
username: { type: DataTypes.STRING }
}, {
paranoid: true
})
self.ParanoidUser.hasOne( self.ParanoidUser )
},
onComplete: function() {
self.User.sync({ force: true }).success(function(){
self.HistoryLog.sync({ force: true }).success(function(){
self.ParanoidUser.sync({force: true }).success(done)
})
})
}
}) })
}) })
...@@ -78,6 +50,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -78,6 +50,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
// But this causes sqlite to fail and exits the entire test suite immediately // But this causes sqlite to fail and exits the entire test suite immediately
var bio = dialect + "'\"\n" // Need to add the dialect here so in case of failure I know what DB it failed for var bio = dialect + "'\"\n" // Need to add the dialect here so in case of failure I know what DB it failed for
, self = this , self = this
this.User.create({ username: bio }).success(function(u1) { this.User.create({ username: bio }).success(function(u1) {
self.User.find(u1.id).success(function(u2) { self.User.find(u1.id).success(function(u2) {
expect(u2.username).toEqual(bio) expect(u2.username).toEqual(bio)
...@@ -122,14 +95,14 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -122,14 +95,14 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
it("returns false for objects found by findAll method", function(done) { it("returns false for objects found by findAll method", function(done) {
var chainer = new Sequelize.Utils.QueryChainer() var self = this
, self = this , users = []
for (var i = 0; i < 10; i++) { for (var i = 0; i < 10; i++) {
chainer.add(self.User.create({ username: 'user' })) users[users.length] = {username: 'user'}
} }
chainer.run().success(function() { this.User.bulkCreate(users).success(function() {
self.User.findAll().success(function(users) { self.User.findAll().success(function(users) {
users.forEach(function(u) { users.forEach(function(u) {
expect(u.isNewRecord).toBeFalsy() expect(u.isNewRecord).toBeFalsy()
...@@ -141,226 +114,206 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -141,226 +114,206 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
describe('increment', function () { describe('increment', function () {
before(function (done) { before(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done) this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done)
}); })
it('with array', function (done) {
var self = this;
// Select something it('with array', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.increment(['aNumber'], 2).done(function (err, user2) { this.User.find(1).done(function(err, user1) {
self.User.find(1).done(function (err, user3) { user1.increment(['aNumber'], 2).done(function() {
expect(user3.aNumber).toBe(2); self.User.find(1).done(function(err, user3) {
done(); expect(user3.aNumber).toBe(2)
}); done()
}); })
}); })
}); })
})
it('with single field', function (done) { it('with single field', function(done) {
var self = this; var self = this
this.User.find(1).done(function(err, user1) {
user1.increment('aNumber', 2).done(function() {
self.User.find(1).done(function(err, user3) {
expect(user3.aNumber).toBe(2)
done()
})
})
})
})
// Select something it('should still work right with other concurrent updates', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.increment('aNumber', 2).done(function (err, user2) {
self.User.find(1).done(function (err, user3) {
expect(user3.aNumber).toBe(2);
done();
});
});
});
});
it('should still work right with other concurrent updates', function (done) {
var self = this;
// Select something
this.User.find(1).done(function (err, user1) { this.User.find(1).done(function (err, user1) {
// Select the user again (simulating a concurrent query) // Select the user again (simulating a concurrent query)
self.User.find(1).done(function (err, user2) { self.User.find(1).done(function (err, user2) {
user2.updateAttributes({ user2.updateAttributes({
aNumber: user2.aNumber + 1 aNumber: user2.aNumber + 1
}).done(function (err, user3) { }).done(function () {
user1.increment(['aNumber'], 2).done(function (err, user4) { user1.increment(['aNumber'], 2).done(function() {
self.User.find(1).done(function (err, user5) { self.User.find(1).done(function(err, user5) {
expect(user5.aNumber).toBe(3); expect(user5.aNumber).toBe(3)
done(); done()
}); })
}); })
});
});
});
});
it('should still work right with other concurrent increments', function (done) {
var self = this;
// Select something
this.User.find(1).done(function (err, user1) {
var _done = _.after(3, function () {
self.User.find(1).done(function (err, user2) {
expect(user2.aNumber).toEqual(6);
done();
}) })
}); })
})
})
user1.increment(['aNumber'], 2).done(_done); it('should still work right with other concurrent increments', function(done) {
user1.increment(['aNumber'], 2).done(_done); var self = this
user1.increment(['aNumber'], 2).done(_done); this.User.find(1).done(function(err, user1) {
}); var _done = _.after(3, function() {
}); self.User.find(1).done(function(err, user2) {
expect(user2.aNumber).toEqual(6)
done()
})
})
it('with key value pair', function (done) { user1.increment(['aNumber'], 2).done(_done)
var self = this; user1.increment(['aNumber'], 2).done(_done)
user1.increment(['aNumber'], 2).done(_done)
})
})
// Select something it('with key value pair', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.increment({ 'aNumber': 1, 'bNumber': 2}).done(function (err, user2) { this.User.find(1).done(function(err, user1) {
user1.increment({ 'aNumber': 1, 'bNumber': 2}).done(function() {
self.User.find(1).done(function (err, user3) { self.User.find(1).done(function (err, user3) {
expect(user3.aNumber).toBe(1); expect(user3.aNumber).toBe(1)
expect(user3.bNumber).toBe(2); expect(user3.bNumber).toBe(2)
done(); done()
}); })
}); })
}); })
}); })
}); })
describe('decrement', function () { describe('decrement', function () {
before(function (done) { before(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done) this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done)
}); })
it('with array', function (done) {
var self = this;
// Select something it('with array', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.decrement(['aNumber'], 2).done(function (err, user2) { this.User.find(1).done(function(err, user1) {
self.User.find(1).done(function (err, user3) { user1.decrement(['aNumber'], 2).done(function() {
expect(user3.aNumber).toBe(-2); self.User.find(1).done(function(err, user3) {
done(); expect(user3.aNumber).toBe(-2)
}); done()
}); })
}); })
}); })
})
it('with single field', function (done) { it('with single field', function(done) {
var self = this; var self = this
this.User.find(1).done(function(err, user1) {
user1.decrement('aNumber', 2).done(function() {
self.User.find(1).done(function(err, user3) {
expect(user3.aNumber).toBe(-2)
done()
})
})
})
})
// Select something it('should still work right with other concurrent updates', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.decrement('aNumber', 2).done(function (err, user2) { this.User.find(1).done(function(err, user1) {
self.User.find(1).done(function (err, user3) {
expect(user3.aNumber).toBe(-2);
done();
});
});
});
});
it('should still work right with other concurrent updates', function (done) {
var self = this;
// Select something
this.User.find(1).done(function (err, user1) {
// Select the user again (simulating a concurrent query) // Select the user again (simulating a concurrent query)
self.User.find(1).done(function (err, user2) { self.User.find(1).done(function(err, user2) {
user2.updateAttributes({ user2.updateAttributes({
aNumber: user2.aNumber + 1 aNumber: user2.aNumber + 1
}).done(function (err, user3) { }).done(function () {
user1.decrement(['aNumber'], 2).done(function (err, user4) { user1.decrement(['aNumber'], 2).done(function() {
self.User.find(1).done(function (err, user5) { self.User.find(1).done(function(err, user5) {
expect(user5.aNumber).toBe(-1); expect(user5.aNumber).toBe(-1)
done(); done()
}); })
}); })
});
});
});
});
it('should still work right with other concurrent increments', function (done) {
var self = this;
// Select something
this.User.find(1).done(function (err, user1) {
var _done = _.after(3, function () {
self.User.find(1).done(function (err, user2) {
expect(user2.aNumber).toEqual(-6);
done();
}) })
}); })
})
})
user1.decrement(['aNumber'], 2).done(_done); it('should still work right with other concurrent increments', function(done) {
user1.decrement(['aNumber'], 2).done(_done); var self = this
user1.decrement(['aNumber'], 2).done(_done); this.User.find(1).done(function(err, user1) {
}); var _done = _.after(3, function() {
}); self.User.find(1).done(function (err, user2) {
expect(user2.aNumber).toEqual(-6)
done()
})
})
it('with key value pair', function (done) { user1.decrement(['aNumber'], 2).done(_done)
var self = this; user1.decrement(['aNumber'], 2).done(_done)
user1.decrement(['aNumber'], 2).done(_done)
})
})
// Select something it('with key value pair', function(done) {
this.User.find(1).done(function (err, user1) { var self = this
user1.decrement({ 'aNumber': 1, 'bNumber': 2}).done(function (err, user2) { this.User.find(1).done(function(err, user1) {
self.User.find(1).done(function (err, user3) { user1.decrement({ 'aNumber': 1, 'bNumber': 2}).done(function() {
expect(user3.aNumber).toBe(-1); self.User.find(1).done(function(err, user3) {
expect(user3.bNumber).toBe(-2); expect(user3.aNumber).toBe(-1)
done(); expect(user3.bNumber).toBe(-2)
}); done()
}); })
}); })
}); })
}); })
})
describe('reload', function () { describe('reload', function () {
it("should return a reference to the same DAO instead of creating a new one", function (done) { it("should return a reference to the same DAO instead of creating a new one", function(done) {
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) { this.User.create({ username: 'John Doe' }).done(function(err, originalUser) {
originalUser.updateAttributes({ username: 'Doe John' }).done(function() {
originalUser.updateAttributes({ username: 'Doe John' }).done(function () {
originalUser.reload().done(function (err, updatedUser) { originalUser.reload().done(function (err, updatedUser) {
expect(originalUser === updatedUser).toBeTrue() expect(originalUser === updatedUser).toBeTrue()
done(); done()
}) })
}) })
}) })
}) })
it("should update the values on all references to the DAO", function (done) { it("should update the values on all references to the DAO", function(done) {
var self = this var self = this
this.User.create({ username: 'John Doe' }).done(function(err, originalUser) {
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) { self.User.find(originalUser.id).done(function(err, updater) {
self.User.find(originalUser.id).done(function (err, updater) { updater.updateAttributes({ username: 'Doe John' }).done(function() {
updater.updateAttributes({ username: 'Doe John' }).done(function () {
// We used a different reference when calling updateAttributes, so originalUser is now out of sync // We used a different reference when calling updateAttributes, so originalUser is now out of sync
expect(originalUser.username).toEqual('John Doe') expect(originalUser.username).toEqual('John Doe')
originalUser.reload().done(function (err, updatedUser) { originalUser.reload().done(function(err, updatedUser) {
expect(originalUser.username).toEqual('Doe John') expect(originalUser.username).toEqual('Doe John')
expect(updatedUser.username).toEqual('Doe John') expect(updatedUser.username).toEqual('Doe John')
done()
done();
}) })
}) })
}) })
}) })
}) })
it("should update read only attributes as well (updatedAt)", function (done) { it("should update read only attributes as well (updatedAt)", function(done) {
var self = this var self = this
this.timeout = 2000; this.timeout = 2000
this.User.create({ username: 'John Doe' }).done(function (err, originalUser) { this.User.create({ username: 'John Doe' }).done(function(err, originalUser) {
var originallyUpdatedAt = originalUser.updatedAt var originallyUpdatedAt = originalUser.updatedAt
// Wait for a second, so updatedAt will actually be different // Wait for a second, so updatedAt will actually be different
setTimeout(function () { setTimeout(function () {
self.User.find(originalUser.id).done(function (err, updater) { self.User.find(originalUser.id).done(function(err, updater) {
updater.updateAttributes({ username: 'Doe John' }).done(function () { updater.updateAttributes({ username: 'Doe John' }).done(function () {
originalUser.reload().done(function (err, updatedUser) { originalUser.reload().done(function(err, updatedUser) {
expect(originalUser.updatedAt).toBeGreaterThan(originallyUpdatedAt) expect(originalUser.updatedAt).toBeGreaterThan(originallyUpdatedAt)
expect(updatedUser.updatedAt).toBeGreaterThan(originallyUpdatedAt) expect(updatedUser.updatedAt).toBeGreaterThan(originallyUpdatedAt)
done()
done();
}) })
}) })
}) })
...@@ -375,51 +328,53 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -375,51 +328,53 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
Book.hasMany(Page) Book.hasMany(Page)
Page.belongsTo(Book) Page.belongsTo(Book)
this.sequelize.sync({ force: true }).success(function() { Book.sync().success(function() {
Book.create({ title: 'A very old book' }).success(function(book) { Page.sync().success(function() {
Page.create({ content: 'om nom nom' }).success(function(page) { Book.create({ title: 'A very old book' }).success(function(book) {
book.setPages([ page ]).success(function() { Page.create({ content: 'om nom nom' }).success(function(page) {
Book.find({ book.setPages([ page ]).success(function() {
where: (dialect === 'postgres' ? '"Books"."id"=' : '`Books`.`id`=') + book.id, Book.find({
include: [Page] where: (dialect === 'postgres' ? '"Books"."id"=' : '`Books`.`id`=') + book.id,
}).success(function(leBook) { include: [Page]
page.updateAttributes({ content: 'something totally different' }).success(function(page) { }).success(function(leBook) {
expect(leBook.pages[0].content).toEqual('om nom nom') page.updateAttributes({ content: 'something totally different' }).success(function(page) {
expect(page.content).toEqual('something totally different') expect(leBook.pages[0].content).toEqual('om nom nom')
leBook.reload().success(function(leBook) {
expect(leBook.pages[0].content).toEqual('something totally different')
expect(page.content).toEqual('something totally different') expect(page.content).toEqual('something totally different')
done() leBook.reload().success(function(leBook) {
expect(leBook.pages[0].content).toEqual('something totally different')
expect(page.content).toEqual('something totally different')
done()
})
}) })
}) })
}) })
}) })
}) })
}.bind(this)) })
}.bind(this)) })
}) })
}); })
describe('default values', function() { describe('default values', function() {
describe('current date', function() { describe('current date', function() {
it('should store a date in touchedAt', function() { it('should store a date in touchedAt', function(done) {
var user = this.User.build({ username: 'a user'}) var user = this.User.build({ username: 'a user'})
expect(user.touchedAt instanceof Date).toBeTrue() expect(user.touchedAt instanceof Date).toBeTrue()
done()
}) })
it("should store the current date in touchedAt", function() { it("should store the current date in touchedAt", function(done) {
this.useFakeTimers().tick(5000) this.useFakeTimers().tick(5000)
var user = this.User.build({ username: 'a user'}) var user = this.User.build({ username: 'a user'})
expect(+user.touchedAt).toBe(5000) expect(+user.touchedAt).toBe(5000)
done()
}) })
}) })
describe('allowNull date', function() { describe('allowNull date', function() {
it('should be just "null" and not Date with Invalid Date', function(done) { it('should be just "null" and not Date with Invalid Date', function(done) {
var self = this; var self = this
this.User.build({ username: 'a user'}).save().success(function() { this.User.build({ username: 'a user'}).save().success(function() {
self.User.find({where: {username: 'a user'}}).success(function(user) { self.User.find({where: {username: 'a user'}}).success(function(user) {
expect(user.dateAllowNullTrue).toBe(null) expect(user.dateAllowNullTrue).toBe(null)
...@@ -429,8 +384,8 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -429,8 +384,8 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
it('should be the same valid date when saving the date', function(done) { it('should be the same valid date when saving the date', function(done) {
var self = this; var self = this
var date = new Date(); var date = new Date()
this.User.build({ username: 'a user', dateAllowNullTrue: date}).save().success(function() { this.User.build({ username: 'a user', dateAllowNullTrue: date}).save().success(function() {
self.User.find({where: {username: 'a user'}}).success(function(user) { self.User.find({where: {username: 'a user'}}).success(function(user) {
expect(user.dateAllowNullTrue.toString()).toEqual(date.toString()) expect(user.dateAllowNullTrue.toString()).toEqual(date.toString())
...@@ -443,7 +398,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -443,7 +398,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
describe('complete', function() { describe('complete', function() {
it("gets triggered if an error occurs", function(done) { it("gets triggered if an error occurs", function(done) {
this.User.find({ where: "asdasdasd" }).complete(function(err, result) { this.User.find({ where: "asdasdasd" }).complete(function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err.message).toBeDefined() expect(err.message).toBeDefined()
done() done()
...@@ -507,7 +462,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -507,7 +462,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
it("updates the timestamps", function(done) { it("updates the timestamps", function(done) {
this.timeout = 1000 * 5; this.timeout = 1000 * 5
var now = Date.now() var now = Date.now()
, user = null , user = null
, updatedAt = null , updatedAt = null
...@@ -532,10 +487,16 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -532,10 +487,16 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
describe('without timestamps option', function() { describe('without timestamps option', function() {
it("doesn't update the updatedAt column", function(done) { it("doesn't update the updatedAt column", function(done) {
this.User2.create({ username: 'john doe' }).success(function(johnDoe) { var User2 = sequelize.define('User2', {
// sqlite and mysql return undefined, whereas postgres returns null username: DataTypes.STRING,
expect([undefined, null].indexOf(johnDoe.updatedAt)).not.toBe(-1); updatedAt: DataTypes.DATE
done() }, { timestamps: false })
User2.sync().success(function() {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
// sqlite and mysql return undefined, whereas postgres returns null
expect([undefined, null].indexOf(johnDoe.updatedAt)).not.toBe(-1)
done()
})
}) })
}) })
}) })
...@@ -546,9 +507,9 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -546,9 +507,9 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
expect(err).toBeObject() expect(err).toBeObject()
expect(err.validateTest).toBeArray() expect(err.validateTest).toBeArray()
expect(err.validateTest[0]).toBeDefined() expect(err.validateTest[0]).toBeDefined()
expect(err.validateTest[0].indexOf('Invalid integer')).toBeGreaterThan(-1); expect(err.validateTest[0].indexOf('Invalid integer')).toBeGreaterThan(-1)
done(); done()
}); })
}) })
it('should fail a validation upon building', function(done){ it('should fail a validation upon building', function(done){
...@@ -586,90 +547,99 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -586,90 +547,99 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
it('saves a record with no primary key', function(done){ it('saves a record with no primary key', function(done){
this.HistoryLog.create({ someText: 'Some random text', aNumber: 3, aRandomId: 5 }).success(function(log) { var HistoryLog = sequelize.define('HistoryLog', {
log.updateAttributes({ aNumber: 5 }).success(function(newLog){ someText: { type: DataTypes.STRING },
expect(newLog.aNumber).toEqual(5) aNumber: { type: DataTypes.INTEGER },
done() aRandomId: { type: DataTypes.INTEGER }
})
HistoryLog.sync().success(function() {
HistoryLog.create({ someText: 'Some random text', aNumber: 3, aRandomId: 5 }).success(function(log) {
log.updateAttributes({ aNumber: 5 }).success(function(newLog){
expect(newLog.aNumber).toEqual(5)
done()
})
}) })
}) })
}) })
before(function(done) { before(function(done) {
this.UserEager = this.sequelize.define('UserEagerLoadingSaves', { var self = this
username : Helpers.Sequelize.STRING, this.UserEager = this.sequelize.define('UserEagerLoadingSaves', {
age : Helpers.Sequelize.INTEGER username: DataTypes.STRING,
age: DataTypes.INTEGER
}, { timestamps: false }) }, { timestamps: false })
this.ProjectEager = this.sequelize.define('ProjectEagerLoadingSaves', { this.ProjectEager = this.sequelize.define('ProjectEagerLoadingSaves', {
title : Helpers.Sequelize.STRING, title: DataTypes.STRING,
overdue_days: Helpers.Sequelize.INTEGER overdue_days: DataTypes.INTEGER
}, { timestamps: false }) }, { timestamps: false })
this.UserEager.hasMany(this.ProjectEager, { as: 'Projects' }) this.UserEager.hasMany(this.ProjectEager, { as: 'Projects' })
this.ProjectEager.belongsTo(this.UserEager, { as: 'Poobah' }) this.ProjectEager.belongsTo(this.UserEager, { as: 'Poobah' })
this.sequelize.sync({ force: true }).success(done) self.UserEager.sync({force: true}).success(function() {
self.ProjectEager.sync({force: true}).success(done)
})
}) })
it('saves one object that has a collection of eagerly loaded objects', function(done) { it('saves one object that has a collection of eagerly loaded objects', function(done) {
var self = this
this.UserEager.create({ username: 'joe', age: 1 }).success(function(user) { this.UserEager.create({ username: 'joe', age: 1 }).success(function(user) {
this.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 }).success(function(project1) { self.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 }).success(function(project1) {
this.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 }).success(function(project2) { self.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 }).success(function(project2) {
user.setProjects([project1, project2]).success(function() { user.setProjects([project1, project2]).success(function() {
self.UserEager.find({where: {age: 1}, include: [{model: self.ProjectEager, as: 'Projects'}]}).success(function(user) {
this.UserEager.find({where: {age: 1}, include: [{model: this.ProjectEager, as: 'Projects'}]}).success(function(user) {
expect(user.username).toEqual('joe') expect(user.username).toEqual('joe')
expect(user.age).toEqual(1) expect(user.age).toEqual(1)
expect(user.projects).toBeDefined() expect(user.projects).toBeDefined()
expect(user.projects.length).toEqual(2) expect(user.projects.length).toEqual(2)
user.age = user.age + 1; // happy birthday joe user.age = user.age + 1 // happy birthday joe
user.save().success(function(saveduser) { user.save().success(function() {
expect(user.username).toEqual('joe') expect(user.username).toEqual('joe')
expect(user.age).toEqual(2) expect(user.age).toEqual(2)
expect(user.projects).toBeDefined() expect(user.projects).toBeDefined()
expect(user.projects.length).toEqual(2) expect(user.projects.length).toEqual(2)
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it('saves many objects that each a have collection of eagerly loaded objects', function(done) { it('saves many objects that each a have collection of eagerly loaded objects', function(done) {
var self = this
this.UserEager.create({ username: 'bart', age: 20 }).success(function(bart) { this.UserEager.create({ username: 'bart', age: 20 }).success(function(bart) {
this.UserEager.create({ username: 'lisa', age: 20 }).success(function(lisa) { self.UserEager.create({ username: 'lisa', age: 20 }).success(function(lisa) {
self.ProjectEager.create({ title: 'detention1', overdue_days: 0 }).success(function(detention1) {
this.ProjectEager.create({ title: 'detention1', overdue_days: 0 }).success(function(detention1) { self.ProjectEager.create({ title: 'detention2', overdue_days: 0 }).success(function(detention2) {
this.ProjectEager.create({ title: 'detention2', overdue_days: 0 }).success(function(detention2) { self.ProjectEager.create({ title: 'exam1', overdue_days: 0 }).success(function(exam1) {
this.ProjectEager.create({ title: 'exam1', overdue_days: 0 }).success(function(exam1) { self.ProjectEager.create({ title: 'exam2', overdue_days: 0 }).success(function(exam2) {
this.ProjectEager.create({ title: 'exam2', overdue_days: 0 }).success(function(exam2) {
bart.setProjects([detention1, detention2]).success(function() { bart.setProjects([detention1, detention2]).success(function() {
lisa.setProjects([exam1, exam2]).success(function() { lisa.setProjects([exam1, exam2]).success(function() {
this.UserEager.findAll({where: {age: 20}, order: 'username ASC', include: [{model: this.ProjectEager, as: 'Projects'}]}).success(function(simpsons) { self.UserEager.findAll({where: {age: 20}, order: 'username ASC', include: [{model: self.ProjectEager, as: 'Projects'}]}).success(function(simpsons) {
var _bart, _lisa; var _bart, _lisa
expect(simpsons.length).toEqual(2) expect(simpsons.length).toEqual(2)
_bart = simpsons[0]; _bart = simpsons[0]
_lisa = simpsons[1]; _lisa = simpsons[1]
expect(_bart.projects).toBeDefined() expect(_bart.projects).toBeDefined()
expect(_lisa.projects).toBeDefined() expect(_lisa.projects).toBeDefined()
expect(_bart.projects.length).toEqual(2) expect(_bart.projects.length).toEqual(2)
expect(_lisa.projects.length).toEqual(2) expect(_lisa.projects.length).toEqual(2)
_bart.age = _bart.age + 1; // happy birthday bart - off to Moe's _bart.age = _bart.age + 1 // happy birthday bart - off to Moe's
_bart.save().success(function(savedbart) { _bart.save().success(function(savedbart) {
expect(savedbart.username).toEqual('bart') expect(savedbart.username).toEqual('bart')
expect(savedbart.age).toEqual(21) expect(savedbart.age).toEqual(21)
_lisa.username = 'lsimpson'; _lisa.username = 'lsimpson'
_lisa.save().success(function(savedlisa) { _lisa.save().success(function(savedlisa) {
expect(savedlisa.username).toEqual('lsimpson') expect(savedlisa.username).toEqual('lsimpson')
...@@ -679,22 +649,23 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -679,22 +649,23 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
}) })
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it('saves many objects that each has one eagerly loaded object (to which they belong)', function(done) { it('saves many objects that each has one eagerly loaded object (to which they belong)', function(done) {
var self = this
this.UserEager.create({ username: 'poobah', age: 18 }).success(function(user) { this.UserEager.create({ username: 'poobah', age: 18 }).success(function(user) {
this.ProjectEager.create({ title: 'homework', overdue_days: 10 }).success(function(homework) { self.ProjectEager.create({ title: 'homework', overdue_days: 10 }).success(function(homework) {
this.ProjectEager.create({ title: 'party', overdue_days: 2 }).success(function(party) { self.ProjectEager.create({ title: 'party', overdue_days: 2 }).success(function(party) {
user.setProjects([homework, party]).success(function() { user.setProjects([homework, party]).success(function() {
this.ProjectEager.findAll({include: [{model: this.UserEager, as: 'Poobah'}]}).success(function(projects) { self.ProjectEager.findAll({include: [{model: self.UserEager, as: 'Poobah'}]}).success(function(projects) {
expect(projects.length).toEqual(2) expect(projects.length).toEqual(2)
expect(projects[0].poobah).toBeDefined() expect(projects[0].poobah).toBeDefined()
...@@ -702,14 +673,14 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -702,14 +673,14 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
expect(projects[0].poobah.username).toEqual('poobah') expect(projects[0].poobah.username).toEqual('poobah')
expect(projects[1].poobah.username).toEqual('poobah') expect(projects[1].poobah.username).toEqual('poobah')
projects[0].title = 'partymore'; projects[0].title = 'partymore'
projects[1].title = 'partymore'; projects[1].title = 'partymore'
projects[0].overdue_days = 0; projects[0].overdue_days = 0
projects[1].overdue_days = 0; projects[1].overdue_days = 0
projects[0].save().success(function() { projects[0].save().success(function() {
projects[1].save().success(function() { projects[1].save().success(function() {
this.ProjectEager.findAll({where: {title: 'partymore', overdue_days: 0}, include: [{model: this.UserEager, as: 'Poobah'}]}).success(function(savedprojects) { self.ProjectEager.findAll({where: {title: 'partymore', overdue_days: 0}, include: [{model: self.UserEager, as: 'Poobah'}]}).success(function(savedprojects) {
expect(savedprojects.length).toEqual(2) expect(savedprojects.length).toEqual(2)
expect(savedprojects[0].poobah).toBeDefined() expect(savedprojects[0].poobah).toBeDefined()
...@@ -719,18 +690,19 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -719,18 +690,19 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('toJSON', function toJSON() { describe('toJSON', function() {
before(function(done) { before(function(done) {
var self = this
this.User = this.sequelize.define('UserWithUsernameAndAgeAndIsAdmin', { this.User = this.sequelize.define('UserWithUsernameAndAgeAndIsAdmin', {
username: Helpers.Sequelize.STRING, username: Helpers.Sequelize.STRING,
age: Helpers.Sequelize.INTEGER, age: Helpers.Sequelize.INTEGER,
...@@ -742,35 +714,41 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -742,35 +714,41 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
this.User.hasMany(this.Project, { as: 'Projects' }) this.User.hasMany(this.Project, { as: 'Projects' })
this.Project.belongsTo(this.User, { as: 'LovelyUser' }) this.Project.belongsTo(this.User, { as: 'LovelyUser' })
this.sequelize.sync({ force: true }).success(done) this.User.sync({ force: true }).success(function() {
self.Project.sync({ force: true }).success(done)
})
}) })
it('returns an object containing all values', function() { it('returns an object containing all values', function(done) {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true }) var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true })
expect(user.toJSON()).toEqual({ username: 'test.user', age: 99, isAdmin: true, id: null }) expect(user.toJSON()).toEqual({ username: 'test.user', age: 99, isAdmin: true, id: null })
done()
}) })
it('returns a response that can be stringified', function() { it('returns a response that can be stringified', function(done) {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true }) var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true })
expect(JSON.stringify(user)).toEqual('{"username":"test.user","age":99,"isAdmin":true,"id":null}') expect(JSON.stringify(user)).toEqual('{"username":"test.user","age":99,"isAdmin":true,"id":null}')
done()
}) })
it('returns a response that can be stringified and then parsed', function() { it('returns a response that can be stringified and then parsed', function(done) {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true }) var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true })
expect(JSON.parse(JSON.stringify(user))).toEqual({ username: 'test.user', age: 99, isAdmin: true, id: null }) expect(JSON.parse(JSON.stringify(user))).toEqual({ username: 'test.user', age: 99, isAdmin: true, id: null })
done()
}) })
it('includes the eagerly loaded associations', function(done) { it('includes the eagerly loaded associations', function(done) {
var self = this
this.User.create({ username: 'fnord', age: 1, isAdmin: true }).success(function(user) { this.User.create({ username: 'fnord', age: 1, isAdmin: true }).success(function(user) {
this.Project.create({ title: 'fnord' }).success(function(project) { self.Project.create({ title: 'fnord' }).success(function(project) {
user.setProjects([ project ]).success(function() { user.setProjects([ project ]).success(function() {
this.User.findAll({include: [ { model: this.Project, as: 'Projects' } ]}).success(function(users) { self.User.findAll({include: [ { model: self.Project, as: 'Projects' } ]}).success(function(users) {
var _user = users[0] var _user = users[0]
expect(_user.projects).toBeDefined() expect(_user.projects).toBeDefined()
expect(JSON.parse(JSON.stringify(_user)).projects).toBeDefined() expect(JSON.parse(JSON.stringify(_user)).projects).toBeDefined()
this.Project.findAll({include: [ { model: this.User, as: 'LovelyUser' } ]}).success(function(projects) { self.Project.findAll({include: [ { model: self.User, as: 'LovelyUser' } ]}).success(function(projects) {
var _project = projects[0] var _project = projects[0]
expect(_project.lovelyUser).toBeDefined() expect(_project.lovelyUser).toBeDefined()
...@@ -778,14 +756,23 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -778,14 +756,23 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('findAll', function findAll() { describe('findAll', function() {
before(function(done) {
this.ParanoidUser = sequelize.define('ParanoidUser', {
username: { type: DataTypes.STRING }
}, { paranoid: true })
this.ParanoidUser.hasOne(this.ParanoidUser)
this.ParanoidUser.sync({ force: true }).success(done)
})
it("escapes a single single quotes properly in where clauses", function(done) { it("escapes a single single quotes properly in where clauses", function(done) {
var self = this var self = this
...@@ -819,113 +806,120 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -819,113 +806,120 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
}) })
it("returns the timestamps if no attributes have been specified", function(done) { it("returns the timestamps if no attributes have been specified", function(done) {
var self = this
this.User.create({ username: 'fnord' }).success(function() { this.User.create({ username: 'fnord' }).success(function() {
this.User.findAll().success(function(users) { self.User.findAll().success(function(users) {
expect(users[0].createdAt).toBeDefined() expect(users[0].createdAt).toBeDefined()
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("does not return the timestamps if the username attribute has been specified", function(done) { it("does not return the timestamps if the username attribute has been specified", function(done) {
var self = this
this.User.create({ username: 'fnord' }).success(function() { this.User.create({ username: 'fnord' }).success(function() {
this.User.findAll({ attributes: ['username'] }).success(function(users) { self.User.findAll({ attributes: ['username'] }).success(function(users) {
expect(users[0].createdAt).not.toBeDefined() expect(users[0].createdAt).not.toBeDefined()
expect(users[0].username).toBeDefined() expect(users[0].username).toBeDefined()
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("creates the deletedAt property, when defining paranoid as true", function(done) { it("creates the deletedAt property, when defining paranoid as true", function(done) {
var self = this
this.ParanoidUser.create({ username: 'fnord' }).success(function() { this.ParanoidUser.create({ username: 'fnord' }).success(function() {
this.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
expect(users[0].deletedAt).toBeDefined() expect(users[0].deletedAt).toBeDefined()
expect(users[0].deletedAt).toBe(null) expect(users[0].deletedAt).toBe(null)
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("sets deletedAt property to a specific date when deleting an instance", function(done) { it("sets deletedAt property to a specific date when deleting an instance", function(done) {
var self = this
this.ParanoidUser.create({ username: 'fnord' }).success(function() { this.ParanoidUser.create({ username: 'fnord' }).success(function() {
this.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
users[0].destroy().success(function(user) { users[0].destroy().success(function(user) {
expect(user.deletedAt.getMonth).toBeDefined() expect(user.deletedAt.getMonth).toBeDefined()
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it("keeps the deletedAt-attribute with value null, when running updateAttributes", function(done) { it("keeps the deletedAt-attribute with value null, when running updateAttributes", function(done) {
var self = this
this.ParanoidUser.create({ username: 'fnord' }).success(function() { this.ParanoidUser.create({ username: 'fnord' }).success(function() {
this.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
users[0].updateAttributes({username: 'newFnord'}).success(function(user) { users[0].updateAttributes({username: 'newFnord'}).success(function(user) {
expect(user.deletedAt).toBe(null) expect(user.deletedAt).toBe(null)
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it("keeps the deletedAt-attribute with value null, when updating associations", function(done) { it("keeps the deletedAt-attribute with value null, when updating associations", function(done) {
var self = this
this.ParanoidUser.create({ username: 'fnord' }).success(function() { this.ParanoidUser.create({ username: 'fnord' }).success(function() {
this.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
this.ParanoidUser.create({ username: 'linkedFnord' }).success(function( linkedUser ) { self.ParanoidUser.create({ username: 'linkedFnord' }).success(function(linkedUser) {
users[0].setParanoidUser( linkedUser ).success(function(user) { users[0].setParanoidUser( linkedUser ).success(function(user) {
expect(user.deletedAt).toBe(null) expect(user.deletedAt).toBe(null)
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it("can reuse query option objects", function(done) { it("can reuse query option objects", function(done) {
var self = this
this.User.create({ username: 'fnord' }).success(function() { this.User.create({ username: 'fnord' }).success(function() {
var query = { where: { username: 'fnord' }} var query = { where: { username: 'fnord' }}
this.User.findAll(query).success(function(users) { self.User.findAll(query).success(function(users) {
expect(users[0].username).toEqual('fnord') expect(users[0].username).toEqual('fnord')
self.User.findAll(query).success(function(users) {
this.User.findAll(query).success(function(users) {
expect(users[0].username).toEqual('fnord') expect(users[0].username).toEqual('fnord')
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('find', function find() { describe('find', function() {
it("can reuse query option objects", function(done) { it("can reuse query option objects", function(done) {
var self = this
this.User.create({ username: 'fnord' }).success(function() { this.User.create({ username: 'fnord' }).success(function() {
var query = { where: { username: 'fnord' }} var query = { where: { username: 'fnord' }}
this.User.find(query).success(function(user) { self.User.find(query).success(function(user) {
expect(user.username).toEqual('fnord') expect(user.username).toEqual('fnord')
this.User.find(query).success(function(user) { self.User.find(query).success(function(user) {
expect(user.username).toEqual('fnord') expect(user.username).toEqual('fnord')
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('equals', function find() { describe('equals', function() {
it("can compare records with Date field", function(done) { it("can compare records with Date field", function(done) {
var self = this
this.User.create({ username: 'fnord' }).success(function(user1) { this.User.create({ username: 'fnord' }).success(function(user1) {
var query = { where: { username: 'fnord' }} var query = { where: { username: 'fnord' }}
this.User.find(query).success(function(user2) { self.User.find(query).success(function(user2) {
expect(user1.equals(user2)).toBeTrue() expect(user1.equals(user2)).toBeTrue()
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
}) })
...@@ -935,7 +929,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -935,7 +929,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
username: Helpers.Sequelize.STRING username: Helpers.Sequelize.STRING
}, { timestamps: false, logging: false }) }, { timestamps: false, logging: false })
User.sync({ force: true }).success(function() { User.sync().success(function() {
var user = User.build({ username: 'foo' }) var user = User.build({ username: 'foo' })
expect(user.values).toEqual({ username: "foo", id: null }) expect(user.values).toEqual({ username: "foo", id: null })
done() done()
...@@ -971,7 +965,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -971,7 +965,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
identifier: {type: Helpers.Sequelize.STRING, primaryKey: true} identifier: {type: Helpers.Sequelize.STRING, primaryKey: true}
}) })
User.sync({ force: true }).success(function(){ User.sync().success(function(){
User.create({ User.create({
name: 'snafu', name: 'snafu',
identifier: 'identifier' identifier: 'identifier'
...@@ -999,7 +993,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -999,7 +993,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
identifier: {type: Helpers.Sequelize.STRING, primaryKey: true} identifier: {type: Helpers.Sequelize.STRING, primaryKey: true}
}) })
User.sync({ force:true }).success(function(){ User.sync().success(function(){
User.create({ User.create({
name: 'snafu', name: 'snafu',
identifier: 'identifier' identifier: 'identifier'
...@@ -1020,7 +1014,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() { ...@@ -1020,7 +1014,7 @@ describe(Helpers.getTestDialectTeaser("DAO"), function() {
finishedAt: Helpers.Sequelize.DATE finishedAt: Helpers.Sequelize.DATE
}) })
Download.sync({ force: true }).success(function() { Download.sync().success(function() {
Download.create({ Download.create({
startedAt: new Date() startedAt: new Date()
}).success(function(download) { }).success(function(download) {
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Sequelize = require("../index")
, Sequelize = require("../index") , Helpers = require('./buster-helpers')
, Helpers = require('./buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
describe('validations', function() { describe('validations', function() {
before(function(done) { beforeAll(function(done) {
var self = this
Helpers.initTests({ Helpers.initTests({
dialect: dialect, dialect: dialect,
onComplete: function(sequelize) { onComplete: function(sequelize) {
this.sequelize = sequelize self.sequelize = sequelize
done() done()
}.bind(this) }
}) })
}) //- before })
var checks = { var checks = {
is: { is: {
...@@ -44,9 +43,9 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -44,9 +43,9 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
pass: "129.89.23.1" pass: "129.89.23.1"
} }
, isIPv6 : { , isIPv6 : {
fail: '1111:2222:3333::5555:', fail: '1111:2222:3333::5555:',
pass: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156' pass: 'fe80:0000:0000:0000:0204:61ff:fe9d:f156'
} }
, isAlpha : { , isAlpha : {
fail: "012", fail: "012",
pass: "abc" pass: "abc"
...@@ -116,72 +115,72 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -116,72 +115,72 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
fail: "a", fail: "a",
pass: "0" pass: "0"
} }
, len : { , len: {
spec: { args: [2,4] }, spec: { args: [2,4] },
fail: ["1", "12345"], fail: ["1", "12345"],
pass: ["12", "123", "1234"], pass: ["12", "123", "1234"],
raw: true raw: true
} }
, len: { , len$: {
spec: [2,4], spec: [2,4],
fail: ["1", "12345"], fail: ["1", "12345"],
pass: ["12", "123", "1234"], pass: ["12", "123", "1234"],
raw: true raw: true
} }
, isUUID : { , isUUID: {
spec: { args: 4 }, spec: { args: 4 },
fail: "f47ac10b-58cc-3372-a567-0e02b2c3d479", fail: "f47ac10b-58cc-3372-a567-0e02b2c3d479",
pass: "f47ac10b-58cc-4372-a567-0e02b2c3d479" pass: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
} }
, isDate : { , isDate: {
fail: "not a date", fail: "not a date",
pass: "2011-02-04" pass: "2011-02-04"
} }
, isAfter : { , isAfter: {
spec: { args: "2011-11-05" }, spec: { args: "2011-11-05" },
fail: "2011-11-04", fail: "2011-11-04",
pass: "2011-11-05" pass: "2011-11-05"
} }
, isBefore : { , isBefore: {
spec: { args: "2011-11-05" }, spec: { args: "2011-11-05" },
fail: "2011-11-06", fail: "2011-11-06",
pass: "2011-11-05" pass: "2011-11-05"
} }
, isIn : { , isIn: {
spec: { args: "abcdefghijk" }, spec: { args: "abcdefghijk" },
fail: "ghik", fail: "ghik",
pass: "ghij" pass: "ghij"
} }
, notIn : { , notIn: {
spec: { args: "abcdefghijk" }, spec: { args: "abcdefghijk" },
fail: "ghij", fail: "ghij",
pass: "ghik" pass: "ghik"
} }
, max : { , max: {
spec: { args: 23 }, spec: { args: 23 },
fail: "24", fail: "24",
pass: "23" pass: "23"
} }
, max : { , max$: {
spec: 23, spec: 23,
fail: "24", fail: "24",
pass: "23" pass: "23"
} }
, min : { , min: {
spec: { args: 23 }, spec: { args: 23 },
fail: "22", fail: "22",
pass: "23" pass: "23"
} }
, min : { , min$: {
spec: 23, spec: 23,
fail: "22", fail: "22",
pass: "23" pass: "23"
} }
, isArray : { , isArray: {
fail: 22, fail: 22,
pass: [22] pass: [22]
} }
, isCreditCard : { , isCreditCard: {
fail: "401288888888188f", fail: "401288888888188f",
pass: "4012888888881881" pass: "4012888888881881"
} }
...@@ -189,6 +188,8 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -189,6 +188,8 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
for (var validator in checks) { for (var validator in checks) {
if (checks.hasOwnProperty(validator)) { if (checks.hasOwnProperty(validator)) {
validator = validator.replace(/\$$/, '')
var validatorDetails = checks[validator] var validatorDetails = checks[validator]
if (!validatorDetails.hasOwnProperty("raw")) { if (!validatorDetails.hasOwnProperty("raw")) {
...@@ -202,7 +203,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -202,7 +203,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
for (var i = 0; i < validatorDetails.fail.length; i++) { for (var i = 0; i < validatorDetails.fail.length; i++) {
var failingValue = validatorDetails.fail[i] var failingValue = validatorDetails.fail[i]
it('correctly specifies an instance as invalid using a value of "' + failingValue + '" for the validation "' + validator + '"', function() { it('correctly specifies an instance as invalid using a value of "' + failingValue + '" for the validation "' + validator + '"', function(done) {
var validations = {} var validations = {}
, message = validator + "(" + failingValue + ")" , message = validator + "(" + failingValue + ")"
...@@ -226,6 +227,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -226,6 +227,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
expect(errors).not.toBeNull() expect(errors).not.toBeNull()
expect(errors).toEqual({ name : [message] }) expect(errors).toEqual({ name : [message] })
done()
}) })
} }
...@@ -235,7 +237,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -235,7 +237,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
for (var j = 0; j < validatorDetails.pass.length; j++) { for (var j = 0; j < validatorDetails.pass.length; j++) {
var succeedingValue = validatorDetails.pass[j] var succeedingValue = validatorDetails.pass[j]
it('correctly specifies an instance as valid using a value of "' + succeedingValue + '" for the validation "' + validator + '"', function() { it('correctly specifies an instance as valid using a value of "' + succeedingValue + '" for the validation "' + validator + '"', function(done) {
var validations = {} var validations = {}
if (validatorDetails.hasOwnProperty('spec')) { if (validatorDetails.hasOwnProperty('spec')) {
...@@ -255,12 +257,13 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -255,12 +257,13 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
var successfulUser = UserSuccess.build({ name: succeedingValue }) var successfulUser = UserSuccess.build({ name: succeedingValue })
expect(successfulUser.validate()).toBeNull() expect(successfulUser.validate()).toBeNull()
done()
}) })
} }
} }
} }
it('correctly validates using custom validation methods', function() { it('correctly validates using custom validation methods', function(done) {
var User = this.sequelize.define('User' + Math.random(), { var User = this.sequelize.define('User' + Math.random(), {
name: { name: {
type: Sequelize.STRING, type: Sequelize.STRING,
...@@ -282,9 +285,10 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -282,9 +285,10 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
var successfulUser = User.build({ name : "2" }) var successfulUser = User.build({ name : "2" })
expect(successfulUser.validate()).toBeNull() expect(successfulUser.validate()).toBeNull()
done()
}) })
it('skips other validations if allowNull is true and the value is null', function() { it('skips other validations if allowNull is true and the value is null', function(done) {
var User = this.sequelize.define('User' + Math.random(), { var User = this.sequelize.define('User' + Math.random(), {
age: { age: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
...@@ -306,9 +310,10 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -306,9 +310,10 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
var successfulUser2 = User.build({ age: 1 }) var successfulUser2 = User.build({ age: 1 })
expect(successfulUser2.validate()).toBeNull() expect(successfulUser2.validate()).toBeNull()
done()
}) })
it('validates a model with custom model-wide validation methods', function() { it('validates a model with custom model-wide validation methods', function(done) {
var Foo = this.sequelize.define('Foo' + Math.random(), { var Foo = this.sequelize.define('Foo' + Math.random(), {
field1: { field1: {
type: Sequelize.INTEGER, type: Sequelize.INTEGER,
...@@ -336,6 +341,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() { ...@@ -336,6 +341,7 @@ describe(Helpers.getTestDialectTeaser("DaoValidator"), function() {
var successfulFoo = Foo.build({ field1: 33, field2: null }) var successfulFoo = Foo.build({ field1: 33, field2: null })
expect(successfulFoo.validate()).toBeNull() expect(successfulFoo.validate()).toBeNull()
done()
}) })
}) })
}) })
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Sequelize = require("../index")
, Sequelize = require("../index") , Helpers = require('./buster-helpers')
, Helpers = require('./buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser('DataTypes'), function() { describe(Helpers.getTestDialectTeaser('DataTypes'), function() {
it('should return DECIMAL for the default decimal type', function() { it('should return DECIMAL for the default decimal type', function(done) {
expect(Sequelize.DECIMAL).toEqual('DECIMAL'); expect(Sequelize.DECIMAL).toEqual('DECIMAL')
}); done()
})
it('should return DECIMAL(10,2) for the default decimal type with arguments', function() { it('should return DECIMAL(10,2) for the default decimal type with arguments', function(done) {
expect(Sequelize.DECIMAL(10, 2)).toEqual('DECIMAL(10,2)'); expect(Sequelize.DECIMAL(10, 2)).toEqual('DECIMAL(10,2)')
}); done()
})
var tests = [ var tests = [
[Sequelize.STRING, 'STRING', 'VARCHAR(255)'], [Sequelize.STRING, 'STRING', 'VARCHAR(255)'],
...@@ -59,8 +60,9 @@ describe(Helpers.getTestDialectTeaser('DataTypes'), function() { ...@@ -59,8 +60,9 @@ describe(Helpers.getTestDialectTeaser('DataTypes'), function() {
] ]
tests.forEach(function(test) { tests.forEach(function(test) {
it('transforms "' + test[1] + '" to "' + test[2] + '"', function() { it('transforms "' + test[1] + '" to "' + test[2] + '"', function(done) {
expect(test[0]).toEqual(test[2]) expect(test[0]).toEqual(test[2])
done()
}) })
}) })
}) })
...@@ -12,7 +12,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() { ...@@ -12,7 +12,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() {
describe("proxy", function () { describe("proxy", function () {
/* Tests could _probably_ be run synchronously, but for future proofing we're basing it on the events */ /* Tests could _probably_ be run synchronously, but for future proofing we're basing it on the events */
it("should correctly work with success listeners", function (done) { it("should correctly work with success listeners", function(done) {
var emitter = new CustomEventEmitter() var emitter = new CustomEventEmitter()
, proxy = new CustomEventEmitter() , proxy = new CustomEventEmitter()
, success = this.spy() , success = this.spy()
...@@ -29,7 +29,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() { ...@@ -29,7 +29,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() {
proxy.emit('success') proxy.emit('success')
}) })
it("should correctly work with error listeners", function (done) { it("should correctly work with error listeners", function(done) {
var emitter = new CustomEventEmitter() var emitter = new CustomEventEmitter()
, proxy = new CustomEventEmitter() , proxy = new CustomEventEmitter()
, error = this.spy() , error = this.spy()
...@@ -46,7 +46,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() { ...@@ -46,7 +46,7 @@ describe(Helpers.getTestDialectTeaser("CustomEventEmitter"), function() {
proxy.emit('error') proxy.emit('error')
}) })
it("should correctly work with complete/done listeners", function (done) { it("should correctly work with complete/done listeners", function(done) {
var emitter = new CustomEventEmitter() var emitter = new CustomEventEmitter()
, proxy = new CustomEventEmitter() , proxy = new CustomEventEmitter()
, complete = this.spy() , complete = this.spy()
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Sequelize = require("../index")
, Sequelize = require("../index") , Helpers = require('./buster-helpers')
, Helpers = require('./buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("Language Util"), function() { describe(Helpers.getTestDialectTeaser("Language Util"), function() {
describe("Plural", function(){ describe("Plural", function(){
before(function(done) { beforeAll(function(done) {
var self = this
Helpers.initTests({ Helpers.initTests({
dialect: dialect, dialect: dialect,
onComplete: function(sequelize) { onComplete: function(sequelize) {
this.sequelize = sequelize self.sequelize = sequelize
this.sequelize.options.language = 'es' self.sequelize.options.language = 'es'
done() done()
}.bind(this) }
}) })
}) })
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('./buster-helpers')
, QueryChainer = require("../lib/query-chainer") , dialect = Helpers.getTestDialect()
, CustomEventEmitter = require("../lib/emitters/custom-event-emitter") , Migrator = require("../lib/migrator")
, Helpers = require('./buster-helpers')
, dialect = Helpers.getTestDialect()
, Migrator = require("../lib/migrator")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 10000 buster.testRunner.timeout = 10000
describe(Helpers.getTestDialectTeaser("Migrator"), function() { describe(Helpers.getTestDialectTeaser("Migrator"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
this.sequelize = sequelize
this.init = function(options, callback) { this.init = function(options, callback) {
options = Helpers.Sequelize.Utils._.extend({ options = Helpers.Sequelize.Utils._.extend({
path: __dirname + '/assets/migrations', path: __dirname + '/assets/migrations',
logging: function(){} logging: function(){},
context: sequelize
}, options || {}) }, options || {})
var migrator = new Migrator(this.sequelize, options) var migrator = new Migrator(sequelize, options)
migrator migrator
.findOrCreateSequelizeMetaDAO({ force: true }) .findOrCreateSequelizeMetaDAO({ force: true })
...@@ -26,13 +26,9 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -26,13 +26,9 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
callback && callback(migrator, SequelizeMeta) callback && callback(migrator, SequelizeMeta)
}) })
.error(function(err) { console.log(err) }) .error(function(err) { console.log(err) })
}.bind(this) }
Helpers.initTests({ dialect: dialect, onComplete: done, context: this })
})
it("as", function() { Helpers.clearDatabase(this.sequelize, done)
expect(1).toEqual(1)
}) })
describe('getUndoneMigrations', function() { describe('getUndoneMigrations', function() {
...@@ -42,8 +38,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -42,8 +38,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(err).toBeNull() expect(err).toBeNull()
expect(migrations.length).toEqual(0) expect(migrations.length).toEqual(0)
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("returns only files between from and to", function(done) { it("returns only files between from and to", function(done) {
...@@ -53,8 +49,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -53,8 +49,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(migrations.length).toEqual(1) expect(migrations.length).toEqual(1)
expect(migrations[migrations.length - 1].filename).toEqual('20111117063700-createPerson.js') expect(migrations[migrations.length - 1].filename).toEqual('20111117063700-createPerson.js')
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("returns exactly the migration which is defined in from and to", function(done) { it("returns exactly the migration which is defined in from and to", function(done) {
...@@ -64,8 +60,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -64,8 +60,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(migrations.length).toEqual(1) expect(migrations.length).toEqual(1)
expect(migrations[migrations.length - 1].filename).toEqual('20111117063700-createPerson.js') expect(migrations[migrations.length - 1].filename).toEqual('20111117063700-createPerson.js')
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("returns also the file which is exactly options.from or options.to", function(done) { it("returns also the file which is exactly options.from or options.to", function(done) {
...@@ -76,8 +72,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -76,8 +72,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(migrations[0].filename).toEqual('20111117063700-createPerson.js') expect(migrations[0].filename).toEqual('20111117063700-createPerson.js')
expect(migrations[1].filename).toEqual('20111130161100-emptyMigration.js') expect(migrations[1].filename).toEqual('20111130161100-emptyMigration.js')
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("returns all files to options.to if no options.from is defined", function(done) { it("returns all files to options.to if no options.from is defined", function(done) {
...@@ -86,8 +82,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -86,8 +82,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(err).toBeNull() expect(err).toBeNull()
expect(migrations.length).toEqual(2) expect(migrations.length).toEqual(2)
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it("returns all files from last migration id stored in database", function(done) { it("returns all files from last migration id stored in database", function(done) {
...@@ -98,23 +94,24 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -98,23 +94,24 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
expect(migrations.length).toEqual(6) expect(migrations.length).toEqual(6)
expect(migrations[0].filename).toEqual('20111130161100-emptyMigration.js') expect(migrations[0].filename).toEqual('20111130161100-emptyMigration.js')
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('migrations', function() { describe('migrations', function() {
before(function(done) { before(function(done) {
var self = this
this.init({ from: 20111117063700, to: 20111117063700 }, function(migrator) { this.init({ from: 20111117063700, to: 20111117063700 }, function(migrator) {
this.migrator = migrator self.migrator = migrator
this.migrator.migrate().success(done) self.migrator.migrate().success(done)
}.bind(this)) })
}) })
describe('executions', function() { describe('executions', function() {
it("executes migration #20111117063700 and correctly creates the table", function(done) { it("executes migration #20111117063700 and correctly creates the table", function(done) {
this.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' }) tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' })
expect(tableNames).toEqual([ 'Person' ]) expect(tableNames).toEqual([ 'Person' ])
done() done()
...@@ -122,7 +119,7 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -122,7 +119,7 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
}) })
it("executes migration #20111117063700 and correctly adds isBetaMember", function(done) { it("executes migration #20111117063700 and correctly adds isBetaMember", function(done) {
this.sequelize.getQueryInterface().describeTable('Person').success(function(data) { sequelize.getQueryInterface().describeTable('Person').success(function(data) {
var fields = Helpers.Sequelize.Utils._.keys(data).sort() var fields = Helpers.Sequelize.Utils._.keys(data).sort()
expect(fields).toEqual([ 'isBetaMember', 'name' ]) expect(fields).toEqual([ 'isBetaMember', 'name' ])
done() done()
...@@ -130,18 +127,19 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -130,18 +127,19 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
}) })
it("executes migration #20111117063700 correctly up (createTable) and downwards (dropTable)", function(done) { it("executes migration #20111117063700 correctly up (createTable) and downwards (dropTable)", function(done) {
this.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { var self = this
sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' }) tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' })
expect(tableNames).toEqual([ 'Person' ]) expect(tableNames).toEqual([ 'Person' ])
this.migrator.migrate({ method: 'down' }).success(function() { self.migrator.migrate({ method: 'down' }).success(function() {
this.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' }) tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' })
expect(tableNames).toEqual([]) expect(tableNames).toEqual([])
done() done()
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
it("executes the empty migration #20111130161100", function(done) { it("executes the empty migration #20111130161100", function(done) {
...@@ -160,36 +158,39 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -160,36 +158,39 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
}) })
describe('renameTable', function() { describe('renameTable', function() {
before(function(done) { before(function(done) {
var self = this
this.init({ from: 20111117063700, to: 20111117063700 }, function(migrator) { this.init({ from: 20111117063700, to: 20111117063700 }, function(migrator) {
this.migrator = migrator self.migrator = migrator
this.migrator.migrate().success(done) self.migrator.migrate().success(done)
}.bind(this)) })
}) })
it("executes migration #20111205064000 and renames a table", function(done) { it("executes migration #20111205064000 and renames a table", function(done) {
this.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { var self = this
self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' }) tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' })
expect(tableNames).toContain('Person') expect(tableNames).toContain('Person')
this.init({ from: 20111205064000, to: 20111205064000 }, function(migrator) { self.init({ from: 20111205064000, to: 20111205064000 }, function(migrator) {
migrator.migrate().success(function() { migrator.migrate().success(function() {
this.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' }) tableNames = tableNames.filter(function(e){ return e != 'SequelizeMeta' })
expect(tableNames).toEqual([ 'User' ]) expect(tableNames).toEqual([ 'User' ])
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('addColumn', function() { describe('addColumn', function() {
it('adds a column to the user table', function(done) { it('adds a column to the user table', function(done) {
this.init({ from: 20111117063700, to: 20111205162700 }, function(migrator) { var self = this
self.init({ from: 20111117063700, to: 20111205162700 }, function(migrator) {
migrator.migrate().complete(function(err) { migrator.migrate().complete(function(err) {
this.sequelize.getQueryInterface().describeTable('User').complete(function(err, data) { self.sequelize.getQueryInterface().describeTable('User').complete(function(err, data) {
var signature = data.signature var signature = data.signature
, isAdmin = data.isAdmin , isAdmin = data.isAdmin
, shopId = data.shopId , shopId = data.shopId
...@@ -201,16 +202,17 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -201,16 +202,17 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('removeColumn', function() { describe('removeColumn', function() {
it('removes the shopId column from user', function(done) { it('removes the shopId column from user', function(done) {
this.init({ to: 20111206061400 }, function(migrator) { var self = this
self.init({ to: 20111206061400 }, function(migrator) {
migrator.migrate().success(function(){ migrator.migrate().success(function(){
this.sequelize.getQueryInterface().describeTable('User').success(function(data) { self.sequelize.getQueryInterface().describeTable('User').success(function(data) {
var signature = data.signature var signature = data.signature
, isAdmin = data.isAdmin , isAdmin = data.isAdmin
, shopId = data.shopId , shopId = data.shopId
...@@ -223,16 +225,17 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -223,16 +225,17 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('changeColumn', function() { describe('changeColumn', function() {
it('changes the signature column from user to default "signature" + notNull', function(done) { it('changes the signature column from user to default "signature" + notNull', function(done) {
this.init({ to: 20111206063000 }, function(migrator) { var self = this
self.init({ to: 20111206063000 }, function(migrator) {
migrator.migrate().success(function() { migrator.migrate().success(function() {
this.sequelize.getQueryInterface().describeTable('User').success(function(data) { self.sequelize.getQueryInterface().describeTable('User').success(function(data) {
var signature = data.signature var signature = data.signature
if (dialect === 'postgres') { if (dialect === 'postgres') {
...@@ -245,17 +248,18 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -245,17 +248,18 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
}) })
describe('renameColumn', function() { describe('renameColumn', function() {
it("renames the signature column from user to sig", function(done) { it("renames the signature column from user to sig", function(done) {
this.init({ to: 20111206163300 }, function(migrator) { var self = this
self.init({ to: 20111206163300 }, function(migrator) {
migrator.migrate().success(function(){ migrator.migrate().success(function(){
this.sequelize.getQueryInterface().describeTable('User').success(function(data) { self.sequelize.getQueryInterface().describeTable('User').success(function(data) {
var signature = data.signature var signature = data.signature
, sig = data.sig , sig = data.sig
...@@ -264,9 +268,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() { ...@@ -264,9 +268,8 @@ describe(Helpers.getTestDialectTeaser("Migrator"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
}) })
/* jshint camelcase: false */ /* jshint camelcase: false */
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , config = require('../config/config')
, config = require('../config/config') , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect.match(/^mysql/)) { if (dialect.match(/^mysql/)) {
describe('[MYSQL] Associations', function() { describe('[MYSQL] Associations', function() {
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, done)
dialect: dialect,
beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
}) })
describe('many-to-many', function() { describe('many-to-many', function() {
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect.match(/^mysql/)) { if (dialect.match(/^mysql/)) {
describe('[MYSQL] Connector Manager', function() { describe('[MYSQL] Connector Manager', function() {
before(function(done) { before(function(done) {
var self = this this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
Helpers.initTests({
dialect: dialect,
beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
}) })
it('works correctly after being idle', function(done) { it('works correctly after being idle', function(done) {
......
/* jshint camelcase: false */ /* jshint camelcase: false */
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , config = require('../config/config')
, config = require('../config/config') , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect.match(/^mysql/)) { if (dialect.match(/^mysql/)) {
describe('[MYSQL] DAOFactory', function() { describe('[MYSQL] DAOFactory', function() {
before(function(done) { before(function(done) {
var self = this this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
Helpers.initTests({
dialect: dialect,
beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
self.User = self.sequelize.define('User', { age: DataTypes.INTEGER, name: DataTypes.STRING, bio: DataTypes.TEXT })
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
}) })
describe('constructor', function() { describe('constructor', function() {
......
/* jshint camelcase: false */ /* jshint camelcase: false */
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, config = require('../config/config') , dialect = Helpers.getTestDialect()
, Helpers = require('../buster-helpers') , QueryGenerator = require("../../lib/dialects/mysql/query-generator")
, dialect = Helpers.getTestDialect() , util = require("util")
, QueryGenerator = require("../../lib/dialects/mysql/query-generator")
, util = require("util")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect.match(/^mysql/)) { if (dialect.match(/^mysql/)) {
describe('[MYSQL] QueryGenerator', function() { describe('[MYSQL] QueryGenerator', function() {
before(function(done) { before(function(done) {
var self = this this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
Helpers.initTests({
dialect: dialect,
beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
}) })
var suites = { var suites = {
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 2000
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
describe('[POSTGRES] associations', function() { describe('[POSTGRES] associations', function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
var self = this this.sequelize = sequelize
Helpers.clearDatabase(this.sequelize, done)
Helpers.initTests({
dialect: dialect,
beforeComplete: function(sequelize, DataTypes) {
self.sequelize = sequelize
},
onComplete: function() {
self.sequelize.sync({ force: true }).success(done)
}
})
}) })
describe('many-to-many', function() { describe('many-to-many', function() {
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , DataTypes = require(__dirname + "/../../lib/data-types")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
describe('[POSTGRES] DAO', function() { describe('[POSTGRES] DAO', function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, function() {
dialect: dialect, self.User = sequelize.define('User', {
beforeComplete: function(sequelize, DataTypes) { username: DataTypes.STRING,
self.sequelize = sequelize email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
self.User = sequelize.define('User', { })
username: DataTypes.STRING, self.User.sync({ force: true }).success(done)
email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
})
},
onComplete: function() {
self.User.sync({ force: true }).success(done)
}
}) })
}) })
describe('model', function() { describe('model', function() {
it("create handles array correctly", function(done) { it("create handles array correctly", function(done) {
var self = this
this.User this.User
.create({ username: 'user', email: ['foo@bar.com', 'bar@baz.com'] }) .create({ username: 'user', email: ['foo@bar.com', 'bar@baz.com'] })
.success(function(oldUser) { .success(function(oldUser) {
...@@ -65,61 +58,50 @@ if (dialect.match(/^postgres/)) { ...@@ -65,61 +58,50 @@ if (dialect.match(/^postgres/)) {
.error(console.log) .error(console.log)
}) })
}) })
})
describe('[POSTGRES] Unquoted identifiers', function() { describe('[POSTGRES] Unquoted identifiers', function() {
before(function(done) {
before(function(done) { var self = this
var self = this this.sequelize.options.quoteIdentifiers = false
Helpers.initTests({ self.User = this.sequelize.define('User', {
dialect: dialect, username: DataTypes.STRING,
beforeComplete: function(sequelize, DataTypes) { fullName: DataTypes.STRING // Note mixed case
self.sequelize = sequelize })
self.sequelize.options.quoteIdentifiers = false
self.User = sequelize.define('User', { self.User.sync({ force: true }).success(done)
username: DataTypes.STRING,
fullName: DataTypes.STRING // Note mixed case
})
},
onComplete: function() {
// We can create a table with non-quoted identifiers
self.User.sync({ force: true }).success(done)
}
}) })
})
it("can insert and select", function(done) { after(function(done) {
var self = this this.sequelize.options.quoteIdentifiers = true
done()
})
self.User it("can insert and select", function(done) {
.create({ username: 'user', fullName: "John Smith" }) var self = this
.success(function(user) {
// We can insert into a table with non-quoted identifiers
expect(user.id).toBeDefined()
expect(user.id).not.toBeNull()
expect(user.username).toEqual('user')
expect(user.fullName).toEqual('John Smith')
// We can query by non-quoted identifiers self.User
self.User.find({ .create({ username: 'user', fullName: "John Smith" })
where: {fullName: "John Smith"} .success(function(user) {
}) // We can insert into a table with non-quoted identifiers
.success(function(user2) { expect(user.id).toBeDefined()
// We can map values back to non-quoted identifiers expect(user.id).not.toBeNull()
expect(user2.id).toEqual(user.id) expect(user.username).toEqual('user')
expect(user2.username).toEqual('user') expect(user.fullName).toEqual('John Smith')
expect(user2.fullName).toEqual('John Smith')
done(); // We can query by non-quoted identifiers
}) self.User.find({
.error(function(err) { where: {fullName: "John Smith"}
console.log(err) })
.success(function(user2) {
// We can map values back to non-quoted identifiers
expect(user2.id).toEqual(user.id)
expect(user2.username).toEqual('user')
expect(user2.fullName).toEqual('John Smith')
done();
})
}) })
}) })
.error(function(err) {
console.log(err)
})
}) })
}) })
} }
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
describe('[POSTGRES] hstore', function() { describe('[POSTGRES] hstore', function() {
const hstore = require('../../lib/dialects/postgres/hstore') var hstore = require('../../lib/dialects/postgres/hstore')
describe('stringifyPart', function() { describe('stringifyPart', function() {
it("handles undefined values correctly", function() { it("handles undefined values correctly", function(done) {
expect(hstore.stringifyPart(undefined)).toEqual('NULL') expect(hstore.stringifyPart(undefined)).toEqual('NULL')
done()
}) })
it("handles null values correctly", function() {
it("handles null values correctly", function(done) {
expect(hstore.stringifyPart(null)).toEqual('NULL') expect(hstore.stringifyPart(null)).toEqual('NULL')
done()
}) })
it("handles boolean values correctly", function() {
it("handles boolean values correctly", function(done) {
expect(hstore.stringifyPart(false)).toEqual('false') expect(hstore.stringifyPart(false)).toEqual('false')
expect(hstore.stringifyPart(true)).toEqual('true') expect(hstore.stringifyPart(true)).toEqual('true')
done()
}) })
it("handles strings correctly", function() {
it("handles strings correctly", function(done) {
expect(hstore.stringifyPart('foo')).toEqual('"foo"') expect(hstore.stringifyPart('foo')).toEqual('"foo"')
done()
}) })
it("handles strings with backslashes correctly", function() {
it("handles strings with backslashes correctly", function(done) {
expect(hstore.stringifyPart("\\'literally\\'")).toEqual('"\\\\\'literally\\\\\'"') expect(hstore.stringifyPart("\\'literally\\'")).toEqual('"\\\\\'literally\\\\\'"')
done()
}) })
it("handles arrays correctly", function() {
it("handles arrays correctly", function(done) {
expect(hstore.stringifyPart([1,['2'],'"3"'])).toEqual('"[1,[\\"2\\"],\\"\\\\\\"3\\\\\\"\\"]"') expect(hstore.stringifyPart([1,['2'],'"3"'])).toEqual('"[1,[\\"2\\"],\\"\\\\\\"3\\\\\\"\\"]"')
done()
}) })
it("handles simple objects correctly", function() {
it("handles simple objects correctly", function(done) {
expect(hstore.stringifyPart({ test: 'value' })).toEqual('"{\\"test\\":\\"value\\"}"') expect(hstore.stringifyPart({ test: 'value' })).toEqual('"{\\"test\\":\\"value\\"}"')
done()
}) })
it("handles nested objects correctly", function () {
it("handles nested objects correctly", function(done) {
expect(hstore.stringifyPart({ test: { nested: 'value' } })).toEqual('"{\\"test\\":{\\"nested\\":\\"value\\"}}"') expect(hstore.stringifyPart({ test: { nested: 'value' } })).toEqual('"{\\"test\\":{\\"nested\\":\\"value\\"}}"')
done()
}) })
it("handles objects correctly", function() {
it("handles objects correctly", function(done) {
expect(hstore.stringifyPart({test: {nested: {value: {including: '"string"'}}}})).toEqual('"{\\"test\\":{\\"nested\\":{\\"value\\":{\\"including\\":\\"\\\\\\"string\\\\\\"\\"}}}}"') expect(hstore.stringifyPart({test: {nested: {value: {including: '"string"'}}}})).toEqual('"{\\"test\\":{\\"nested\\":{\\"value\\":{\\"including\\":\\"\\\\\\"string\\\\\\"\\"}}}}"')
done()
}) })
}) })
describe('stringify', function() { describe('stringify', function() {
it('should handle empty objects correctly', function() { it('should handle empty objects correctly', function(done) {
expect(hstore.stringify({ })).toEqual('') expect(hstore.stringify({ })).toEqual('')
done()
}) })
it('should handle null values correctly', function () {
it('should handle null values correctly', function(done) {
expect(hstore.stringify({ null: null })).toEqual('"null"=>NULL') expect(hstore.stringify({ null: null })).toEqual('"null"=>NULL')
done()
}) })
it('should handle simple objects correctly', function() {
it('should handle simple objects correctly', function(done) {
expect(hstore.stringify({ test: 'value' })).toEqual('"test"=>"value"') expect(hstore.stringify({ test: 'value' })).toEqual('"test"=>"value"')
done()
}) })
it('should handle nested objects correctly', function() {
it('should handle nested objects correctly', function(done) {
expect(hstore.stringify({ test: { nested: 'value' } })).toEqual('"test"=>"{\\"nested\\":\\"value\\"}"') expect(hstore.stringify({ test: { nested: 'value' } })).toEqual('"test"=>"{\\"nested\\":\\"value\\"}"')
done()
}) })
it('should handle nested arrays correctly', function() {
it('should handle nested arrays correctly', function(done) {
expect(hstore.stringify({ test: [ 1, '2', [ '"3"' ] ] })).toEqual('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"') expect(hstore.stringify({ test: [ 1, '2', [ '"3"' ] ] })).toEqual('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"')
done()
}) })
it('should handle multiple keys with different types of values', function() {
it('should handle multiple keys with different types of values', function(done) {
expect(hstore.stringify({ true: true, false: false, null: null, undefined: undefined, integer: 1, array: [1,'2'], object: { object: 'value' }})).toEqual('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"') expect(hstore.stringify({ true: true, false: false, null: null, undefined: undefined, integer: 1, array: [1,'2'], object: { object: 'value' }})).toEqual('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"')
done()
}) })
}) })
describe('parse', function() { describe('parse', function() {
it('should handle empty objects correctly', function() { it('should handle empty objects correctly', function(done) {
expect(hstore.parse('')).toEqual({ }) expect(hstore.parse('')).toEqual({ })
done()
}) })
it('should handle simple objects correctly', function() {
it('should handle simple objects correctly', function(done) {
expect(hstore.parse('"test"=>"value"')).toEqual({ test: 'value' }) expect(hstore.parse('"test"=>"value"')).toEqual({ test: 'value' })
done()
}) })
it('should handle nested objects correctly', function() {
it('should handle nested objects correctly', function(done) {
expect(hstore.parse('"test"=>"{\\"nested\\":\\"value\\"}"')).toEqual({ test: { nested: 'value' } }) expect(hstore.parse('"test"=>"{\\"nested\\":\\"value\\"}"')).toEqual({ test: { nested: 'value' } })
done()
}) })
it('should handle nested arrays correctly', function() {
it('should handle nested arrays correctly', function(done) {
expect(hstore.parse('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"')).toEqual({ test: [ 1, '2', [ '"3"' ] ] }) expect(hstore.parse('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"')).toEqual({ test: [ 1, '2', [ '"3"' ] ] })
done()
}) })
it('should handle multiple keys with different types of values', function() {
it('should handle multiple keys with different types of values', function(done) {
expect(hstore.parse('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"')).toEqual({ true: true, false: false, null: null, undefined: null, integer: 1, array: [1,'2'], object: { object: 'value' }}) expect(hstore.parse('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"')).toEqual({ true: true, false: false, null: null, undefined: null, integer: 1, array: [1,'2'], object: { object: 'value' }})
done()
}) })
}) })
}) })
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , QueryGenerator = require("../../lib/dialects/postgres/query-generator")
, QueryGenerator = require("../../lib/dialects/postgres/query-generator") , util = require("util")
, util = require("util") , moment = require('moment')
, moment = require('moment') , DataTypes = require(__dirname + "/../../lib/data-types")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
if (dialect.match(/^postgres/)) { if (dialect.match(/^postgres/)) {
describe('[POSTGRES] QueryGenerator', function() { describe('[POSTGRES] QueryGenerator', function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, function() {
dialect: dialect, self.User = sequelize.define('User', {
beforeComplete: function(sequelize, DataTypes) { username: DataTypes.STRING,
self.sequelize = sequelize email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
self.User = sequelize.define('User', { })
username: DataTypes.STRING, self.User.sync({ force: true }).success(done)
email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
})
},
onComplete: function() {
self.User.sync({ force: true }).success(done)
}
}) })
}) })
......
if (typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('./buster-helpers')
, Helpers = require('./buster-helpers') , DataTypes = require(__dirname + "/../lib/data-types")
, dialect = Helpers.getTestDialect() , dialect = Helpers.getTestDialect()
, _ = require('lodash') , _ = require('lodash')
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("Promise"), function () { describe(Helpers.getTestDialectTeaser("Promise"), function () {
before(function (done) { var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
var self = this , User = sequelize.define('User', {
username: { type: DataTypes.STRING },
Helpers.initTests({ touchedAt: { type: DataTypes.DATE, defaultValue: DataTypes.NOW },
dialect: dialect, aNumber: { type: DataTypes.INTEGER },
beforeComplete: function (sequelize, DataTypes) { bNumber: { type: DataTypes.INTEGER },
self.sequelize = sequelize
self.User = sequelize.define('User', { validateTest: {
username: { type: DataTypes.STRING }, type: DataTypes.INTEGER,
touchedAt: { type: DataTypes.DATE, defaultValue: DataTypes.NOW }, allowNull: true,
aNumber: { type: DataTypes.INTEGER }, validate: {isInt: true}
bNumber: { type: DataTypes.INTEGER },
validateTest: {
type: DataTypes.INTEGER,
allowNull: true,
validate: {isInt: true}
},
validateCustom: {
type: DataTypes.STRING,
allowNull: true,
validate: {len: {msg: 'Length failed.', args: [1, 20]}}
},
dateAllowNullTrue: {
type: DataTypes.DATE,
allowNull: true
}
})
self.HistoryLog = sequelize.define('HistoryLog', {
someText: { type: DataTypes.STRING },
aNumber: { type: DataTypes.INTEGER },
aRandomId: { type: DataTypes.INTEGER }
})
self.ParanoidUser = sequelize.define('ParanoidUser', {
username: { type: DataTypes.STRING }
}, {
paranoid: true
})
self.ParanoidUser.hasOne(self.ParanoidUser)
}, },
onComplete: function () { validateCustom: {
self.User.sync({ force: true }).then(function () { type: DataTypes.STRING,
return self.HistoryLog.sync({ force: true }) allowNull: true,
}).then(function () { validate: {len: {msg: 'Length failed.', args: [1, 20]}}
return self.ParanoidUser.sync({force: true }) },
})
.then(function () {done()}, done) dateAllowNullTrue: {
type: DataTypes.DATE,
allowNull: true
} }
}) })
before(function(done) {
var self = this
self.sequelize = sequelize
self.User = User
Helpers.clearDatabase(this.sequelize, function(){
self.User.sync({ force: true }).then(function() {done()}, done)
})
}) })
describe('increment', function () { describe('increment', function () {
before(function (done) { before(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done) this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done)
}); });
it('with array', function (done) { it('with array', function(done) {
var self = this; var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function(user1) {
return user1.increment(['aNumber'], 2) return user1.increment(['aNumber'], 2)
}).then(function (user2) { }).then(function(user2) {
return self.User.find(1) return self.User.find(1)
}).then(function (user3) { }).then(function(user3) {
expect(user3.aNumber).toBe(2); expect(user3.aNumber).toBe(2)
done(); done()
}, done); }, done)
}); });
it('should still work right with other concurrent updates', function (done) { it('should still work right with other concurrent updates', function(done) {
var self = this; var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function (user1) {
// Select the user again (simulating a concurrent query) // Select the user again (simulating a concurrent query)
return self.User.find(1).then(function (user2) { return self.User.find(1).then(function (user2) {
return user2.updateAttributes({ return user2.updateAttributes({
aNumber: user2.aNumber + 1 aNumber: user2.aNumber + 1
}).then(function (user3) { }).then(function() {
return user1.increment(['aNumber'], 2) return user1.increment(['aNumber'], 2)
}).then(function (user4) { }).then(function() {
return self.User.find(1) return self.User.find(1)
}).then(function (user5) { }).then(function(user5) {
expect(user5.aNumber).toBe(3); expect(user5.aNumber).toBe(3)
done(); done();
}, done) }, done)
}); })
}); })
}); })
it('with key value pair', function (done) {
var self = this;
it('with key value pair', function(done) {
var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function(user1) {
return user1.increment({ 'aNumber': 1, 'bNumber': 2}) return user1.increment({ 'aNumber': 1, 'bNumber': 2})
}).then(function () { }).then(function () {
return self.User.find(1) return self.User.find(1)
}).then(function (user3) { }).then(function (user3) {
expect(user3.aNumber).toBe(1); expect(user3.aNumber).toBe(1)
expect(user3.bNumber).toBe(2); expect(user3.bNumber).toBe(2)
done(); done()
}, done); }, done)
}); });
}); });
...@@ -123,80 +99,75 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () { ...@@ -123,80 +99,75 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done) this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).done(done)
}); });
it('with array', function (done) { it('with array', function(done) {
var self = this; var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function(user1) {
return user1.decrement(['aNumber'], 2) return user1.decrement(['aNumber'], 2)
}).then(function () { }).then(function(user2) {
return self.User.find(1); return self.User.find(1)
}).then(function (user3) { }).then(function(user3) {
expect(user3.aNumber).toBe(-2); expect(user3.aNumber).toBe(-2)
done(); done()
}, done); }, done)
}); });
it('with single field', function (done) { it('with single field', function(done) {
var self = this; var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function(user1) {
return user1.decrement(['aNumber'], 2) return user1.decrement(['aNumber'], 2)
}).then(function () { }).then(function(user3) {
return self.User.find(1); return self.User.find(1)
}).then(function (user3) { }).then(function (user3) {
expect(user3.aNumber).toBe(-2); expect(user3.aNumber).toBe(-2)
done(); done()
}, done); }, done)
}); });
it('should still work right with other concurrent decrements', function (done) { it('should still work right with other concurrent decrements', function(done) {
var self = this; var self = this
// Select something // Select something
this.User.find(1).then(function (user1) { this.User.find(1).then(function(user1) {
var _done = _.after(3, function () { var _done = _.after(3, function() {
self.User.find(1).then(function (user2) { self.User.find(1).then(function(user2) {
expect(user2.aNumber).toEqual(-6); expect(user2.aNumber).toEqual(-6)
done(); done()
}) })
}); })
user1.decrement(['aNumber'], 2).done(_done); user1.decrement(['aNumber'], 2).done(_done)
user1.decrement(['aNumber'], 2).done(_done); user1.decrement(['aNumber'], 2).done(_done)
user1.decrement(['aNumber'], 2).done(_done); user1.decrement(['aNumber'], 2).done(_done)
}); })
}); })
}); })
describe('reload', function () { describe('reload', function () {
it("should return a reference to the same DAO instead of creating a new one", function (done) { it("should return a reference to the same DAO instead of creating a new one", function(done) {
this.User.create({ username: 'John Doe' }).then(function (originalUser) { this.User.create({ username: 'John Doe' }).then(function(originalUser) {
return originalUser.updateAttributes({ username: 'Doe John' }).then(function () { return originalUser.updateAttributes({ username: 'Doe John' }).then(function () {
return originalUser.reload() return originalUser.reload()
}).then(function (updatedUser) { }).then(function(updatedUser) {
expect(originalUser === updatedUser).toBeTrue() expect(originalUser === updatedUser).toBeTrue()
done(); done()
}, done) }, done)
}) })
}) })
it("should update the values on all references to the DAO", function (done) { it("should update the values on all references to the DAO", function(done) {
var self = this var self = this
this.User.create({ username: 'John Doe' }).then(function(originalUser) {
this.User.create({ username: 'John Doe' }).then(function (originalUser) { return self.User.find(originalUser.id).then(function(updater) {
return self.User.find(originalUser.id).then(function (updater) {
return updater.updateAttributes({ username: 'Doe John' }) return updater.updateAttributes({ username: 'Doe John' })
}).then(function () { }).then(function () {
// We used a different reference when calling updateAttributes, so originalUser is now out of sync // We used a different reference when calling updateAttributes, so originalUser is now out of sync
expect(originalUser.username).toEqual('John Doe') expect(originalUser.username).toEqual('John Doe')
return originalUser.reload() return originalUser.reload()
}).then(function (updatedUser) { }).then(function(updatedUser) {
expect(originalUser.username).toEqual('Doe John') expect(originalUser.username).toEqual('Doe John')
expect(updatedUser.username).toEqual('Doe John') expect(updatedUser.username).toEqual('Doe John')
done()
done();
}, done) }, done)
}) })
}) })
...@@ -209,44 +180,46 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () { ...@@ -209,44 +180,46 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () {
Book.hasMany(Page) Book.hasMany(Page)
Page.belongsTo(Book) Page.belongsTo(Book)
this.sequelize.sync({ force: true }).then(function () { Book.sync({ force: true }).then(function() {
return Book.create({ title: 'A very old book' }) Page.sync({ force: true }).then(function() {
}).then(function (book) { return Book.create({ title: 'A very old book' })
return Page.create({ content: 'om nom nom' }).then(function (page) { }).then(function (book) {
return book.setPages([ page ]).then(function () { return Page.create({ content: 'om nom nom' }).then(function(page) {
return Book.find({ return book.setPages([ page ]).then(function() {
where: (dialect === 'postgres' ? '"Books"."id"=' : '`Books`.`id`=') + book.id, return Book.find({
include: [Page] where: (dialect === 'postgres' ? '"Books"."id"=' : '`Books`.`id`=') + book.id,
}).then(function (leBook) { include: [Page]
return page.updateAttributes({ content: 'something totally different' }).then(function (page) { }).then(function (leBook) {
expect(leBook.pages[0].content).toEqual('om nom nom') return page.updateAttributes({ content: 'something totally different' }).then(function (page) {
expect(page.content).toEqual('something totally different') expect(leBook.pages[0].content).toEqual('om nom nom')
return leBook.reload().then(function (leBook) {
expect(leBook.pages[0].content).toEqual('something totally different')
expect(page.content).toEqual('something totally different') expect(page.content).toEqual('something totally different')
done() return leBook.reload().then(function (leBook) {
expect(leBook.pages[0].content).toEqual('something totally different')
expect(page.content).toEqual('something totally different')
done()
})
}) })
}) })
}) })
}) })
}) }, done)
}, done) })
}) })
}); })
describe('complete', function () { describe('complete', function () {
it("gets triggered if an error occurs", function (done) { it("gets triggered if an error occurs", function(done) {
this.User.find({ where: "asdasdasd" }).then(null, function (err) { this.User.find({ where: "asdasdasd" }).then(null, function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err.message).toBeDefined() expect(err.message).toBeDefined()
done() done()
}) })
}) })
it("gets triggered if everything was ok", function (done) { it("gets triggered if everything was ok", function(done) {
this.User.count().then(function (result) { this.User.count().then(function(result) {
expect(result).toBeDefined() expect(result).toBeDefined()
done() done()
}) })
...@@ -254,20 +227,20 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () { ...@@ -254,20 +227,20 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () {
}) })
describe('save', function () { describe('save', function () {
it('should fail a validation upon creating', function (done) { it('should fail a validation upon creating', function(done) {
this.User.create({aNumber: 0, validateTest: 'hello'}).then(null, function (err) { this.User.create({aNumber: 0, validateTest: 'hello'}).then(null, function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err).toBeObject() expect(err).toBeObject()
expect(err.validateTest).toBeArray() expect(err.validateTest).toBeArray()
expect(err.validateTest[0]).toBeDefined() expect(err.validateTest[0]).toBeDefined()
expect(err.validateTest[0].indexOf('Invalid integer')).toBeGreaterThan(-1); expect(err.validateTest[0].indexOf('Invalid integer')).toBeGreaterThan(-1)
done(); done()
}); });
}) })
it('should fail a validation upon building', function (done) { it('should fail a validation upon building', function(done) {
this.User.build({aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa'}).save() this.User.build({aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa'}).save()
.then(null, function (err) { .then(null, function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err).toBeObject() expect(err).toBeObject()
expect(err.validateCustom).toBeDefined() expect(err.validateCustom).toBeDefined()
...@@ -278,10 +251,10 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () { ...@@ -278,10 +251,10 @@ describe(Helpers.getTestDialectTeaser("Promise"), function () {
}) })
}) })
it('should fail a validation when updating', function (done) { it('should fail a validation when updating', function(done) {
this.User.create({aNumber: 0}).then(function (user) { this.User.create({aNumber: 0}).then(function (user) {
return user.updateAttributes({validateTest: 'hello'}) return user.updateAttributes({validateTest: 'hello'})
}).then(null, function (err) { }).then(null, function(err) {
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err).toBeObject() expect(err).toBeObject()
expect(err.validateTest).toBeDefined() expect(err.validateTest).toBeDefined()
......
...@@ -10,21 +10,24 @@ buster.spec.expose() ...@@ -10,21 +10,24 @@ buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("QueryChainer"), function() { describe(Helpers.getTestDialectTeaser("QueryChainer"), function() {
before(function() { before(function(done) {
this.queryChainer = new QueryChainer() this.queryChainer = new QueryChainer()
done()
}) })
describe('add', function() { describe('add', function() {
it('adds a new serial item if method is passed', function() { it('adds a new serial item if method is passed', function(done) {
expect(this.queryChainer.serials.length).toEqual(0) expect(this.queryChainer.serials.length).toEqual(0)
this.queryChainer.add({}, 'foo') this.queryChainer.add({}, 'foo')
expect(this.queryChainer.serials.length).toEqual(1) expect(this.queryChainer.serials.length).toEqual(1)
done()
}) })
it('adds a new emitter if no method is passed', function() { it('adds a new emitter if no method is passed', function(done) {
expect(this.queryChainer.emitters.length).toEqual(0) expect(this.queryChainer.emitters.length).toEqual(0)
this.queryChainer.add(new CustomEventEmitter()) this.queryChainer.add(new CustomEventEmitter())
expect(this.queryChainer.emitters.length).toEqual(1) expect(this.queryChainer.emitters.length).toEqual(1)
done()
}) })
}) })
......
/* jshint multistr: true */ /* jshint multistr: true */
var buster = require("buster")
if (typeof require === 'function') { , Helpers = require('./buster-helpers')
var buster = require("buster") , dialect = Helpers.getTestDialect()
, Helpers = require('./buster-helpers') , DataTypes = require(__dirname + "/../lib/data-types")
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 2000 buster.testRunner.timeout = 2000
describe(Helpers.getTestDialectTeaser("QueryGenerators"), function() { describe(Helpers.getTestDialectTeaser("QueryGenerators"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
Helpers.initTests({ this.sequelize = sequelize
dialect: dialect, this.interface = this.sequelize.getQueryInterface()
beforeComplete: function(sequelize, DataTypes) { done()
this.sequelize = sequelize
this.DataTypes = DataTypes
}.bind(this),
onComplete: function() {
this.interface = this.sequelize.getQueryInterface()
done()
}.bind(this)
})
}) })
describe("comments", function() { describe("comments", function() {
it("should create a comment for a column", function(done) { it("should create a comment for a column", function(done) {
var self = this var self = this
, User = this.sequelize.define('User', { , User = this.sequelize.define('User', {
username: {type: this.DataTypes.STRING, comment: 'Some lovely info for my DBA'} username: {type: DataTypes.STRING, comment: 'Some lovely info for my DBA'}
}) })
User.sync().success(function(){ User.sync({ force: true }).success(function(){
var sql = '' var sql = ''
if (dialect === "mysql") { if (dialect === "mysql") {
sql = 'SELECT COLUMN_COMMENT as cmt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \'' + self.sequelize.config.database + '\' AND TABLE_NAME = \'Users\' AND COLUMN_NAME = \'username\''; sql = 'SELECT COLUMN_COMMENT as cmt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \'' + self.sequelize.config.database + '\' AND TABLE_NAME = \'Users\' AND COLUMN_NAME = \'username\'';
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('./buster-helpers')
, CustomEventEmitter = require("../lib/emitters/custom-event-emitter") , dialect = Helpers.getTestDialect()
, Helpers = require('./buster-helpers')
, dialect = Helpers.getTestDialect()
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("QueryInterface"), function() { describe(Helpers.getTestDialectTeaser("QueryInterface"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
Helpers.initTests({ this.sequelize = sequelize
dialect: dialect, this.interface = this.sequelize.getQueryInterface()
beforeComplete: function(sequelize) { done()
this.sequelize = sequelize
}.bind(this),
onComplete: function() {
this.interface = this.sequelize.getQueryInterface()
done()
}.bind(this)
})
}) })
describe('dropAllTables', function() { describe('dropAllTables', function() {
it("should drop all tables", function(done) { it("should drop all tables", function(done) {
var self = this
this.interface.dropAllTables().complete(function(err) { this.interface.dropAllTables().complete(function(err) {
expect(err).toBeNull() expect(err).toBeNull()
this.interface.showAllTables().complete(function(err, tableNames) { self.interface.showAllTables().complete(function(err, tableNames) {
expect(err).toBeNull() expect(err).toBeNull()
expect(tableNames.length).toEqual(0) expect(tableNames.length).toEqual(0)
this.interface.createTable('table', { name: Helpers.Sequelize.STRING }).complete(function(err) { self.interface.createTable('table', { name: Helpers.Sequelize.STRING }).complete(function(err) {
expect(err).toBeNull() expect(err).toBeNull()
this.interface.showAllTables().complete(function(err, tableNames) { self.interface.showAllTables().complete(function(err, tableNames) {
expect(err).toBeNull() expect(err).toBeNull()
expect(tableNames.length).toEqual(1) expect(tableNames.length).toEqual(1)
this.interface.dropAllTables().complete(function(err) { self.interface.dropAllTables().complete(function(err) {
expect(err).toBeNull() expect(err).toBeNull()
this.interface.showAllTables().complete(function(err, tableNames) { self.interface.showAllTables().complete(function(err, tableNames) {
expect(err).toBeNull() expect(err).toBeNull()
expect(tableNames.length).toEqual(0) expect(tableNames.length).toEqual(0)
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
...@@ -63,19 +56,20 @@ describe(Helpers.getTestDialectTeaser("QueryInterface"), function() { ...@@ -63,19 +56,20 @@ describe(Helpers.getTestDialectTeaser("QueryInterface"), function() {
}) })
it('adds, reads and removes an index to the table', function(done) { it('adds, reads and removes an index to the table', function(done) {
var self = this
this.interface.addIndex('User', ['username', 'isAdmin']).complete(function(err) { this.interface.addIndex('User', ['username', 'isAdmin']).complete(function(err) {
expect(err).toBeNull() expect(err).toBeNull()
this.interface.showIndex('User').complete(function(err, indexes) { self.interface.showIndex('User').complete(function(err, indexes) {
expect(err).toBeNull() expect(err).toBeNull()
var indexColumns = Helpers.Sequelize.Utils._.uniq(indexes.map(function(index) { return index.name })) var indexColumns = Helpers.Sequelize.Utils._.uniq(indexes.map(function(index) { return index.name }))
expect(indexColumns).toEqual(['user_username_is_admin']) expect(indexColumns).toEqual(['user_username_is_admin'])
this.interface.removeIndex('User', ['username', 'isAdmin']).complete(function(err) { self.interface.removeIndex('User', ['username', 'isAdmin']).complete(function(err) {
expect(err).toBeNull() expect(err).toBeNull()
this.interface.showIndex('User').complete(function(err, indexes) { self.interface.showIndex('User').complete(function(err, indexes) {
expect(err).toBeNull() expect(err).toBeNull()
indexColumns = Helpers.Sequelize.Utils._.uniq(indexes.map(function(index) { return index.name })) indexColumns = Helpers.Sequelize.Utils._.uniq(indexes.map(function(index) { return index.name }))
...@@ -83,43 +77,42 @@ describe(Helpers.getTestDialectTeaser("QueryInterface"), function() { ...@@ -83,43 +77,42 @@ describe(Helpers.getTestDialectTeaser("QueryInterface"), function() {
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
}) })
describe('describeTable', function() { describe('describeTable', function() {
before(function(done) { it('reads the metadata of the table', function(done) {
var self = this
this.interface.createTable('User', { this.interface.createTable('User', {
username: Helpers.Sequelize.STRING, username: Helpers.Sequelize.STRING,
isAdmin: Helpers.Sequelize.BOOLEAN, isAdmin: Helpers.Sequelize.BOOLEAN,
enumVals: Helpers.Sequelize.ENUM('hello', 'world') enumVals: Helpers.Sequelize.ENUM('hello', 'world')
}).success(done) }).success(function() {
}) self.interface.describeTable('User').complete(function(err, metadata) {
expect(err).toBeNull()
it('reads the metadata of the table', function(done) {
this.interface.describeTable('User').complete(function(err, metadata) {
expect(err).toBeNull()
var username = metadata.username var username = metadata.username
var isAdmin = metadata.isAdmin var isAdmin = metadata.isAdmin
var enumVals = metadata.enumVals var enumVals = metadata.enumVals
expect(username.type).toEqual(dialect === 'postgres' ? 'CHARACTER VARYING' : 'VARCHAR(255)') expect(username.type).toEqual(dialect === 'postgres' ? 'CHARACTER VARYING' : 'VARCHAR(255)')
expect(username.allowNull).toBeTrue() expect(username.allowNull).toBeTrue()
expect(username.defaultValue).toBeNull() expect(username.defaultValue).toBeNull()
expect(isAdmin.type).toEqual(dialect === 'postgres' ? 'BOOLEAN' : 'TINYINT(1)') expect(isAdmin.type).toEqual(dialect === 'postgres' ? 'BOOLEAN' : 'TINYINT(1)')
expect(isAdmin.allowNull).toBeTrue() expect(isAdmin.allowNull).toBeTrue()
expect(isAdmin.defaultValue).toBeNull() expect(isAdmin.defaultValue).toBeNull()
if (dialect === 'postgres') { if (dialect === "postgres" || dialect === "postgres-native") {
expect(enumVals.special).toBeArray(); expect(enumVals.special).toBeArray();
expect(enumVals.special.length).toEqual(2); expect(enumVals.special.length).toEqual(2);
} }
done() done()
})
}) })
}) })
}) })
......
var buster = require("buster")
, Helpers = require('./buster-helpers')
, config = require(__dirname + "/config/config")
, dialect = Helpers.getTestDialect()
, moment = require('moment')
var qq = function(str) {
if (dialect == 'postgres' || dialect == 'sqlite') {
return '"' + str + '"'
} else if (dialect == 'mysql') {
return '`' + str + '`'
} else {
return str
}
}
buster.spec.expose()
buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) {
console.log('BEFORE #1', sequelize.options.quoteIdentifiers)
var self = this
self.sequelize = sequelize
Helpers.clearDatabase(self.sequelize, done)
})
describe('constructor', function() {
it('should pass the global options correctly', function(done) {
var self = Object.create(this)
self.sequelize.options.define = self.sequelize.options.define || {}
self.sequelize.options.define.underscored = true
var DAO = self.sequelize.define('dao', {name: Helpers.Sequelize.STRING})
expect(DAO.options.underscored).toBeTruthy()
done()
})
it('should correctly set the host and the port', function(done) {
var sequelize = Helpers.createSequelizeInstance({ host: '127.0.0.1', port: 1234 })
expect(sequelize.config.port).toEqual(1234)
expect(sequelize.config.host).toEqual('127.0.0.1')
done()
})
})
describe('isDefined', function() {
it("returns false if the dao wasn't defined before", function(done) {
var self = this
expect(self.sequelize.isDefined('Project')).toBeFalse()
done()
})
it("returns true if the dao was defined before", function(done) {
var self = this
self.sequelize.define('Project', {
name: Helpers.Sequelize.STRING
})
expect(self.sequelize.isDefined('Project')).toBeTrue()
done()
})
})
describe('query', function() {
before(function(done) {
var self = this
self.sequelize.options.logging = console.log
self.User = self.sequelize.define('User', {
username: Helpers.Sequelize.STRING
})
self.insertQuery = "INSERT INTO " + qq(self.User.tableName) + " (username, " + qq("createdAt") + ", " + qq("updatedAt") + ") VALUES ('john', '2012-01-01 10:10:10', '2012-01-01 10:10:10')"
console.log('BEFORE #2');
Helpers.clearDatabase(self.sequelize, function() {
self.User.sync({ force: true }).success(done)
})
})
it('executes a query the internal way', function(done) {
var self = this
self.sequelize.query(self.insertQuery, null, { raw: true })
.complete(function(err, result) {
expect(err).toBeNull()
expect(result).toBeNull()
done()
})
})
it('executes a query if only the sql is passed', function(done) {
var self = this
self.sequelize.query(self.insertQuery)
.complete(function(err, result) {
expect(err).toBeNull()
expect(result).not.toBeDefined()
done()
})
})
it('executes select queries correctly', function(done) {
var self = this
sequelize.query(this.insertQuery).success(function() {
sequelize
.query("select * from " + qq(self.User.tableName) + "")
.complete(function(err, users) {
console.log('USERS', users)
expect(err).toBeNull()
expect(users.map(function(u){ return u.username })).toEqual(['john'])
done()
})
})
})
it('executes select queries correctly when quoteIdentifiers is false', function(done) {
var temp = this
var self = cloneObject(this.sequelize)
self.options.quoteIdentifiers = false
self.query(self.insertQuery).success(function() {
self.query("select * from " + qq(temp.User.tableName) + "")
.complete(function(err, users) {
console.log('USERS', users)
expect(err).toBeNull()
expect(users.map(function(u){ return u.username })).toEqual(['john'])
done()
})
})
})
it('executes select query and parses dot notation results', function(done) {
var self = this
self.sequelize.query(self.insertQuery).success(function() {
self.sequelize
.query("select username as " + qq("user.username") + " from " + qq(self.User.tableName) + "")
.complete(function(err, users) {
expect(err).toBeNull()
expect(users.map(function(u){ return u.user })).toEqual([{'username':'john'}])
done()
})
})
})
if (dialect == 'mysql') {
it('executes stored procedures', function(done) {
var self = this
sequelize.query(self.insertQuery).success(function() {
sequelize.query('DROP PROCEDURE IF EXISTS foo').success(function() {
sequelize.query(
"CREATE PROCEDURE foo()\nSELECT * FROM " + self.User.tableName + ";"
).success(function() {
sequelize.query('CALL foo()').success(function(users) {
expect(users.map(function(u){ return u.username })).toEqual(['john'])
done()
})
})
})
})
})
} else {
console.log('FIXME: I want to be supported in this dialect as well :-(')
}
it('uses the passed DAOFactory', function(done) {
var self = this
self.sequelize.query(self.insertQuery).success(function() {
self.sequelize.query("SELECT * FROM " + qq(self.User.tableName) + ";", self.User).success(function(users) {
expect(users[0].__factory).toEqual(self.User)
done()
})
})
})
it('destructs dot separated attributes when doing a raw query', function(done) {
var tickChar = (dialect === 'postgres') ? '"' : '`'
, sql = "select 1 as " + Helpers.Sequelize.Utils.addTicks('foo.bar.baz', tickChar)
, self = this
self.sequelize.query(sql, null, { raw: true }).success(function(result) {
expect(result).toEqual([ { foo: { bar: { baz: 1 } } } ])
done()
})
})
it('replaces token with the passed array', function(done) {
var self = this
self.sequelize.query('select ? as foo, ? as bar', null, { raw: true }, [ 1, 2 ]).success(function(result) {
expect(result).toEqual([{ foo: 1, bar: 2 }])
done()
})
})
it('handles AS in conjunction with functions just fine', function(done) {
var self = this
self.sequelize.query('SELECT ' + (dialect === "sqlite" ? 'date(\'now\')' : 'NOW()') + ' AS t').success(function(result) {
expect(moment(result[0].t).isValid()).toBeTrue()
done()
})
})
})
describe('define', function() {
it("adds a new dao to the dao manager", function(done) {
var self = this
expect(self.sequelize.daoFactoryManager.all.length).toEqual(0)
self.sequelize.define('foo', { title: Helpers.Sequelize.STRING })
expect(self.sequelize.daoFactoryManager.all.length).toEqual(1)
done()
})
it("overwrites global options", function(done) {
var sequelize = Helpers.createSequelizeInstance({ define: { collate: 'utf8_general_ci' } })
var DAO = sequelize.define('foo', {bar: Helpers.Sequelize.STRING}, {collate: 'utf8_bin'})
expect(DAO.options.collate).toEqual('utf8_bin')
done()
})
it("inherits global collate option", function(done) {
var sequelize = Helpers.createSequelizeInstance({ define: { collate: 'utf8_general_ci' } })
var DAO = sequelize.define('foo', {bar: Helpers.Sequelize.STRING})
expect(DAO.options.collate).toEqual('utf8_general_ci')
done()
})
it("inherits global classMethods and instanceMethods", function(done) {
var sequelize = Helpers.createSequelizeInstance({
define: {
classMethods : { globalClassMethod : function() {} },
instanceMethods : { globalInstanceMethod : function() {} }
}
})
var DAO = sequelize.define('foo', {bar: Helpers.Sequelize.STRING}, {
classMethods : { localClassMethod : function() {} }
})
expect(typeof DAO.options.classMethods.globalClassMethod).toEqual('function')
expect(typeof DAO.options.classMethods.localClassMethod).toEqual('function')
expect(typeof DAO.options.instanceMethods.globalInstanceMethod).toEqual('function')
done()
})
it("uses the passed tableName", function(done) {
var self = this
, Photo = this.sequelize.define('Foto', { name: Helpers.Sequelize.STRING }, { tableName: 'photos' })
Photo.sync({ force: true }).success(function() {
self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
expect(tableNames).toContain('photos')
done()
})
})
})
})
describe('sync', function() {
it("synchronizes all daos", function(done) {
var self = this
var Project = self.sequelize.define('project' + config.rand(), { title: Helpers.Sequelize.STRING })
var Task = self.sequelize.define('task' + config.rand(), { title: Helpers.Sequelize.STRING })
self.sequelize.sync().success(function() {
Project.create({title: 'bla'}).success(function() {
Task.create({title: 'bla'}).success(function(task){
expect(task).toBeDefined()
expect(task.title).toEqual('bla')
done()
})
})
})
})
it('works with correct database credentials', function(done) {
var self = this
var User = self.sequelize.define('User', { username: Helpers.Sequelize.STRING })
User.sync().success(function() {
expect(true).toBeTrue()
done()
})
})
it("fails with incorrect database credentials", function(done) {
var sequelize2 = Helpers.getSequelizeInstance('foo', 'bar', null, { logging: false })
, User2 = sequelize2.define('User', { name: Helpers.Sequelize.STRING, bio: Helpers.Sequelize.TEXT })
User2.sync().error(function(err) {
expect(err.message).toMatch(/.*Access\ denied.*/)
done()
})
})
})
describe('drop should work', function() {
it('correctly succeeds', function(done) {
var self = this
, User = self.sequelize.define('Users', {username: Helpers.Sequelize.STRING })
User.sync({ force: true }).success(function() {
User.drop().success(function() {
expect(true).toBeTrue()
done()
})
})
})
})
describe('import', function() {
it("imports a dao definition from a file", function(done) {
var self = this
, Project = self.sequelize.import(__dirname + "/assets/project")
expect(Project).toBeDefined()
done()
})
})
describe('define', function() {
[
{ type: Helpers.Sequelize.ENUM, values: ['scheduled', 'active', 'finished']},
Helpers.Sequelize.ENUM('scheduled', 'active', 'finished')
].forEach(function(status) {
describe('enum', function() {
before(function(done) {
var self = this
self.Review = self.sequelize.define('review', { status: status })
self.Review.sync({ force: true }).success(done)
})
it('raises an error if no values are defined', function(done) {
var self = this
expect(function() {
self.sequelize.define('omnomnom', {
bla: { type: Helpers.Sequelize.ENUM }
})
}).toThrow('Error', 'Values for ENUM haven\'t been defined.')
done()
})
it('correctly stores values', function(done) {
this.Review.create({ status: 'active' }).success(function(review) {
expect(review.status).toEqual('active')
done()
})
})
it('correctly loads values', function(done) {
var self = this
self.Review.create({ status: 'active' }).success(function() {
self.Review.findAll().success(function(reviews) {
expect(reviews[0].status).toEqual('active')
done()
})
})
})
it("doesn't save an instance if value is not in the range of enums", function(done) {
var self = this
expect(function() {
self.Review.create({ status: 'fnord' })
}).toThrow('Error', 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished')
done()
})
})
})
describe('table', function() {
[
{ id: { type: Helpers.Sequelize.BIGINT } },
{ id: { type: Helpers.Sequelize.STRING, allowNull: true } },
{ id: { type: Helpers.Sequelize.BIGINT, allowNull: false, primaryKey: true, autoIncrement: true } }
].forEach(function(customAttributes) {
it('should be able to override options on the default attributes', function(done) {
var self = this
var Picture = self.sequelize.define('picture', Helpers.Sequelize.Utils._.cloneDeep(customAttributes))
Picture.sync({ force: true }).success(function() {
Object.keys(customAttributes).forEach(function(attribute) {
Object.keys(customAttributes[attribute]).forEach(function(option) {
var optionValue = customAttributes[attribute][option];
expect(Picture.rawAttributes[attribute][option]).toBe(optionValue)
});
})
done()
})
})
})
})
})
})
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('./buster-helpers')
, Helpers = require('./buster-helpers') , config = require(__dirname + "/config/config")
, config = require(__dirname + "/config/config") , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , moment = require('moment')
, moment = require('moment')
}
var qq = function(str) { var qq = function(str) {
if (dialect == 'postgres' || dialect == 'sqlite') { if (dialect == 'postgres' || dialect == 'sqlite') {
...@@ -17,15 +15,15 @@ var qq = function(str) { ...@@ -17,15 +15,15 @@ var qq = function(str) {
} }
buster.spec.expose() buster.spec.expose()
buster.timeout = 1000 buster.testRunner.timeout = 1000
describe(Helpers.getTestDialectTeaser("Sequelize"), function() { describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
before(function(done) { before(function(done) {
Helpers.initTests({ var self = this
dialect: dialect, self.sequelize = sequelize
beforeComplete: function(sequelize) { this.sequelize = sequelize }.bind(this), Helpers.clearDatabase(self.sequelize, done)
onComplete: done
})
}) })
describe('constructor', function() { describe('constructor', function() {
...@@ -60,24 +58,19 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -60,24 +58,19 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
describe('query', function() { describe('query', function() {
before(function(done) { before(function(done) {
this.sequelize.options.quoteIdentifiers = true
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: Helpers.Sequelize.STRING username: Helpers.Sequelize.STRING
}) })
this.insertQuery = "INSERT INTO " + qq(this.User.tableName) + " (username, " + qq("createdAt") + ", " + qq("updatedAt") + ") VALUES ('john', '2012-01-01 10:10:10', '2012-01-01 10:10:10')" this.insertQuery = "INSERT INTO " + qq(this.User.tableName) + " (username, " + qq("createdAt") + ", " + qq("updatedAt") + ") VALUES ('john', '2012-01-01 10:10:10', '2012-01-01 10:10:10')"
this.User.sync().success(done).error(function(err) { this.User.sync({ force: true }).success(done)
console.log(err)
done()
})
}) })
it('executes a query the internal way', function(done) { it('executes a query the internal way', function(done) {
this.sequelize.query(this.insertQuery, null, { raw: true }) this.sequelize.query(this.insertQuery, null, { raw: true })
.complete(function(err, result) { .complete(function(err, result) {
if (err) {
console.log(err)
}
expect(err).toBeNull() expect(err).toBeNull()
expect(result).toBeNull() expect(result).toBeNull()
done() done()
...@@ -87,9 +80,6 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -87,9 +80,6 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
it('executes a query if only the sql is passed', function(done) { it('executes a query if only the sql is passed', function(done) {
this.sequelize.query(this.insertQuery) this.sequelize.query(this.insertQuery)
.complete(function(err, result) { .complete(function(err, result) {
if (err) {
console.log(err)
}
expect(err).toBeNull() expect(err).toBeNull()
expect(result).not.toBeDefined() expect(result).not.toBeDefined()
done() done()
...@@ -97,98 +87,97 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -97,98 +87,97 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
}) })
it('executes select queries correctly', function(done) { it('executes select queries correctly', function(done) {
this.sequelize.query(this.insertQuery).success(function() { var self = this
this.sequelize sequelize.query(this.insertQuery).success(function() {
.query("select * from " + qq(this.User.tableName) + "") sequelize
.query("select * from " + qq(self.User.tableName) + "")
.complete(function(err, users) { .complete(function(err, users) {
if (err) {
console.log(err)
}
expect(err).toBeNull() expect(err).toBeNull()
expect(users.map(function(u){ return u.username })).toEqual(['john']) expect(users.map(function(u){ return u.username })).toEqual(['john'])
done() done()
}) })
}.bind(this)) })
}) })
it('executes select queries correctly when quoteIdentifiers is false', function(done) { it('executes select queries correctly when quoteIdentifiers is false', function(done) {
this.sequelize.options.quoteIdentifiers = false var self = this
this.sequelize.query(this.insertQuery).success(function() { , seq = Object.create(self.sequelize)
this.sequelize
.query("select * from " + qq(this.User.tableName) + "") seq.options.quoteIdentifiers = false
seq.query(this.insertQuery).success(function() {
seq.query("select * from " + qq(self.User.tableName) + "")
.complete(function(err, users) { .complete(function(err, users) {
if (err) {
console.log(err)
}
expect(err).toBeNull() expect(err).toBeNull()
expect(users.map(function(u){ return u.username })).toEqual(['john']) expect(users.map(function(u){ return u.username })).toEqual(['john'])
done() done()
}) })
}.bind(this)) })
}) })
it('executes select query and parses dot notation results', function(done) { it('executes select query and parses dot notation results', function(done) {
this.sequelize.query(this.insertQuery).success(function() { var self = this
this.sequelize sequelize.query('DELETE FROM ' + qq(self.User.tableName)).complete(function() {
.query("select username as " + qq("user.username") + " from " + qq(this.User.tableName) + "") sequelize.query(self.insertQuery).success(function() {
.complete(function(err, users) { sequelize
if (err) { .query("select username as " + qq("user.username") + " from " + qq(self.User.tableName) + "")
console.log(err) .complete(function(err, users) {
} expect(err).toBeNull()
expect(err).toBeNull() expect(users.map(function(u){ return u.user })).toEqual([{'username':'john'}])
expect(users.map(function(u){ return u.user })).toEqual([{'username':'john'}]) done()
done() })
}) })
}.bind(this)) })
}) })
if (dialect == 'mysql') { if (dialect == 'mysql') {
it('executes stored procedures', function(done) { it('executes stored procedures', function(done) {
this.sequelize.query(this.insertQuery).success(function() { var self = this
this.sequelize.query('DROP PROCEDURE IF EXISTS foo').success(function() { sequelize.query(this.insertQuery).success(function() {
this.sequelize.query( sequelize.query('DROP PROCEDURE IF EXISTS foo').success(function() {
"CREATE PROCEDURE foo()\nSELECT * FROM " + this.User.tableName + ";" sequelize.query(
"CREATE PROCEDURE foo()\nSELECT * FROM " + self.User.tableName + ";"
).success(function() { ).success(function() {
this.sequelize.query('CALL foo()').success(function(users) { sequelize.query('CALL foo()').success(function(users) {
expect(users.map(function(u){ return u.username })).toEqual(['john']) expect(users.map(function(u){ return u.username })).toEqual(['john'])
done() done()
}) })
}.bind(this)) })
}.bind(this)) })
}.bind(this)) })
}) })
} else { } else {
console.log('FIXME: I want to be supported in this dialect as well :-(') console.log('FIXME: I want to be supported in this dialect as well :-(')
} }
it('uses the passed DAOFactory', function(done) { it('uses the passed DAOFactory', function(done) {
this.sequelize.query(this.insertQuery).success(function() { var self = this
this.sequelize.query("SELECT * FROM " + qq(this.User.tableName) + ";", this.User).success(function(users) { sequelize.query(this.insertQuery).success(function() {
expect(users[0].__factory).toEqual(this.User) sequelize.query("SELECT * FROM " + qq(self.User.tableName) + ";", self.User).success(function(users) {
expect(users[0].__factory).toEqual(self.User)
done() done()
}.bind(this)) })
}.bind(this)) })
}) })
it('destructs dot separated attributes when doing a raw query', function(done) { it('destructs dot separated attributes when doing a raw query', function(done) {
var tickChar = (dialect === 'postgres') ? '"' : '`' var tickChar = (dialect === 'postgres') ? '"' : '`'
, sql = "select 1 as " + Helpers.Sequelize.Utils.addTicks('foo.bar.baz', tickChar) , sql = "select 1 as " + Helpers.Sequelize.Utils.addTicks('foo.bar.baz', tickChar)
this.sequelize.query(sql, null, { raw: true }).success(function(result) { sequelize.query(sql, null, { raw: true }).success(function(result) {
expect(result).toEqual([ { foo: { bar: { baz: 1 } } } ]) expect(result).toEqual([ { foo: { bar: { baz: 1 } } } ])
done() done()
}) })
}) })
it('replaces token with the passed array', function(done) { it('replaces token with the passed array', function(done) {
this.sequelize.query('select ? as foo, ? as bar', null, { raw: true }, [ 1, 2 ]).success(function(result) { sequelize.query('select ? as foo, ? as bar', null, { raw: true }, [ 1, 2 ]).success(function(result) {
expect(result).toEqual([{ foo: 1, bar: 2 }]) expect(result).toEqual([{ foo: 1, bar: 2 }])
done() done()
}) })
}) })
it('handles AS in conjunction with functions just fine', function(done) { it('handles AS in conjunction with functions just fine', function(done) {
this.sequelize.query('SELECT ' + (dialect === "sqlite" ? 'date(\'now\')' : 'NOW()') + ' AS t').success(function(result) { sequelize.query('SELECT ' + (dialect === "sqlite" ? 'date(\'now\')' : 'NOW()') + ' AS t').success(function(result) {
expect(moment(result[0].t).isValid()).toBeTrue() expect(moment(result[0].t).isValid()).toBeTrue()
done() done()
}) })
...@@ -197,9 +186,9 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -197,9 +186,9 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
describe('define', function() { describe('define', function() {
it("adds a new dao to the dao manager", function(done) { it("adds a new dao to the dao manager", function(done) {
expect(this.sequelize.daoFactoryManager.all.length).toEqual(0) expect(sequelize.daoFactoryManager.all.length).toEqual(0)
this.sequelize.define('foo', { title: Helpers.Sequelize.STRING }) sequelize.define('foo', { title: Helpers.Sequelize.STRING })
expect(this.sequelize.daoFactoryManager.all.length).toEqual(1) expect(sequelize.daoFactoryManager.all.length).toEqual(1)
done() done()
}) })
...@@ -239,7 +228,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -239,7 +228,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
var self = this var self = this
, Photo = this.sequelize.define('Foto', { name: Helpers.Sequelize.STRING }, { tableName: 'photos' }) , Photo = this.sequelize.define('Foto', { name: Helpers.Sequelize.STRING }, { tableName: 'photos' })
Photo.sync({ force: true }).success(function() { Photo.sync({ force: true }).success(function() {
self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) { sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
expect(tableNames).toContain('photos') expect(tableNames).toContain('photos')
done() done()
}) })
...@@ -252,7 +241,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -252,7 +241,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
var Project = this.sequelize.define('project' + config.rand(), { title: Helpers.Sequelize.STRING }) var Project = this.sequelize.define('project' + config.rand(), { title: Helpers.Sequelize.STRING })
var Task = this.sequelize.define('task' + config.rand(), { title: Helpers.Sequelize.STRING }) var Task = this.sequelize.define('task' + config.rand(), { title: Helpers.Sequelize.STRING })
this.sequelize.sync().success(function() { sequelize.sync().success(function() {
Project.create({title: 'bla'}).success(function() { Project.create({title: 'bla'}).success(function() {
Task.create({title: 'bla'}).success(function(task){ Task.create({title: 'bla'}).success(function(task){
expect(task).toBeDefined() expect(task).toBeDefined()
...@@ -264,7 +253,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -264,7 +253,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
}) })
it('works with correct database credentials', function(done) { it('works with correct database credentials', function(done) {
var User = this.sequelize.define('User', { username: Helpers.Sequelize.STRING }) var User = sequelize.define('User', { username: Helpers.Sequelize.STRING })
User.sync().success(function() { User.sync().success(function() {
expect(true).toBeTrue() expect(true).toBeTrue()
done() done()
...@@ -284,7 +273,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -284,7 +273,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
describe('drop should work', function() { describe('drop should work', function() {
it('correctly succeeds', function(done) { it('correctly succeeds', function(done) {
var User = this.sequelize.define('Users', {username: Helpers.Sequelize.STRING }) var User = sequelize.define('Users', {username: Helpers.Sequelize.STRING })
User.sync({ force: true }).success(function() { User.sync({ force: true }).success(function() {
User.drop().success(function() { User.drop().success(function() {
expect(true).toBeTrue() expect(true).toBeTrue()
...@@ -296,7 +285,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -296,7 +285,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
describe('import', function() { describe('import', function() {
it("imports a dao definition from a file", function(done) { it("imports a dao definition from a file", function(done) {
var Project = this.sequelize.import(__dirname + "/assets/project") var Project = sequelize.import(__dirname + "/assets/project")
expect(Project).toBeDefined() expect(Project).toBeDefined()
done() done()
}) })
...@@ -309,16 +298,17 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -309,16 +298,17 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
].forEach(function(status) { ].forEach(function(status) {
describe('enum', function() { describe('enum', function() {
before(function(done) { before(function(done) {
this.Review = this.sequelize.define('review', { status: status }) this.Review = sequelize.define('review', { status: status })
this.Review.sync({ force: true }).success(done) this.Review.sync({ force: true }).success(done)
}) })
it('raises an error if no values are defined', function() { it('raises an error if no values are defined', function(done) {
Helpers.assertException(function() { expect(function() {
this.sequelize.define('omnomnom', { sequelize.define('omnomnom', {
bla: { type: Helpers.Sequelize.ENUM } bla: { type: Helpers.Sequelize.ENUM }
}) })
}.bind(this), 'Values for ENUM haven\'t been defined.') }).toThrow('Error', 'Values for ENUM haven\'t been defined.')
done()
}) })
it('correctly stores values', function(done) { it('correctly stores values', function(done) {
...@@ -329,18 +319,21 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -329,18 +319,21 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
}) })
it('correctly loads values', function(done) { it('correctly loads values', function(done) {
var self = this
this.Review.create({ status: 'active' }).success(function() { this.Review.create({ status: 'active' }).success(function() {
this.Review.findAll().success(function(reviews) { self.Review.findAll().success(function(reviews) {
expect(reviews[0].status).toEqual('active') expect(reviews[0].status).toEqual('active')
done() done()
}) })
}.bind(this)) })
}) })
it("doesn't save an instance if value is not in the range of enums", function() { it("doesn't save an instance if value is not in the range of enums", function(done) {
Helpers.assertException(function() { var self = this
this.Review.create({ status: 'fnord' }) expect(function() {
}.bind(this), 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished') self.Review.create({ status: 'fnord' })
}).toThrow('Error', 'Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished')
done()
}) })
}) })
}) })
...@@ -353,7 +346,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() { ...@@ -353,7 +346,7 @@ describe(Helpers.getTestDialectTeaser("Sequelize"), function() {
].forEach(function(customAttributes) { ].forEach(function(customAttributes) {
it('should be able to override options on the default attributes', function(done) { it('should be able to override options on the default attributes', function(done) {
var Picture = this.sequelize.define('picture', Helpers.Sequelize.Utils._.cloneDeep(customAttributes)) var Picture = sequelize.define('picture', Helpers.Sequelize.Utils._.cloneDeep(customAttributes))
Picture.sync({ force: true }).success(function() { Picture.sync({ force: true }).success(function() {
Object.keys(customAttributes).forEach(function(attribute) { Object.keys(customAttributes).forEach(function(attribute) {
Object.keys(customAttributes[attribute]).forEach(function(option) { Object.keys(customAttributes[attribute]).forEach(function(option) {
......
/* jshint camelcase: false */ /* jshint camelcase: false */
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , dbFile = __dirname + '/test.sqlite'
, dbFile = __dirname + '/test.sqlite' , storages = [dbFile]
, storages = [dbFile] , DataTypes = require(__dirname + "/../../lib/data-types")
, DataTypes = require(__dirname + "/../../lib/data-types")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
describe('[SQLITE] DAOFactory', function() { describe('[SQLITE] DAOFactory', function() {
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, function() {
dialect: 'sqlite', self.User = sequelize.define('User', {
beforeComplete: function(sequelize, DataTypes) { age: DataTypes.INTEGER,
self.sequelize = sequelize name: DataTypes.STRING,
bio: DataTypes.TEXT
self.User = sequelize.define('User', { })
age: DataTypes.INTEGER, self.User.sync({ force: true }).success(done)
name: DataTypes.STRING,
bio: DataTypes.TEXT
})
},
onComplete: function() {
self.User.sync({ force: true }).success(done)
}
}) })
}) })
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , DataTypes = require(__dirname + "/../../lib/data-types")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
describe('[SQLITE] DAO', function() { describe('[SQLITE] DAO', function() {
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, function() {
dialect: 'sqlite', self.User = sequelize.define('User', {
beforeComplete: function(sequelize, DataTypes) { username: DataTypes.STRING
self.sequelize = sequelize })
self.User.sync({ force: true }).success(done)
self.User = sequelize.define('User', {
username: DataTypes.STRING
})
},
onComplete: function() {
self.User.sync({ force: true }).success(done)
}
}) })
}) })
...@@ -32,8 +27,8 @@ if (dialect === 'sqlite') { ...@@ -32,8 +27,8 @@ if (dialect === 'sqlite') {
this.User this.User
.create({ username: 'user', createdAt: new Date(2011, 04, 04) }) .create({ username: 'user', createdAt: new Date(2011, 04, 04) })
.success(function(oldUser) { .success(function() {
self.User.create({ username: 'new user' }).success(function(newUser) { self.User.create({ username: 'new user' }).success(function() {
self.User.findAll({ self.User.findAll({
where: ['createdAt > ?', new Date(2012, 01, 01)] where: ['createdAt > ?', new Date(2012, 01, 01)]
}).success(function(users) { }).success(function(users) {
......
if(typeof require === 'function') { var buster = require("buster")
const buster = require("buster") , Helpers = require('../buster-helpers')
, Helpers = require('../buster-helpers') , dialect = Helpers.getTestDialect()
, dialect = Helpers.getTestDialect() , QueryGenerator = require("../../lib/dialects/sqlite/query-generator")
, QueryGenerator = require("../../lib/dialects/sqlite/query-generator") , util = require("util")
, util = require("util"); , DataTypes = require(__dirname + "/../../lib/data-types")
}
buster.spec.expose() buster.spec.expose()
buster.testRunner.timeout = 1000 buster.testRunner.timeout = 1000
var sequelize = Helpers.createSequelizeInstance({dialect: dialect})
if (dialect === 'sqlite') { if (dialect === 'sqlite') {
describe('[SQLITE] QueryGenerator', function() { describe('[SQLITE] QueryGenerator', function() {
before(function(done) { before(function(done) {
var self = this var self = this
this.sequelize = sequelize
Helpers.initTests({ Helpers.clearDatabase(this.sequelize, function() {
dialect: 'sqlite', self.User = sequelize.define('User', {
beforeComplete: function(sequelize, DataTypes) { username: DataTypes.STRING
self.sequelize = sequelize })
self.User.sync({ force: true }).success(done)
self.User = sequelize.define('User', {
username: DataTypes.STRING
})
},
onComplete: function() {
self.User.sync({ force: true }).success(done)
}
}) })
}) })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!