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

Commit f5fc5010 by Mick Hansen

Merge pull request #3443 from BridgeAR/master

WIP Refactor almost all tests to use promise style
2 parents 768c4400 3ce25c28
......@@ -52,11 +52,10 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
}
});
it('when we don\'t have a valid dialect.', function(done) {
it('when we don\'t have a valid dialect.', 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});
}).to.throw(Error, 'The dialect undefined is not supported.');
done();
});
});
......@@ -75,13 +74,12 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
expect(config.port).to.equal('9821');
});
it('should work with no authentication options', function(done) {
it('should work with no authentication options', function() {
var sequelize = new Sequelize('mysql://example.com:9821/dbname');
var config = sequelize.config;
expect(config.username).to.not.be.ok;
expect(config.password).to.be.null;
done();
});
it('should work with no authentication options and passing additional options', function() {
......@@ -113,26 +111,24 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
});
describe('Intantiation with arguments', function() {
it('should accept two parameters (database, username)', function(done) {
it('should accept two parameters (database, username)', function() {
var sequelize = new Sequelize('dbname', 'root');
var config = sequelize.config;
expect(config.database).to.equal('dbname');
expect(config.username).to.equal('root');
done();
});
it('should accept three parameters (database, username, password)', function(done) {
it('should accept three parameters (database, username, password)', function() {
var sequelize = new Sequelize('dbname', 'root', 'pass');
var config = sequelize.config;
expect(config.database).to.equal('dbname');
expect(config.username).to.equal('root');
expect(config.password).to.equal('pass');
done();
});
it('should accept four parameters (database, username, password, options)', function(done) {
it('should accept four parameters (database, username, password, options)', function() {
var sequelize = new Sequelize('dbname', 'root', 'pass', {
port: 999,
dialectOptions: {
......@@ -148,7 +144,6 @@ describe(Support.getTestDialectTeaser('Configuration'), function() {
expect(config.port).to.equal(999);
expect(config.dialectOptions.supportBigNumbers).to.be.true;
expect(config.dialectOptions.bigNumberStrings).to.be.true;
done();
});
});
......
......@@ -11,33 +11,30 @@ if (Support.dialectIsMySQL()) {
describe('[MYSQL Specific] Associations', function() {
describe('many-to-many', function() {
describe('where tables have the same prefix', function() {
it('should create a table wp_table1wp_table2s', function(done) {
it('should create a table wp_table1wp_table2s', function() {
var Table2 = this.sequelize.define('wp_table2', {foo: DataTypes.STRING})
, Table1 = this.sequelize.define('wp_table1', {foo: DataTypes.STRING})
, self = this;
Table1.hasMany(Table2);
Table2.hasMany(Table1);
Table1.sync({ force: true }).success(function() {
Table2.sync({ force: true }).success(function() {
return Table1.sync({ force: true }).then(function() {
return Table2.sync({ force: true }).then(function() {
expect(self.sequelize.daoFactoryManager.getDAO('wp_table1swp_table2s')).to.exist;
done();
});
});
});
});
describe('when join table name is specified', function() {
beforeEach(function(done) {
beforeEach(function() {
var Table2 = this.sequelize.define('ms_table1', {foo: DataTypes.STRING})
, Table1 = this.sequelize.define('ms_table2', {foo: DataTypes.STRING});
Table1.hasMany(Table2, {joinTableName: 'table1_to_table2'});
Table2.hasMany(Table1, {joinTableName: 'table1_to_table2'});
Table1.sync({ force: true }).success(function() {
Table2.sync({ force: true }).success(function() {
done();
});
return Table1.sync({ force: true }).then(function() {
return Table2.sync({ force: true });
});
});
......@@ -50,7 +47,7 @@ if (Support.dialectIsMySQL()) {
describe('HasMany', function() {
beforeEach(function(done) {
beforeEach(function() {
//prevent periods from occurring in the table name since they are used to delimit (table.column)
this.User = this.sequelize.define('User' + Math.ceil(Math.random() * 10000000), { name: DataTypes.STRING });
this.Task = this.sequelize.define('Task' + Math.ceil(Math.random() * 10000000), { name: DataTypes.STRING });
......@@ -72,40 +69,36 @@ if (Support.dialectIsMySQL()) {
tasks[tasks.length] = {name: 'Task' + Math.random()};
}
this.sequelize.sync({ force: true }).success(function() {
self.User.bulkCreate(users).success(function() {
self.Task.bulkCreate(tasks).success(function() {
done();
});
return this.sequelize.sync({ force: true }).then(function() {
return self.User.bulkCreate(users).then(function() {
return self.Task.bulkCreate(tasks);
});
});
});
describe('addDAO / getDAO', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.user = null;
self.task = null;
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
return self.User.findAll().then(function(_users) {
return self.Task.findAll().then(function(_tasks) {
self.user = _users[0];
self.task = _tasks[0];
done();
});
});
});
it('should correctly add an association to the dao', function(done) {
it('should correctly add an association to the dao', function() {
var self = this;
self.user.getTasks().on('success', function(_tasks) {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks.length).to.equal(0);
self.user.addTask(self.task).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.addTask(self.task).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks.length).to.equal(1);
done();
});
});
});
......@@ -113,36 +106,34 @@ if (Support.dialectIsMySQL()) {
});
describe('removeDAO', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.user = null;
self.tasks = null;
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
return self.User.findAll().then(function(_users) {
return self.Task.findAll().then(function(_tasks) {
self.user = _users[0];
self.tasks = _tasks;
done();
});
});
});
it('should correctly remove associated objects', function(done) {
it('should correctly remove associated objects', function() {
var self = this;
self.user.getTasks().on('success', function(__tasks) {
return self.user.getTasks().then(function(__tasks) {
expect(__tasks.length).to.equal(0);
self.user.setTasks(self.tasks).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.setTasks(self.tasks).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks.length).to.equal(self.tasks.length);
self.user.removeTask(self.tasks[0]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.removeTask(self.tasks[0]).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks.length).to.equal(self.tasks.length - 1);
self.user.removeTasks([self.tasks[1], self.tasks[2]]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.removeTasks([self.tasks[1], self.tasks[2]]).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 3);
done();
});
});
});
......
......@@ -10,25 +10,25 @@ chai.config.includeStack = true;
if (Support.dialectIsMySQL()) {
describe('[MYSQL Specific] Connector Manager', function() {
it('works correctly after being idle', function(done) {
it('works correctly after being idle', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING })
, spy = sinon.spy();
, spy = sinon.spy()
, self = this;
User.sync({force: true}).on('success', function() {
User.create({username: 'user1'}).on('success', function() {
User.count().on('success', function(count) {
return User.sync({force: true}).then(function() {
return User.create({username: 'user1'}).then(function() {
return User.count().then(function(count) {
expect(count).to.equal(1);
spy();
setTimeout(function() {
User.count().on('success', function(count) {
return self.sequelize.Promise.delay(1000).then(function() {
return User.count().then(function(count) {
expect(count).to.equal(1);
spy();
if (spy.calledTwice) {
done();
if (!spy.calledTwice) {
throw new Error('Spy was not called twice');
}
});
}, 1000);
});
});
});
});
......
......@@ -11,81 +11,71 @@ chai.config.includeStack = true;
if (Support.dialectIsMySQL()) {
describe('[MYSQL Specific] DAOFactory', function() {
describe('constructor', function() {
it('handles extended attributes (unique)', function(done) {
it('handles extended attributes (unique)', function() {
var User = this.sequelize.define('User' + config.rand(), {
username: { type: DataTypes.STRING, unique: true }
}, { timestamps: false });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({username: 'VARCHAR(255) UNIQUE', id: 'INTEGER NOT NULL auto_increment PRIMARY KEY'});
done();
});
it('handles extended attributes (default)', function(done) {
it('handles extended attributes (default)', function() {
var User = this.sequelize.define('User' + config.rand(), {
username: {type: DataTypes.STRING, defaultValue: 'foo'}
}, { timestamps: false });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({username: "VARCHAR(255) DEFAULT 'foo'", id: 'INTEGER NOT NULL auto_increment PRIMARY KEY'});
done();
});
it('handles extended attributes (null)', function(done) {
it('handles extended attributes (null)', function() {
var User = this.sequelize.define('User' + config.rand(), {
username: {type: DataTypes.STRING, allowNull: false}
}, { timestamps: false });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({username: 'VARCHAR(255) NOT NULL', id: 'INTEGER NOT NULL auto_increment PRIMARY KEY'});
done();
});
it('handles extended attributes (primaryKey)', function(done) {
it('handles extended attributes (primaryKey)', function() {
var User = this.sequelize.define('User' + config.rand(), {
username: {type: DataTypes.STRING, primaryKey: true}
}, { timestamps: false });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({username: 'VARCHAR(255) PRIMARY KEY'});
done();
});
it('adds timestamps', function(done) {
it('adds timestamps', function() {
var User1 = this.sequelize.define('User' + config.rand(), {});
var User2 = this.sequelize.define('User' + config.rand(), {}, { timestamps: true });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User1.attributes)).to.deep.equal({id: 'INTEGER NOT NULL auto_increment PRIMARY KEY', updatedAt: 'DATETIME NOT NULL', createdAt: 'DATETIME NOT NULL'});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User2.attributes)).to.deep.equal({id: 'INTEGER NOT NULL auto_increment PRIMARY KEY', updatedAt: 'DATETIME NOT NULL', createdAt: 'DATETIME NOT NULL'});
done();
});
it('adds deletedAt if paranoid', function(done) {
it('adds deletedAt if paranoid', function() {
var User = this.sequelize.define('User' + config.rand(), {}, { paranoid: true });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({id: 'INTEGER NOT NULL auto_increment PRIMARY KEY', deletedAt: 'DATETIME', updatedAt: 'DATETIME NOT NULL', createdAt: 'DATETIME NOT NULL'});
done();
});
it('underscores timestamps if underscored', function(done) {
it('underscores timestamps if underscored', function() {
var User = this.sequelize.define('User' + config.rand(), {}, { paranoid: true, underscored: true });
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.attributes)).to.deep.equal({id: 'INTEGER NOT NULL auto_increment PRIMARY KEY', deleted_at: 'DATETIME', updated_at: 'DATETIME NOT NULL', created_at: 'DATETIME NOT NULL'});
done();
});
it('omits text fields with defaultValues', function(done) {
it('omits text fields with defaultValues', function() {
var User = this.sequelize.define('User' + config.rand(), {name: {type: DataTypes.TEXT, defaultValue: 'helloworld'}});
expect(User.attributes.name.type.toString()).to.equal('TEXT');
done();
});
it('omits blobs fields with defaultValues', function(done) {
it('omits blobs fields with defaultValues', function() {
var User = this.sequelize.define('User' + config.rand(), {name: {type: DataTypes.STRING.BINARY, defaultValue: 'helloworld'}});
expect(User.attributes.name.type.toString()).to.equal('VARCHAR(255) BINARY');
done();
});
});
describe('primaryKeys', function() {
it('determines the correct primaryKeys', function(done) {
it('determines the correct primaryKeys', function() {
var User = this.sequelize.define('User' + config.rand(), {
foo: {type: DataTypes.STRING, primaryKey: true},
bar: DataTypes.STRING
});
expect(this.sequelize.getQueryInterface().QueryGenerator.attributesToSQL(User.primaryKeys)).to.deep.equal({'foo': 'VARCHAR(255) PRIMARY KEY'});
done();
});
});
});
......
......@@ -56,7 +56,7 @@ if (dialect.match(/^postgres/)) {
describe('HasMany', function() {
describe('addDAO / getDAO', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
//prevent periods from occurring in the table name since they are used to delimit (table.column)
......@@ -79,14 +79,13 @@ if (dialect.match(/^postgres/)) {
tasks[tasks.length] = {name: 'Task' + Math.random()};
}
this.sequelize.sync({ force: true }).success(function() {
self.User.bulkCreate(users).success(function() {
self.Task.bulkCreate(tasks).success(function() {
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
return this.sequelize.sync({ force: true }).then(function() {
return self.User.bulkCreate(users).then(function() {
return self.Task.bulkCreate(tasks).then(function() {
return self.User.findAll().then(function(_users) {
return self.Task.findAll().then(function(_tasks) {
self.user = _users[0];
self.task = _tasks[0];
done();
});
});
});
......@@ -94,15 +93,14 @@ if (dialect.match(/^postgres/)) {
});
});
it('should correctly add an association to the dao', function(done) {
it('should correctly add an association to the dao', function() {
var self = this;
self.user.getTasks().on('success', function(_tasks) {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(0);
self.user.addTask(self.task).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.addTask(self.task).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(1);
done();
});
});
});
......@@ -110,7 +108,7 @@ if (dialect.match(/^postgres/)) {
});
describe('removeDAO', function() {
it('should correctly remove associated objects', function(done) {
it('should correctly remove associated objects', function() {
var self = this
, users = []
, tasks = [];
......@@ -132,30 +130,27 @@ if (dialect.match(/^postgres/)) {
tasks[tasks.length] = {id: x + 1, name: 'Task' + Math.random()};
}
this.sequelize.sync({ force: true }).success(function() {
self.User.bulkCreate(users).done(function(err) {
expect(err).not.to.be.ok;
self.Task.bulkCreate(tasks).done(function(err) {
expect(err).not.to.be.ok;
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
return this.sequelize.sync({ force: true }).then(function() {
return self.User.bulkCreate(users).then(function() {
return self.Task.bulkCreate(tasks).then(function() {
return self.User.findAll().then(function(_users) {
return self.Task.findAll().then(function(_tasks) {
self.user = _users[0];
self.task = _tasks[0];
self.users = _users;
self.tasks = _tasks;
self.user.getTasks().on('success', function(__tasks) {
return self.user.getTasks().then(function(__tasks) {
expect(__tasks).to.have.length(0);
self.user.setTasks(self.tasks).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.setTasks(self.tasks).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length);
self.user.removeTask(self.tasks[0]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.removeTask(self.tasks[0]).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 1);
self.user.removeTasks([self.tasks[1], self.tasks[2]]).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
return self.user.removeTasks([self.tasks[1], self.tasks[2]]).then(function() {
return self.user.getTasks().then(function(_tasks) {
expect(_tasks).to.have.length(self.tasks.length - 3);
done();
});
});
});
......
......@@ -13,7 +13,7 @@ chai.config.includeStack = true;
if (dialect.match(/^postgres/)) {
describe('[POSTGRES Specific] DAO', function() {
beforeEach(function(done) {
beforeEach(function() {
this.sequelize.options.quoteIdentifiers = true;
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
......@@ -31,20 +31,16 @@ if (dialect.match(/^postgres/)) {
available_amount: DataTypes.RANGE,
holidays: DataTypes.ARRAY(DataTypes.RANGE(DataTypes.DATE))
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
afterEach(function(done) {
afterEach(function() {
this.sequelize.options.quoteIdentifiers = true;
done();
});
it('should be able to search within an array', function(done) {
this.User.all({where: {email: ['hello', 'world']}, attributes: ['id','username','email','settings','document','phones','emergency_contact','friends']}).on('sql', function(sql) {
it('should be able to search within an array', function() {
return this.User.findAll({where: {email: ['hello', 'world']}, attributes: ['id','username','email','settings','document','phones','emergency_contact','friends']}).on('sql', function(sql) {
expect(sql).to.equal('SELECT "id", "username", "email", "settings", "document", "phones", "emergency_contact", "friends" FROM "Users" AS "User" WHERE "User"."email" = ARRAY[\'hello\',\'world\']::TEXT[];');
done();
});
});
......@@ -72,17 +68,16 @@ if (dialect.match(/^postgres/)) {
});
});
it('should be able to find a record while searching in an array', function(done) {
it('should be able to find a record while searching in an array', function() {
var self = this;
this.User.bulkCreate([
return this.User.bulkCreate([
{username: 'bob', email: ['myemail@email.com']},
{username: 'tony', email: ['wrongemail@email.com']}
]).success(function() {
self.User.all({where: {email: ['myemail@email.com']}}).success(function(user) {
]).then(function() {
return self.User.findAll({where: {email: ['myemail@email.com']}}).then(function(user) {
expect(user).to.be.instanceof(Array);
expect(user).to.have.length(1);
expect(user[0].username).to.equal('bob');
done();
});
});
});
......@@ -318,31 +313,27 @@ if (dialect.match(/^postgres/)) {
});
describe('enums', function() {
it('should be able to ignore enum types that already exist', function(done) {
it('should be able to ignore enum types that already exist', function() {
var User = this.sequelize.define('UserEnums', {
mood: DataTypes.ENUM('happy', 'sad', 'meh')
});
User.sync({ force: true }).success(function() {
User.sync().success(function() {
done();
});
return User.sync({ force: true }).then(function() {
return User.sync();
});
});
it('should be able to create/drop enums multiple times', function(done) {
it('should be able to create/drop enums multiple times', function() {
var User = this.sequelize.define('UserEnums', {
mood: DataTypes.ENUM('happy', 'sad', 'meh')
});
User.sync({ force: true }).success(function() {
User.sync({ force: true }).success(function() {
done();
});
return User.sync({ force: true }).then(function() {
return User.sync({ force: true });
});
});
it('should be able to create/drop multiple enums multiple times', function(done) {
it('should be able to create/drop multiple enums multiple times', function() {
var DummyModel = this.sequelize.define('Dummy-pg', {
username: DataTypes.STRING,
theEnumOne: {
......@@ -363,16 +354,11 @@ if (dialect.match(/^postgres/)) {
}
});
DummyModel.sync({ force: true }).done(function(err) {
expect(err).not.to.be.ok;
return DummyModel.sync({ force: true }).then(function() {
// now sync one more time:
DummyModel.sync({force: true}).done(function(err) {
expect(err).not.to.be.ok;
return DummyModel.sync({force: true}).then(function() {
// sync without dropping
DummyModel.sync().done(function(err) {
expect(err).not.to.be.ok;
done();
});
return DummyModel.sync();
});
});
});
......@@ -387,12 +373,12 @@ if (dialect.match(/^postgres/)) {
done();
});
User.sync({ force: true }).success(function() {
User.sync({ force: true }).then(function() {
User = self.sequelize.define('UserEnums', {
mood: DataTypes.ENUM('neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful')
});
User.sync().success(function() {
User.sync().then(function() {
expect(User.rawAttributes.mood.values).to.deep.equal(['neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful']);
_done();
}).on('sql', function(sql) {
......@@ -415,72 +401,64 @@ if (dialect.match(/^postgres/)) {
describe('integers', function() {
describe('integer', function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
aNumber: DataTypes.INTEGER
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
it('positive', function(done) {
it('positive', function() {
var User = this.User;
User.create({aNumber: 2147483647}).success(function(user) {
return User.create({aNumber: 2147483647}).then(function(user) {
expect(user.aNumber).to.equal(2147483647);
User.find({where: {aNumber: 2147483647}}).success(function(_user) {
return User.find({where: {aNumber: 2147483647}}).then(function(_user) {
expect(_user.aNumber).to.equal(2147483647);
done();
});
});
});
it('negative', function(done) {
it('negative', function() {
var User = this.User;
User.create({aNumber: -2147483647}).success(function(user) {
return User.create({aNumber: -2147483647}).then(function(user) {
expect(user.aNumber).to.equal(-2147483647);
User.find({where: {aNumber: -2147483647}}).success(function(_user) {
return User.find({where: {aNumber: -2147483647}}).then(function(_user) {
expect(_user.aNumber).to.equal(-2147483647);
done();
});
});
});
});
describe('bigint', function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
aNumber: DataTypes.BIGINT
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
it('positive', function(done) {
it('positive', function() {
var User = this.User;
User.create({aNumber: '9223372036854775807'}).success(function(user) {
return User.create({aNumber: '9223372036854775807'}).then(function(user) {
expect(user.aNumber).to.equal('9223372036854775807');
User.find({where: {aNumber: '9223372036854775807'}}).success(function(_user) {
return User.find({where: {aNumber: '9223372036854775807'}}).then(function(_user) {
expect(_user.aNumber).to.equal('9223372036854775807');
done();
});
});
});
it('negative', function(done) {
it('negative', function() {
var User = this.User;
User.create({aNumber: '-9223372036854775807'}).success(function(user) {
return User.create({aNumber: '-9223372036854775807'}).then(function(user) {
expect(user.aNumber).to.equal('-9223372036854775807');
User.find({where: {aNumber: '-9223372036854775807'}}).success(function(_user) {
return User.find({where: {aNumber: '-9223372036854775807'}}).then(function(_user) {
expect(_user.aNumber).to.equal('-9223372036854775807');
done();
});
});
});
......@@ -488,35 +466,28 @@ if (dialect.match(/^postgres/)) {
});
describe('timestamps', function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
dates: DataTypes.ARRAY(DataTypes.DATE)
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
it('should use postgres "TIMESTAMP WITH TIME ZONE" instead of "DATETIME"', function(done) {
this.User.create({
it('should use postgres "TIMESTAMP WITH TIME ZONE" instead of "DATETIME"', function() {
return this.User.create({
dates: []
}).on('sql', function(sql) {
expect(sql.indexOf('TIMESTAMP WITH TIME ZONE')).to.be.greaterThan(0);
done();
});
});
});
describe('model', function() {
it('create handles array correctly', function(done) {
this.User
it('create handles array correctly', function() {
return this.User
.create({ username: 'user', email: ['foo@bar.com', 'bar@baz.com'] })
.success(function(oldUser) {
.then(function(oldUser) {
expect(oldUser.email).to.contain.members(['foo@bar.com', 'bar@baz.com']);
done();
})
.error(function(err) {
console.log(err);
});
});
......@@ -575,7 +546,7 @@ if (dialect.match(/^postgres/)) {
// Check to see if updating an hstore field works
return self.User.update({settings: {should: 'update', to: 'this', first: 'place'}}, {where: newUser.identifiers}).then(function() {
return newUser.reload().success(function() {
return newUser.reload().then(function() {
// Postgres always returns keys in alphabetical order (ascending)
expect(newUser.settings).to.deep.equal({first: 'place', should: 'update', to: 'this'});
});
......@@ -622,10 +593,10 @@ if (dialect.match(/^postgres/)) {
});
});
it('should read hstore correctly from multiple rows', function(done) {
it('should read hstore correctly from multiple rows', function() {
var self = this;
self.User
return self.User
.create({ username: 'user1', email: ['foo@bar.com'], settings: { test: '"value"' }})
.then(function() {
return self.User.create({ username: 'user2', email: ['foo2@bar.com'], settings: { another: '"example"' }});
......@@ -637,10 +608,7 @@ if (dialect.match(/^postgres/)) {
.then(function(users) {
expect(users[0].settings).to.deep.equal({ test: '"value"' });
expect(users[1].settings).to.deep.equal({ another: '"example"' });
done();
})
.error(console.log);
});
});
it('should read hstore correctly from included models as well', function() {
......@@ -763,7 +731,7 @@ if (dialect.match(/^postgres/)) {
// Check to see if updating a range field works
return User.update({course_period: period}, {where: newUser.identifiers}).then(function() {
return newUser.reload().success(function() {
return newUser.reload().then(function() {
expect(newUser.course_period[0] instanceof Date).to.be.ok;
expect(newUser.course_period[1] instanceof Date).to.be.ok;
expect(newUser.course_period[0]).to.equalTime(period[0]); // lower bound
......@@ -858,8 +826,7 @@ if (dialect.match(/^postgres/)) {
expect(users[1].course_period[0]).to.equalTime(periods[1][0]); // lower bound
expect(users[1].course_period[1]).to.equalTime(periods[1][1]); // upper bound
expect(users[1].course_period.inclusive).to.deep.equal([false, false]); // not inclusive
})
.error(console.log);
});
});
it('should read range correctly from included models as well', function () {
......@@ -897,7 +864,7 @@ if (dialect.match(/^postgres/)) {
});
describe('[POSTGRES] Unquoted identifiers', function() {
it('can insert and select', function(done) {
it('can insert and select', function() {
var self = this;
this.sequelize.options.quoteIdentifiers = false;
this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = false;
......@@ -909,10 +876,10 @@ if (dialect.match(/^postgres/)) {
quoteIdentifiers: false
});
this.User.sync({ force: true }).success(function() {
self.User
return this.User.sync({ force: true }).then(function() {
return self.User
.create({ username: 'user', fullName: 'John Smith' })
.success(function(user) {
.then(function(user) {
// We can insert into a table with non-quoted identifiers
expect(user.id).to.exist;
expect(user.id).not.to.be.null;
......@@ -920,27 +887,25 @@ if (dialect.match(/^postgres/)) {
expect(user.fullName).to.equal('John Smith');
// We can query by non-quoted identifiers
self.User.find({
return self.User.find({
where: {fullName: 'John Smith'}
})
.success(function(user2) {
.then(function(user2) {
// We can map values back to non-quoted identifiers
expect(user2.id).to.equal(user.id);
expect(user2.username).to.equal('user');
expect(user2.fullName).to.equal('John Smith');
// We can query and aggregate by non-quoted identifiers
self.User
return self.User
.count({
where: {fullName: 'John Smith'}
})
.success(function(count) {
.then(function(count) {
self.sequelize.options.quoteIndentifiers = true;
self.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = true;
self.sequelize.options.logging = false;
expect(count).to.equal(1);
done();
});
});
});
......
......@@ -23,9 +23,8 @@ if (dialect.match(/^postgres/)) {
expect(hstore.stringify({ foo: null })).to.equal('"foo"=>NULL');
});
it('should handle empty string correctly', function(done) {
it('should handle empty string correctly', function() {
expect(hstore.stringify({foo: ''})).to.equal('"foo"=>\"\"');
done();
});
it('should handle a string with backslashes correctly', function() {
......
......@@ -26,11 +26,10 @@ if (dialect.match(/^postgres/)) {
expect(range.stringify([1, 2, 3])).to.equal('');
});
it('should return empty string when non-array parameter is passed', function (done) {
it('should return empty string when non-array parameter is passed', function () {
expect(range.stringify({})).to.equal('');
expect(range.stringify('test')).to.equal('');
expect(range.stringify(undefined)).to.equal('');
done();
});
it('should handle array of objects with `inclusive` and `value` properties', function () {
......
......@@ -12,147 +12,131 @@ chai.config.includeStack = true;
if (dialect === 'sqlite') {
describe('[SQLITE Specific] DAOFactory', function() {
after(function(done) {
after(function() {
this.sequelize.options.storage = ':memory:';
done();
});
beforeEach(function(done) {
beforeEach(function() {
this.sequelize.options.storage = dbFile;
this.User = this.sequelize.define('User', {
age: DataTypes.INTEGER,
name: DataTypes.STRING,
bio: DataTypes.TEXT
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
storages.forEach(function(storage) {
describe('with storage "' + storage + '"', function() {
after(function(done) {
after(function() {
if (storage === dbFile) {
require('fs').writeFile(dbFile, '', function() {
done();
});
require('fs').writeFileSync(dbFile, '');
}
});
describe('create', function() {
it('creates a table entry', function(done) {
it('creates a table entry', function() {
var self = this;
this.User.create({ age: 21, name: 'John Wayne', bio: 'noot noot' }).success(function(user) {
return this.User.create({ age: 21, name: 'John Wayne', bio: 'noot noot' }).then(function(user) {
expect(user.age).to.equal(21);
expect(user.name).to.equal('John Wayne');
expect(user.bio).to.equal('noot noot');
self.User.all().success(function(users) {
return self.User.findAll().then(function(users) {
var usernames = users.map(function(user) {
return user.name;
});
expect(usernames).to.contain('John Wayne');
done();
});
});
});
it('should allow the creation of an object with options as attribute', function(done) {
it('should allow the creation of an object with options as attribute', function() {
var Person = this.sequelize.define('Person', {
name: DataTypes.STRING,
options: DataTypes.TEXT
});
Person.sync({ force: true }).success(function() {
return Person.sync({ force: true }).then(function() {
var options = JSON.stringify({ foo: 'bar', bar: 'foo' });
Person.create({
return Person.create({
name: 'John Doe',
options: options
}).success(function(people) {
}).then(function(people) {
expect(people.options).to.deep.equal(options);
done();
});
});
});
it('should allow the creation of an object with a boolean (true) as attribute', function(done) {
it('should allow the creation of an object with a boolean (true) as attribute', function() {
var Person = this.sequelize.define('Person', {
name: DataTypes.STRING,
has_swag: DataTypes.BOOLEAN
});
Person.sync({ force: true }).success(function() {
Person.create({
return Person.sync({ force: true }).then(function() {
return Person.create({
name: 'John Doe',
has_swag: true
}).success(function(people) {
}).then(function(people) {
expect(people.has_swag).to.be.ok;
done();
});
});
});
it('should allow the creation of an object with a boolean (false) as attribute', function(done) {
it('should allow the creation of an object with a boolean (false) as attribute', function() {
var Person = this.sequelize.define('Person', {
name: DataTypes.STRING,
has_swag: DataTypes.BOOLEAN
});
Person.sync({ force: true }).success(function() {
Person.create({
return Person.sync({ force: true }).then(function() {
return Person.create({
name: 'John Doe',
has_swag: false
}).success(function(people) {
}).then(function(people) {
expect(people.has_swag).to.not.be.ok;
done();
});
});
});
});
describe('.find', function() {
beforeEach(function(done) {
this.User.create({name: 'user', bio: 'footbar'}).success(function() {
done();
});
beforeEach(function() {
return this.User.create({name: 'user', bio: 'footbar'});
});
it('finds normal lookups', function(done) {
this.User.find({ where: { name: 'user' } }).success(function(user) {
it('finds normal lookups', function() {
return this.User.find({ where: { name: 'user' } }).then(function(user) {
expect(user.name).to.equal('user');
done();
});
});
it.skip('should make aliased attributes available', function(done) {
this.User.find({ where: { name: 'user' }, attributes: ['id', ['name', 'username']] }).success(function(user) {
it.skip('should make aliased attributes available', function() {
return this.User.find({ where: { name: 'user' }, attributes: ['id', ['name', 'username']] }).then(function(user) {
expect(user.username).to.equal('user');
done();
});
});
});
describe('.all', function() {
beforeEach(function(done) {
this.User.bulkCreate([
beforeEach(function() {
return this.User.bulkCreate([
{name: 'user', bio: 'foobar'},
{name: 'user', bio: 'foobar'}
]).success(function() {
done();
});
]);
});
it('should return all users', function(done) {
this.User.all().on('success', function(users) {
it('should return all users', function() {
return this.User.findAll().then(function(users) {
expect(users).to.have.length(2);
done();
});
});
});
describe('.min', function() {
it('should return the min value', function(done) {
it('should return the min value', function() {
var self = this
, users = [];
......@@ -160,17 +144,16 @@ if (dialect === 'sqlite') {
users[users.length] = {age: i};
}
this.User.bulkCreate(users).success(function() {
self.User.min('age').on('success', function(min) {
return this.User.bulkCreate(users).then(function() {
return self.User.min('age').then(function(min) {
expect(min).to.equal(2);
done();
});
});
});
});
describe('.max', function() {
it('should return the max value', function(done) {
it('should return the max value', function() {
var self = this
, users = [];
......@@ -178,10 +161,9 @@ if (dialect === 'sqlite') {
users[users.length] = {age: i};
}
this.User.bulkCreate(users).success(function() {
self.User.max('age').on('success', function(min) {
return this.User.bulkCreate(users).then(function() {
return self.User.max('age').then(function(min) {
expect(min).to.equal(5);
done();
});
});
});
......
......@@ -10,29 +10,26 @@ chai.config.includeStack = true;
if (dialect === 'sqlite') {
describe('[SQLITE Specific] DAO', function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.STRING
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
describe('findAll', function() {
it('handles dates correctly', function(done) {
it('handles dates correctly', function() {
var self = this
, user = this.User.build({ username: 'user' });
user.dataValues['createdAt'] = new Date(2011, 4, 4);
user.save().success(function() {
self.User.create({ username: 'new user' }).success(function() {
self.User.findAll({
return user.save().then(function() {
return self.User.create({ username: 'new user' }).then(function() {
return self.User.findAll({
where: ['createdAt > ?', new Date(2012, 1, 1)]
}).success(function(users) {
}).then(function(users) {
expect(users).to.have.length(1);
done();
});
});
});
......
This diff could not be displayed because it is too large.
......@@ -7,7 +7,6 @@ var chai = require('chai')
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + '/../../lib/data-types')
, datetime = require('chai-datetime')
, async = require('async')
, _ = require('lodash')
, dialect = Support.getTestDialect();
......
......@@ -6,8 +6,7 @@ var chai = require('chai')
, Sequelize = require(__dirname + '/../../../index')
, Promise = Sequelize.Promise
, DataTypes = require(__dirname + '/../../../lib/data-types')
, datetime = require('chai-datetime')
, async = require('async');
, datetime = require('chai-datetime');
chai.use(datetime);
chai.config.includeStack = true;
......@@ -215,7 +214,7 @@ describe(Support.getTestDialectTeaser('Include'), function() {
return model.create(values).then(function (instance) {
if (previousInstance) {
return previousInstance['set'+ Sequelize.Utils.uppercaseFirst(model.name)](instance).then(function() {
previousInstance = instance;
previousInstance = instance;
});
} else {
previousInstance = b = instance;
......@@ -275,7 +274,7 @@ describe(Support.getTestDialectTeaser('Include'), function() {
Post.belongsTo(User, { foreignKey: 'owner_id', as: 'Owner', constraints: false });
return this.sequelize.sync({force: true}).then(function () {
return User.find({
return User.find({
where: { id: 2 },
include: [
{ model: Post, as: 'UserPosts', where: {"private": true} }
......
......@@ -210,8 +210,8 @@ describe(Support.getTestDialectTeaser('Includes with schemas'), function() {
it('should support an include with multiple different association types', function(done) {
var self = this;
self.sequelize.dropAllSchemas().success(function() {
self.sequelize.createSchema('account').success(function() {
self.sequelize.dropAllSchemas().then(function() {
self.sequelize.createSchema('account').then(function() {
var AccUser = self.sequelize.define('AccUser', {}, {schema: 'account'})
, Product = self.sequelize.define('Product', {
title: DataTypes.STRING
......
......@@ -18,7 +18,7 @@ chai.use(datetime);
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Instance'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: { type: DataTypes.STRING },
uuidv1: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV1 },
......@@ -49,64 +49,55 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
defaultValue: false
}
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
describe('Escaping', function() {
it('is done properly for special characters', function(done) {
it('is done properly for special characters', function() {
// Ideally we should test more: "\0\n\r\b\t\\\'\"\x1a"
// 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
, self = this;
this.User.create({ username: bio }).success(function(u1) {
self.User.find(u1.id).success(function(u2) {
return this.User.create({ username: bio }).then(function(u1) {
return self.User.find(u1.id).then(function(u2) {
expect(u2.username).to.equal(bio);
done();
});
}).error(function(err) {
done(err);
});
});
});
describe('isNewRecord', function() {
it('returns true for non-saved objects', function(done) {
it('returns true for non-saved objects', function() {
var user = this.User.build({ username: 'user' });
expect(user.id).to.be.null;
expect(user.isNewRecord).to.be.ok;
done();
});
it('returns false for saved objects', function(done) {
this.User.build({ username: 'user' }).save().success(function(user) {
it('returns false for saved objects', function() {
return this.User.build({ username: 'user' }).save().then(function(user) {
expect(user.isNewRecord).to.not.be.ok;
done();
});
});
it('returns false for created objects', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns false for created objects', function() {
return this.User.create({ username: 'user' }).then(function(user) {
expect(user.isNewRecord).to.not.be.ok;
done();
});
});
it('returns false for objects found by find method', function(done) {
it('returns false for objects found by find method', function() {
var self = this;
this.User.create({ username: 'user' }).success(function() {
self.User.create({ username: 'user' }).success(function(user) {
self.User.find(user.id).success(function(user) {
return this.User.create({ username: 'user' }).then(function() {
return self.User.create({ username: 'user' }).then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.isNewRecord).to.not.be.ok;
done();
});
});
});
});
it('returns false for objects found by findAll method', function(done) {
it('returns false for objects found by findAll method', function() {
var self = this
, users = [];
......@@ -114,148 +105,131 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
users[users.length] = {username: 'user'};
}
this.User.bulkCreate(users).success(function() {
self.User.findAll().success(function(users) {
return this.User.bulkCreate(users).then(function() {
return self.User.findAll().then(function(users) {
users.forEach(function(u) {
expect(u.isNewRecord).to.not.be.ok;
});
done();
});
});
});
});
describe('isDirty', function() {
it('returns true for non-saved objects', function(done) {
it('returns true for non-saved objects', function() {
var user = this.User.build({ username: 'user' });
expect(user.id).to.be.null;
expect(user.isDirty).to.be.true;
done();
});
it('returns false for saved objects', function(done) {
this.User.build({ username: 'user' }).save().success(function(user) {
it('returns false for saved objects', function() {
return this.User.build({ username: 'user' }).save().then(function(user) {
expect(user.isDirty).to.be.false;
done();
});
});
it('returns true for changed attribute', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns true for changed attribute', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.username = 'new';
expect(user.isDirty).to.be.true;
done();
});
});
it('returns false for non-changed attribute', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns false for non-changed attribute', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.username = 'user';
expect(user.isDirty).to.be.false;
done();
});
});
it('returns false for non-changed date attribute', function(done) {
this.User.create({ aDate: new Date(2013, 6, 31, 14, 25, 21) }).success(function(user) {
it('returns false for non-changed date attribute', function() {
return this.User.create({ aDate: new Date(2013, 6, 31, 14, 25, 21) }).then(function(user) {
user.aDate = '2013-07-31 14:25:21';
expect(user.isDirty).to.be.false;
done();
});
});
// In my opinion this is bad logic, null is different from an empty string
it.skip('returns false for two empty attributes', function(done) {
this.User.create({ username: null }).success(function(user) {
it.skip('returns false for two empty attributes', function() {
return this.User.create({ username: null }).then(function(user) {
user.username = '';
expect(user.isDirty).to.be.false;
done();
});
});
it('returns true for bulk changed attribute', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns true for bulk changed attribute', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.setAttributes({
username: 'new',
aNumber: 1
});
expect(user.isDirty).to.be.true;
done();
});
});
it('returns true for bulk non-changed attribute + model with timestamps', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns false for bulk non-changed attribute + model with timestamps', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.setAttributes({
username: 'user'
});
expect(user.isDirty).to.be.rue;
done();
expect(user.isDirty).to.be.false;
});
});
it('returns false for bulk non-changed attribute + model without timestamps', function(done) {
it('returns false for bulk non-changed attribute + model without timestamps', function() {
var User = this.sequelize.define('User' + parseInt(Math.random() * 10000000), {
username: DataTypes.STRING
}, {
timestamps: false
});
User
return User
.sync({ force: true })
.then(function() {
return User.create({ username: 'user' });
})
.then(function(user) {
user.setAttributes({ username: 'user' });
expect(user.isDirty).to.be.false;
return user.setAttributes({ username: 'user' });
})
.then(function() {
done();
});
});
it('returns true for changed and bulk non-changed attribute', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns true for changed and bulk non-changed attribute', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.aNumber = 23;
user.setAttributes({
username: 'user'
});
expect(user.isDirty).to.be.true;
done();
});
});
it('returns true for changed attribute and false for saved object', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns true for changed attribute and false for saved object', function() {
return this.User.create({ username: 'user' }).then(function(user) {
user.username = 'new';
expect(user.isDirty).to.be.true;
user.save().success(function() {
return user.save().then(function() {
expect(user.isDirty).to.be.false;
done();
});
});
});
it('returns false for created objects', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('returns false for created objects', function() {
return this.User.create({ username: 'user' }).then(function(user) {
expect(user.isDirty).to.be.false;
done();
});
});
it('returns false for objects found by find method', function(done) {
it('returns false for objects found by find method', function() {
var self = this;
this.User.create({ username: 'user' }).success(function(user) {
self.User.find(user.id).success(function(user) {
return this.User.create({ username: 'user' }).then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.isDirty).to.be.false;
done();
});
});
});
it('returns false for objects found by findAll method', function(done) {
it('returns false for objects found by findAll method', function() {
var self = this
, users = [];
......@@ -263,38 +237,35 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
users[users.length] = {username: 'user'};
}
this.User.bulkCreate(users).success(function() {
self.User.findAll().success(function(users) {
return this.User.bulkCreate(users).then(function() {
return self.User.findAll().then(function(users) {
users.forEach(function(u) {
expect(u.isDirty).to.be.false;
});
done();
});
});
});
});
describe('increment', function() {
beforeEach(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).complete(function() {
done();
});
beforeEach(function() {
return this.User.create({ id: 1, aNumber: 0, bNumber: 0 });
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER });
User.sync({ force: true }).success(function() {
User.create({ number: 1 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.increment('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
return User.sync({ force: true }).then(function() {
return User.create({ number: 1 }).then(function(user) {
return sequelize.transaction().then(function(t) {
return user.increment('number', { by: 2, transaction: t }).then(function() {
return User.findAll().then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
expect(users1[0].number).to.equal(1);
expect(users2[0].number).to.equal(3);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -305,66 +276,61 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
}
it('supports where conditions', function(done) {
it('supports where conditions', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.increment(['aNumber'], { by: 2, where: { bNumber: 1 } }).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.increment(['aNumber'], { by: 2, where: { bNumber: 1 } }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(0);
done();
});
});
});
});
it('with array', function(done) {
it('with array', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.increment(['aNumber'], { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.increment(['aNumber'], { by: 2 }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(2);
done();
});
});
});
});
it('with single field', function(done) {
it('with single field', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.increment('aNumber', { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.increment('aNumber', { by: 2 }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(2);
done();
});
});
});
});
it('with single field and no value', function(done) {
it('with single field and no value', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.increment('aNumber').complete(function() {
self.User.find(1).complete(function(err, user2) {
return this.User.find(1).then(function(user1) {
return user1.increment('aNumber').then(function() {
return self.User.find(1).then(function(user2) {
expect(user2.aNumber).to.be.equal(1);
done();
});
});
});
});
it('should still work right with other concurrent updates', function(done) {
it('should still work right with other concurrent updates', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
return this.User.find(1).then(function(user1) {
// Select the user again (simulating a concurrent query)
self.User.find(1).complete(function(err, user2) {
user2.updateAttributes({
return self.User.find(1).then(function(user2) {
return user2.updateAttributes({
aNumber: user2.aNumber + 1
}).complete(function() {
user1.increment(['aNumber'], { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user5) {
}).then(function() {
return user1.increment(['aNumber'], { by: 2 }).then(function() {
return self.User.find(1).then(function(user5) {
expect(user5.aNumber).to.be.equal(3);
done();
});
});
});
......@@ -372,75 +338,72 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('should still work right with other concurrent increments', function(done) {
it('should still work right with other concurrent increments', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
var _done = _.after(3, function() {
self.User.find(1).complete(function(err, user2) {
return this.User.find(1).then(function(user1) {
return user1.increment(['aNumber'], { by: 2 }).then(function() {
return user1.increment(['aNumber'], { by: 2 });
}).then(function() {
return user1.increment(['aNumber'], { by: 2 });
}).then(function() {
return self.User.find(1).then(function(user2) {
expect(user2.aNumber).to.equal(6);
done();
});
});
user1.increment(['aNumber'], { by: 2 }).complete(_done);
user1.increment(['aNumber'], { by: 2 }).complete(_done);
user1.increment(['aNumber'], { by: 2 }).complete(_done);
});
});
it('with key value pair', function(done) {
it('with key value pair', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.increment({ 'aNumber': 1, 'bNumber': 2 }).success(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.increment({ 'aNumber': 1, 'bNumber': 2 }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(1);
expect(user3.bNumber).to.be.equal(2);
done();
});
});
});
});
it('with timestamps set to true', function(done) {
it('with timestamps set to true', function() {
var User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER
}, { timestamps: true });
User.sync({ force: true }).success(function() {
User.create({aNumber: 1}).success(function(user) {
return User.sync({ force: true }).then(function() {
return User.create({aNumber: 1}).then(function(user) {
var oldDate = user.updatedAt;
setTimeout(function() {
user.increment('aNumber', { by: 1 }).success(function() {
User.find(1).success(function(user) {
return this.sequelize.Promise.delay(1000).then(function() {
return user.increment('aNumber', { by: 1 }).then(function() {
return User.find(1).then(function(user) {
expect(user.updatedAt).to.be.afterTime(oldDate);
done();
});
});
}, 1000);
});
});
});
});
});
describe('decrement', function() {
beforeEach(function(done) {
this.User.create({ id: 1, aNumber: 0, bNumber: 0 }).complete(done);
beforeEach(function() {
return this.User.create({ id: 1, aNumber: 0, bNumber: 0 });
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { number: Support.Sequelize.INTEGER });
User.sync({ force: true }).success(function() {
User.create({ number: 3 }).success(function(user) {
sequelize.transaction().then(function(t) {
user.decrement('number', { by: 2, transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
return User.sync({ force: true }).then(function() {
return User.create({ number: 3 }).then(function(user) {
return sequelize.transaction().then(function(t) {
return user.decrement('number', { by: 2, transaction: t }).then(function() {
return User.findAll().then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
expect(users1[0].number).to.equal(3);
expect(users2[0].number).to.equal(1);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -451,54 +414,50 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
}
it('with array', function(done) {
it('with array', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.decrement(['aNumber'], { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.decrement(['aNumber'], { by: 2 }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(-2);
done();
});
});
});
});
it('with single field', function(done) {
it('with single field', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.decrement('aNumber', { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.decrement('aNumber', { by: 2 }).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(-2);
done();
});
});
});
});
it('with single field and no value', function(done) {
it('with single field and no value', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.decrement('aNumber').complete(function() {
self.User.find(1).complete(function(err, user2) {
return this.User.find(1).then(function(user1) {
return user1.decrement('aNumber').then(function() {
return self.User.find(1).then(function(user2) {
expect(user2.aNumber).to.be.equal(-1);
done();
});
});
});
});
it('should still work right with other concurrent updates', function(done) {
it('should still work right with other concurrent updates', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
return this.User.find(1).then(function(user1) {
// Select the user again (simulating a concurrent query)
self.User.find(1).complete(function(err, user2) {
user2.updateAttributes({
return self.User.find(1).then(function(user2) {
return user2.updateAttributes({
aNumber: user2.aNumber + 1
}).complete(function() {
user1.decrement(['aNumber'], { by: 2 }).complete(function() {
self.User.find(1).complete(function(err, user5) {
}).then(function() {
return user1.decrement(['aNumber'], { by: 2 }).then(function() {
return self.User.find(1).then(function(user5) {
expect(user5.aNumber).to.be.equal(-1);
done();
});
});
});
......@@ -506,51 +465,48 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('should still work right with other concurrent increments', function(done) {
it('should still work right with other concurrent increments', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
var _done = _.after(3, function() {
self.User.find(1).complete(function(err, user2) {
return this.User.find(1).then(function(user1) {
return user1.decrement(['aNumber'], { by: 2 }).then(function() {
return user1.decrement(['aNumber'], { by: 2 });
}).then(function() {
return user1.decrement(['aNumber'], { by: 2 });
}).then(function() {
return self.User.find(1).then(function(user2) {
expect(user2.aNumber).to.equal(-6);
done();
});
});
user1.decrement(['aNumber'], { by: 2 }).complete(_done);
user1.decrement(['aNumber'], { by: 2 }).complete(_done);
user1.decrement(['aNumber'], { by: 2 }).complete(_done);
});
});
it('with key value pair', function(done) {
it('with key value pair', function() {
var self = this;
this.User.find(1).complete(function(err, user1) {
user1.decrement({ 'aNumber': 1, 'bNumber': 2}).complete(function() {
self.User.find(1).complete(function(err, user3) {
return this.User.find(1).then(function(user1) {
return user1.decrement({ 'aNumber': 1, 'bNumber': 2}).then(function() {
return self.User.find(1).then(function(user3) {
expect(user3.aNumber).to.be.equal(-1);
expect(user3.bNumber).to.be.equal(-2);
done();
});
});
});
});
it('with timestamps set to true', function(done) {
it('with timestamps set to true', function() {
var User = this.sequelize.define('IncrementUser', {
aNumber: DataTypes.INTEGER
}, { timestamps: true });
User.sync({ force: true }).success(function() {
User.create({aNumber: 1}).success(function(user) {
return User.sync({ force: true }).then(function() {
return User.create({aNumber: 1}).then(function(user) {
var oldDate = user.updatedAt;
setTimeout(function() {
user.decrement('aNumber', { by: 1 }).success(function() {
User.find(1).success(function(user) {
return this.sequelize.Promise.delay(1000).then(function() {
return user.decrement('aNumber', { by: 1 }).then(function() {
return User.find(1).then(function(user) {
expect(user.updatedAt).to.be.afterTime(oldDate);
done();
});
});
}, 1000);
});
});
});
});
......@@ -558,19 +514,19 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
describe('reload', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING });
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).success(function() {
user.reload().success(function(user) {
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function(user) {
return sequelize.transaction().then(function(t) {
return User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).then(function() {
return user.reload().then(function(user) {
expect(user.username).to.equal('foo');
user.reload({ transaction: t }).success(function(user) {
return user.reload({ transaction: t }).then(function(user) {
expect(user.username).to.equal('bar');
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -581,82 +537,76 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
}
it('should return a reference to the same DAO instead of creating a new one', function(done) {
this.User.create({ username: 'John Doe' }).complete(function(err, originalUser) {
originalUser.updateAttributes({ username: 'Doe John' }).complete(function() {
originalUser.reload().complete(function(err, updatedUser) {
it('should return a reference to the same DAO instead of creating a new one', function() {
return this.User.create({ username: 'John Doe' }).then(function(originalUser) {
return originalUser.updateAttributes({ username: 'Doe John' }).then(function() {
return originalUser.reload().then(function(updatedUser) {
expect(originalUser === updatedUser).to.be.true;
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() {
var self = this;
this.User.create({ username: 'John Doe' }).complete(function(err, originalUser) {
self.User.find(originalUser.id).complete(function(err, updater) {
updater.updateAttributes({ username: 'Doe John' }).complete(function() {
return this.User.create({ username: 'John Doe' }).then(function(originalUser) {
return self.User.find(originalUser.id).then(function(updater) {
return updater.updateAttributes({ username: 'Doe John' }).then(function() {
// We used a different reference when calling updateAttributes, so originalUser is now out of sync
expect(originalUser.username).to.equal('John Doe');
originalUser.reload().complete(function(err, updatedUser) {
return originalUser.reload().then(function(updatedUser) {
expect(originalUser.username).to.equal('Doe John');
expect(updatedUser.username).to.equal('Doe John');
done();
});
});
});
});
});
it('should update read only attributes as well (updatedAt)', function(done) {
it('should update read only attributes as well (updatedAt)', function() {
var self = this;
this.User.create({ username: 'John Doe' }).complete(function(err, originalUser) {
return this.User.create({ username: 'John Doe' }).then(function(originalUser) {
var originallyUpdatedAt = originalUser.updatedAt;
// Wait for a second, so updatedAt will actually be different
setTimeout(function() {
self.User.find(originalUser.id).complete(function(err, updater) {
updater.updateAttributes({ username: 'Doe John' }).complete(function() {
originalUser.reload().complete(function(err, updatedUser) {
return this.sequelize.Promise.delay(1000).then(function() {
return self.User.find(originalUser.id).then(function(updater) {
return updater.updateAttributes({ username: 'Doe John' }).then(function() {
return originalUser.reload().then(function(updatedUser) {
expect(originalUser.updatedAt).to.be.above(originallyUpdatedAt);
expect(updatedUser.updatedAt).to.be.above(originallyUpdatedAt);
done();
});
});
});
}, 1000);
});
});
});
it('should update the associations as well', function(done) {
it('should update the associations as well', function() {
var Book = this.sequelize.define('Book', { title: DataTypes.STRING })
, Page = this.sequelize.define('Page', { content: DataTypes.TEXT });
Book.hasMany(Page);
Page.belongsTo(Book);
Book.sync({force: true}).success(function() {
Page.sync({force: true}).success(function() {
Book.create({ title: 'A very old book' }).success(function(book) {
Page.create({ content: 'om nom nom' }).success(function(page) {
book.setPages([page]).success(function() {
Book.find({
return Book.sync({force: true}).then(function() {
return Page.sync({force: true}).then(function() {
return Book.create({ title: 'A very old book' }).then(function(book) {
return Page.create({ content: 'om nom nom' }).then(function(page) {
return book.setPages([page]).then(function() {
return Book.find({
where: { id: book.id },
include: [Page]
}).success(function(leBook) {
page.updateAttributes({ content: 'something totally different' }).success(function(page) {
}).then(function(leBook) {
return page.updateAttributes({ content: 'something totally different' }).then(function(page) {
expect(leBook.Pages.length).to.equal(1);
expect(leBook.Pages[0].content).to.equal('om nom nom');
expect(page.content).to.equal('something totally different');
leBook.reload().success(function(leBook) {
return leBook.reload().then(function(leBook) {
expect(leBook.Pages.length).to.equal(1);
expect(leBook.Pages[0].content).to.equal('something totally different');
expect(page.content).to.equal('something totally different');
done();
});
});
});
......@@ -670,25 +620,22 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
describe('default values', function() {
describe('uuid', function() {
it('should store a string in uuidv1 and uuidv4', function(done) {
it('should store a string in uuidv1 and uuidv4', function() {
var user = this.User.build({ username: 'a user'});
expect(user.uuidv1).to.be.a('string');
expect(user.uuidv4).to.be.a('string');
done();
});
it('should store a string of length 36 in uuidv1 and uuidv4', function(done) {
it('should store a string of length 36 in uuidv1 and uuidv4', function() {
var user = this.User.build({ username: 'a user'});
expect(user.uuidv1).to.have.length(36);
expect(user.uuidv4).to.have.length(36);
done();
});
it('should store a valid uuid in uuidv1 and uuidv4 that can be parsed to something of length 16', function(done) {
it('should store a valid uuid in uuidv1 and uuidv4 that can be parsed to something of length 16', function() {
var user = this.User.build({ username: 'a user'});
expect(uuid.parse(user.uuidv1)).to.have.length(16);
expect(uuid.parse(user.uuidv4)).to.have.length(16);
done();
});
it('should store a valid uuid if the field is a primary key named id', function() {
......@@ -706,40 +653,36 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
describe('current date', function() {
it('should store a date in touchedAt', function(done) {
it('should store a date in touchedAt', function() {
var user = this.User.build({ username: 'a user'});
expect(user.touchedAt).to.be.instanceof(Date);
done();
});
it('should store the current date in touchedAt', function(done) {
it('should store the current date in touchedAt', function() {
var clock = sinon.useFakeTimers();
clock.tick(5000);
var user = this.User.build({ username: 'a user'});
clock.restore();
expect(+user.touchedAt).to.be.equal(5000);
done();
});
});
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() {
var self = this;
this.User.build({ username: 'a user'}).save().success(function() {
self.User.find({where: {username: 'a user'}}).success(function(user) {
return this.User.build({ username: 'a user'}).save().then(function() {
return self.User.find({where: {username: 'a user'}}).then(function(user) {
expect(user.dateAllowNullTrue).to.be.null;
done();
});
});
});
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() {
var self = this;
var date = new Date();
this.User.build({ username: 'a user', dateAllowNullTrue: date}).save().success(function() {
self.User.find({where: {username: 'a user'}}).success(function(user) {
return this.User.build({ username: 'a user', dateAllowNullTrue: date}).save().then(function() {
return self.User.find({where: {username: 'a user'}}).then(function(user) {
expect(user.dateAllowNullTrue.toString()).to.equal(date.toString());
done();
});
});
});
......@@ -842,37 +785,33 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
describe('complete', function() {
it('gets triggered if an error occurs', function(done) {
this.User.find({ where: 'asdasdasd' }).complete(function(err) {
it('gets triggered if an error occurs', function() {
return this.User.find({ where: 'asdasdasd' }).catch(function(err) {
expect(err).to.exist;
expect(err.message).to.exist;
done();
});
});
it('gets triggered if everything was ok', function(done) {
this.User.count().complete(function(err, result) {
expect(err).to.be.null;
it('gets triggered if everything was ok', function() {
return this.User.count().then(function(result) {
expect(result).to.exist;
done();
});
});
});
describe('save', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.build({ username: 'foo' }).save({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.build({ username: 'foo' }).save({ transaction: t }).then(function() {
return User.count().then(function(count1) {
return User.count({ transaction: t }).then(function(count2) {
expect(count1).to.equal(0);
expect(count2).to.equal(1);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -882,25 +821,24 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
}
it('only updates fields in passed array', function(done) {
it('only updates fields in passed array', function() {
var self = this
, userId = null
, date = new Date(1990, 1, 1);
this.User.create({
return this.User.create({
username: 'foo',
touchedAt: new Date()
}).success(function(user) {
}).then(function(user) {
user.username = 'fizz';
user.touchedAt = date;
user.save(['username']).success(function() {
return user.save(['username']).then(function() {
// re-select user
self.User.find(user.id).success(function(user2) {
return self.User.find(user.id).then(function(user2) {
// name should have changed
expect(user2.username).to.equal('fizz');
// bio should be unchanged
expect(user2.birthDate).not.to.equal(date);
done();
});
});
});
......@@ -934,13 +872,11 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('only validates fields in passed array', function(done) {
this.User.build({
it('only validates fields in passed array', function() {
return this.User.build({
validateTest: 'cake', // invalid, but not saved
validateCustom: '1'
}).save(['validateCustom']).success(function() {
done();
});
}).save(['validateCustom']);
});
describe('hooks', function () {
......@@ -1075,7 +1011,7 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('stores an entry in the database', function(done) {
it('stores an entry in the database', function() {
var username = 'user'
, User = this.User
, user = this.User.build({
......@@ -1083,97 +1019,77 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
touchedAt: new Date(1984, 8, 23)
});
User.all().success(function(users) {
return User.findAll().then(function(users) {
expect(users).to.have.length(0);
user.save().success(function() {
User.all().success(function(users) {
return user.save().then(function() {
return User.findAll().then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal(username);
expect(users[0].touchedAt).to.be.instanceof(Date);
expect(users[0].touchedAt).to.equalDate(new Date(1984, 8, 23));
done();
});
});
});
});
it('updates the timestamps', function(done) {
it('updates the timestamps', function() {
var now = Date.now()
, user = null
, updatedAt = null
, User = this.User;
// timeout is needed, in order to check the update of the timestamp
var build = function(callback) {
return this.sequelize.Promise.delay(1000).then(function() {
user = User.build({ username: 'user' });
var save = user.save();
save.success(function() {
return user.save().then(function() {
expect(now).to.be.below(user.updatedAt.getTime());
callback();
});
};
// closures are fun :)
setTimeout(function() {
build(function() {
done();
});
}, 1000);
});
});
it('does not update timestamps when passing silent=true', function() {
var self = this;
return this.User.create({ username: 'user' }).then(function(user) {
var updatedAt = user.updatedAt;
return new self.sequelize.Promise(function(resolve) {
setTimeout(function() {
user.updateAttributes({
username: 'userman'
}, {
// silent: true
}).then(function() {
expect(user.updatedAt).to.equalDate(updatedAt);
resolve();
});
}, 2000);
return this.sequelize.Promise.delay(2000).then(function() {
return user.update({
username: 'userman'
}, {
silent: true
}).then(function(user1) {
expect(user1.updatedAt).to.equalDate(updatedAt);
});
});
});
});
it('updates with function and column value', function(done) {
it('updates with function and column value', function() {
var self = this;
this.User.create({
return this.User.create({
aNumber: 42
}).success(function(user) {
}).then(function(user) {
user.bNumber = self.sequelize.col('aNumber');
user.username = self.sequelize.fn('upper', 'sequelize');
user.save().success(function() {
self.User.find(user.id).success(function(user2) {
return user.save().then(function() {
return self.User.find(user.id).then(function(user2) {
expect(user2.username).to.equal('SEQUELIZE');
expect(user2.bNumber).to.equal(42);
done();
});
});
});
});
describe('without timestamps option', function() {
it("doesn't update the updatedAt column", function(done) {
it("doesn't update the updatedAt column", function() {
var User2 = this.sequelize.define('User2', {
username: DataTypes.STRING,
updatedAt: DataTypes.DATE
}, { timestamps: false });
User2.sync().success(function() {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
return User2.sync().then(function() {
return User2.create({ username: 'john doe' }).then(function(johnDoe) {
// sqlite and mysql return undefined, whereas postgres returns null
expect([undefined, null].indexOf(johnDoe.updatedAt)).not.to.be.equal(-1);
done();
});
});
});
......@@ -1182,109 +1098,101 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
describe('with custom timestamp options', function() {
var now = Date.now();
it('updates the createdAt column if updatedAt is disabled', function(done) {
it('updates the createdAt column if updatedAt is disabled', function() {
var User2 = this.sequelize.define('User2', {
username: DataTypes.STRING
}, { updatedAt: false });
User2.sync().success(function() {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
return User2.sync().then(function() {
return User2.create({ username: 'john doe' }).then(function(johnDoe) {
expect(johnDoe.updatedAt).to.be.undefined;
expect(now).to.be.below(johnDoe.createdAt.getTime());
done();
});
});
});
it('updates the updatedAt column if createdAt is disabled', function(done) {
it('updates the updatedAt column if createdAt is disabled', function() {
var User2 = this.sequelize.define('User2', {
username: DataTypes.STRING
}, { createdAt: false });
User2.sync().success(function() {
User2.create({ username: 'john doe' }).success(function(johnDoe) {
return User2.sync().then(function() {
return User2.create({ username: 'john doe' }).then(function(johnDoe) {
expect(johnDoe.createdAt).to.be.undefined;
expect(now).to.be.below(johnDoe.updatedAt.getTime());
done();
});
});
});
});
it('should fail a validation upon creating', function(done) {
this.User.create({aNumber: 0, validateTest: 'hello'}).error(function(err) {
it('should fail a validation upon creating', function() {
return this.User.create({aNumber: 0, validateTest: 'hello'}).catch(function(err) {
expect(err).to.exist;
expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')).to.be.instanceof(Array);
expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt failed');
done();
});
});
it('should fail a validation upon creating with hooks false', function(done) {
this.User.create({aNumber: 0, validateTest: 'hello'}, {hooks: false}).error(function(err) {
it('should fail a validation upon creating with hooks false', function() {
return this.User.create({aNumber: 0, validateTest: 'hello'}, {hooks: false}).catch(function(err) {
expect(err).to.exist;
expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')).to.be.instanceof(Array);
expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt failed');
done();
});
});
it('should fail a validation upon building', function(done) {
this.User.build({aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa'}).save()
.error(function(err) {
it('should fail a validation upon building', function() {
return this.User.build({aNumber: 0, validateCustom: 'aaaaaaaaaaaaaaaaaaaaaaaaaa'}).save()
.catch(function(err) {
expect(err).to.exist;
expect(err).to.be.instanceof(Object);
expect(err.get('validateCustom')).to.exist;
expect(err.get('validateCustom')).to.be.instanceof(Array);
expect(err.get('validateCustom')[0]).to.exist;
expect(err.get('validateCustom')[0].message).to.equal('Length failed.');
done();
});
});
it('should fail a validation when updating', function(done) {
this.User.create({aNumber: 0}).success(function(user) {
user.updateAttributes({validateTest: 'hello'}).error(function(err) {
it('should fail a validation when updating', function() {
return this.User.create({aNumber: 0}).then(function(user) {
return user.updateAttributes({validateTest: 'hello'}).catch(function(err) {
expect(err).to.exist;
expect(err).to.be.instanceof(Object);
expect(err.get('validateTest')).to.exist;
expect(err.get('validateTest')).to.be.instanceof(Array);
expect(err.get('validateTest')[0]).to.exist;
expect(err.get('validateTest')[0].message).to.equal('Validation isInt failed');
done();
});
});
});
it('takes zero into account', function(done) {
this.User.build({ aNumber: 0 }).save(['aNumber']).success(function(user) {
it('takes zero into account', function() {
return this.User.build({ aNumber: 0 }).save(['aNumber']).then(function(user) {
expect(user.aNumber).to.equal(0);
done();
});
});
it('saves a record with no primary key', function(done) {
it('saves a record with no primary key', function() {
var HistoryLog = this.sequelize.define('HistoryLog', {
someText: { type: DataTypes.STRING },
aNumber: { type: DataTypes.INTEGER },
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) {
return HistoryLog.sync().then(function() {
return HistoryLog.create({ someText: 'Some random text', aNumber: 3, aRandomId: 5 }).then(function(log) {
return log.updateAttributes({ aNumber: 5 }).then(function(newLog) {
expect(newLog.aNumber).to.equal(5);
done();
});
});
});
});
describe('eagerly loaded objects', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.UserEager = this.sequelize.define('UserEagerLoadingSaves', {
username: DataTypes.STRING,
......@@ -1299,33 +1207,29 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
this.UserEager.hasMany(this.ProjectEager, { as: 'Projects', foreignKey: 'PoobahId' });
this.ProjectEager.belongsTo(this.UserEager, { as: 'Poobah', foreignKey: 'PoobahId' });
self.UserEager.sync({force: true}).success(function() {
self.ProjectEager.sync({force: true}).success(function() {
done();
});
return self.UserEager.sync({force: true}).then(function() {
return self.ProjectEager.sync({force: true});
});
});
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() {
var self = this;
this.UserEager.create({ username: 'joe', age: 1 }).success(function(user) {
self.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 }).success(function(project1) {
self.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 }).success(function(project2) {
user.setProjects([project1, project2]).success(function() {
self.UserEager.find({where: {age: 1}, include: [{model: self.ProjectEager, as: 'Projects'}]}).success(function(user) {
return this.UserEager.create({ username: 'joe', age: 1 }).then(function(user) {
return self.ProjectEager.create({ title: 'project-joe1', overdue_days: 0 }).then(function(project1) {
return self.ProjectEager.create({ title: 'project-joe2', overdue_days: 0 }).then(function(project2) {
return user.setProjects([project1, project2]).then(function() {
return self.UserEager.find({where: {age: 1}, include: [{model: self.ProjectEager, as: 'Projects'}]}).then(function(user) {
expect(user.username).to.equal('joe');
expect(user.age).to.equal(1);
expect(user.Projects).to.exist;
expect(user.Projects.length).to.equal(2);
user.age = user.age + 1; // happy birthday joe
user.save().done(function(err) {
return user.save().then(function(user) {
expect(user.username).to.equal('joe');
expect(user.age).to.equal(2);
expect(user.Projects).to.exist;
expect(user.Projects.length).to.equal(2);
done();
});
});
});
......@@ -1334,17 +1238,17 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
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() {
var self = this;
this.UserEager.create({ username: 'bart', age: 20 }).success(function(bart) {
self.UserEager.create({ username: 'lisa', age: 20 }).success(function(lisa) {
self.ProjectEager.create({ title: 'detention1', overdue_days: 0 }).success(function(detention1) {
self.ProjectEager.create({ title: 'detention2', overdue_days: 0 }).success(function(detention2) {
self.ProjectEager.create({ title: 'exam1', overdue_days: 0 }).success(function(exam1) {
self.ProjectEager.create({ title: 'exam2', overdue_days: 0 }).success(function(exam2) {
bart.setProjects([detention1, detention2]).success(function() {
lisa.setProjects([exam1, exam2]).success(function() {
self.UserEager.findAll({where: {age: 20}, order: 'username ASC', include: [{model: self.ProjectEager, as: 'Projects'}]}).success(function(simpsons) {
return this.UserEager.create({ username: 'bart', age: 20 }).then(function(bart) {
return self.UserEager.create({ username: 'lisa', age: 20 }).then(function(lisa) {
return self.ProjectEager.create({ title: 'detention1', overdue_days: 0 }).then(function(detention1) {
return self.ProjectEager.create({ title: 'detention2', overdue_days: 0 }).then(function(detention2) {
return self.ProjectEager.create({ title: 'exam1', overdue_days: 0 }).then(function(exam1) {
return self.ProjectEager.create({ title: 'exam2', overdue_days: 0 }).then(function(exam2) {
return bart.setProjects([detention1, detention2]).then(function() {
return lisa.setProjects([exam1, exam2]).then(function() {
return self.UserEager.findAll({where: {age: 20}, order: 'username ASC', include: [{model: self.ProjectEager, as: 'Projects'}]}).then(function(simpsons) {
var _bart, _lisa;
expect(simpsons.length).to.equal(2);
......@@ -1359,17 +1263,15 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
_bart.age = _bart.age + 1; // happy birthday bart - off to Moe's
_bart.save().success(function(savedbart) {
return _bart.save().then(function(savedbart) {
expect(savedbart.username).to.equal('bart');
expect(savedbart.age).to.equal(21);
_lisa.username = 'lsimpson';
_lisa.save().success(function(savedlisa) {
return _lisa.save().then(function(savedlisa) {
expect(savedlisa.username).to.equal('lsimpson');
expect(savedlisa.age).to.equal(20);
done();
});
});
});
......@@ -1383,13 +1285,13 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
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() {
var self = this;
this.UserEager.create({ username: 'poobah', age: 18 }).success(function(user) {
self.ProjectEager.create({ title: 'homework', overdue_days: 10 }).success(function(homework) {
self.ProjectEager.create({ title: 'party', overdue_days: 2 }).success(function(party) {
user.setProjects([homework, party]).success(function() {
self.ProjectEager.findAll({include: [{model: self.UserEager, as: 'Poobah'}]}).success(function(projects) {
return this.UserEager.create({ username: 'poobah', age: 18 }).then(function(user) {
return self.ProjectEager.create({ title: 'homework', overdue_days: 10 }).then(function(homework) {
return self.ProjectEager.create({ title: 'party', overdue_days: 2 }).then(function(party) {
return user.setProjects([homework, party]).then(function() {
return self.ProjectEager.findAll({include: [{model: self.UserEager, as: 'Poobah'}]}).then(function(projects) {
expect(projects.length).to.equal(2);
expect(projects[0].Poobah).to.exist;
expect(projects[1].Poobah).to.exist;
......@@ -1401,17 +1303,14 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
projects[0].overdue_days = 0;
projects[1].overdue_days = 0;
projects[0].save().success(function() {
projects[1].save().success(function() {
self.ProjectEager.findAll({where: {title: 'partymore', overdue_days: 0}, include: [{model: self.UserEager, as: 'Poobah'}]}).success(function(savedprojects) {
return projects[0].save().then(function() {
return projects[1].save().then(function() {
return self.ProjectEager.findAll({where: {title: 'partymore', overdue_days: 0}, include: [{model: self.UserEager, as: 'Poobah'}]}).then(function(savedprojects) {
expect(savedprojects.length).to.equal(2);
expect(savedprojects[0].Poobah).to.exist;
expect(savedprojects[1].Poobah).to.exist;
expect(savedprojects[0].Poobah.username).to.equal('poobah');
expect(savedprojects[1].Poobah.username).to.equal('poobah');
done();
});
});
});
......@@ -1426,7 +1325,7 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
describe('many to many relations', function() {
var udo;
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User = this.sequelize.define('UserWithUsernameAndAgeAndIsAdmin', {
username: DataTypes.STRING,
......@@ -1440,32 +1339,30 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
this.Project.hasMany(this.User);
this.User.hasMany(this.Project);
this.User.sync({ force: true }).success(function() {
self.Project.sync({ force: true }).success(function() {
self.User.create({ username: 'fnord', age: 1, isAdmin: true })
.success(function(user) {
return this.User.sync({ force: true }).then(function() {
return self.Project.sync({ force: true }).then(function() {
return self.User.create({ username: 'fnord', age: 1, isAdmin: true })
.then(function(user) {
udo = user;
done();
});
});
});
});
it.skip('Should assign a property to the instance', function(done) {
it.skip('Should assign a property to the instance', function() {
// @thanpolas rethink this test, it doesn't make sense, a relation has
// to be created first in the beforeEach().
var self = this;
this.User.find({id: udo.id})
.success(function(user) {
return this.User.find({id: udo.id})
.then(function(user) {
user.NiceProjectId = 1;
expect(user.NiceProjectId).to.equal(1);
done();
});
});
});
describe('toJSON', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User = this.sequelize.define('UserWithUsernameAndAgeAndIsAdmin', {
username: DataTypes.STRING,
......@@ -1478,18 +1375,15 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
this.User.hasMany(this.Project, { as: 'Projects', foreignKey: 'lovelyUserId' });
this.Project.belongsTo(this.User, { as: 'LovelyUser', foreignKey: 'lovelyUserId' });
this.User.sync({ force: true }).success(function() {
self.Project.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true }).then(function() {
return self.Project.sync({ force: true });
});
});
it("dont return instance that isn't defined", function(done ) {
it("dont return instance that isn't defined", function() {
var self = this;
self.Project.create({ lovelyUserId: null })
.then(function(project ) {
return self.Project.create({ lovelyUserId: null })
.then(function(project) {
return self.Project.find({
where: {
id: project.id
......@@ -1499,21 +1393,16 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
]
});
})
.then(function(project ) {
.then(function(project) {
var json = project.toJSON();
expect(json.LovelyUser).to.be.equal(null);
})
.done(done)
.catch (done);
});
});
it("dont return instances that aren't defined", function(done ) {
it("dont return instances that aren't defined", function() {
var self = this;
self.User.create({ username: 'cuss' })
.then(function(user ) {
return self.User.create({ username: 'cuss' })
.then(function(user) {
return self.User.find({
where: {
id: user.id
......@@ -1523,53 +1412,44 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
]
});
})
.then(function(user ) {
.then(function(user) {
var json = user.toJSON();
expect(user.Projects).to.be.instanceof(Array);
expect(user.Projects).to.be.length(0);
})
.done(done)
.catch (done);
});
});
it('returns an object containing all values', function(done) {
it('returns an object containing all values', function() {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true });
expect(user.toJSON()).to.deep.equal({ username: 'test.user', age: 99, isAdmin: true, id: null });
done();
});
it('returns a response that can be stringified', function(done) {
it('returns a response that can be stringified', function() {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true });
expect(JSON.stringify(user)).to.deep.equal('{"id":null,"username":"test.user","age":99,"isAdmin":true}');
done();
});
it('returns a response that can be stringified and then parsed', function(done) {
it('returns a response that can be stringified and then parsed', function() {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true });
expect(JSON.parse(JSON.stringify(user))).to.deep.equal({ 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() {
var self = this;
this.User.create({ username: 'fnord', age: 1, isAdmin: true }).success(function(user) {
self.Project.create({ title: 'fnord' }).success(function(project) {
user.setProjects([project]).success(function() {
self.User.findAll({include: [{ model: self.Project, as: 'Projects' }]}).success(function(users) {
return this.User.create({ username: 'fnord', age: 1, isAdmin: true }).then(function(user) {
return self.Project.create({ title: 'fnord' }).then(function(project) {
return user.setProjects([project]).then(function() {
return self.User.findAll({include: [{ model: self.Project, as: 'Projects' }]}).then(function(users) {
var _user = users[0];
expect(_user.Projects).to.exist;
expect(JSON.parse(JSON.stringify(_user)).Projects).to.exist;
self.Project.findAll({include: [{ model: self.User, as: 'LovelyUser' }]}).success(function(projects) {
return self.Project.findAll({include: [{ model: self.User, as: 'LovelyUser' }]}).then(function(projects) {
var _project = projects[0];
expect(_project.LovelyUser).to.exist;
expect(JSON.parse(JSON.stringify(_project)).LovelyUser).to.exist;
done();
});
});
});
......@@ -1579,43 +1459,36 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
describe('findAll', function() {
beforeEach(function(done) {
beforeEach(function() {
this.ParanoidUser = this.sequelize.define('ParanoidUser', {
username: { type: DataTypes.STRING }
}, { paranoid: true });
this.ParanoidUser.hasOne(this.ParanoidUser);
this.ParanoidUser.sync({ force: true }).success(function() {
done();
});
return this.ParanoidUser.sync({ force: true });
});
it('sql should have paranoid condition', function(done ) {
it('sql should have paranoid condition', function() {
var self = this;
self.ParanoidUser.create({ username: 'cuss' })
return self.ParanoidUser.create({ username: 'cuss' })
.then(function() {
return self.ParanoidUser.findAll();
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(1);
return users[0].destroy();
})
.then(function() {
return self.ParanoidUser.findAll();
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(0);
})
.done(done)
.catch (done);
});
});
it('sequelize.and as where should include paranoid condition', function(done ) {
it('sequelize.and as where should include paranoid condition', function() {
var self = this;
self.ParanoidUser.create({ username: 'cuss' })
return self.ParanoidUser.create({ username: 'cuss' })
.then(function() {
return self.ParanoidUser.findAll({
where: self.sequelize.and({
......@@ -1623,9 +1496,8 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
})
});
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(1);
return users[0].destroy();
})
.then(function() {
......@@ -1635,18 +1507,14 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
})
});
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(0);
})
.done(done)
.catch (done);
});
});
it('sequelize.or as where should include paranoid condition', function(done ) {
it('sequelize.or as where should include paranoid condition', function() {
var self = this;
self.ParanoidUser.create({ username: 'cuss' })
return self.ParanoidUser.create({ username: 'cuss' })
.then(function() {
return self.ParanoidUser.findAll({
where: self.sequelize.or({
......@@ -1654,9 +1522,8 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
})
});
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(1);
return users[0].destroy();
})
.then(function() {
......@@ -1666,78 +1533,68 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
})
});
})
.then(function(users ) {
.then(function(users) {
expect(users).to.have.length(0);
})
.done(done)
.catch (done);
});
});
it('escapes a single single quotes properly in where clauses', function(done) {
it('escapes a single single quotes properly in where clauses', function() {
var self = this;
this.User
return this.User
.create({ username: "user'name" })
.success(function() {
self.User.findAll({
.then(function() {
return self.User.findAll({
where: { username: "user'name" }
}).success(function(users) {
}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal("user'name");
done();
});
});
});
it('escapes two single quotes properly in where clauses', function(done) {
it('escapes two single quotes properly in where clauses', function() {
var self = this;
this.User
return this.User
.create({ username: "user''name" })
.success(function() {
self.User.findAll({
.then(function() {
return self.User.findAll({
where: { username: "user''name" }
}).success(function(users) {
}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal("user''name");
done();
});
});
});
it('returns the timestamps if no attributes have been specified', function(done) {
it('returns the timestamps if no attributes have been specified', function() {
var self = this;
this.User.create({ username: 'fnord' }).success(function() {
self.User.findAll().success(function(users) {
return this.User.create({ username: 'fnord' }).then(function() {
return self.User.findAll().then(function(users) {
expect(users[0].createdAt).to.exist;
done();
});
});
});
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() {
var self = this;
this.User.create({ username: 'fnord' }).success(function() {
self.User.findAll({ attributes: ['username'] }).success(function(users) {
return this.User.create({ username: 'fnord' }).then(function() {
return self.User.findAll({ attributes: ['username'] }).then(function(users) {
expect(users[0].createdAt).not.to.exist;
expect(users[0].username).to.exist;
done();
});
});
});
it('creates the deletedAt property, when defining paranoid as true', function(done) {
it('creates the deletedAt property, when defining paranoid as true', function() {
var self = this;
this.ParanoidUser.create({ username: 'fnord' }).success(function() {
self.ParanoidUser.findAll().success(function(users) {
return this.ParanoidUser.create({ username: 'fnord' }).then(function() {
return self.ParanoidUser.findAll().then(function(users) {
expect(users[0].deletedAt).to.be.null;
done();
});
});
});
it('destroys a record with a primary key of something other than id', function(done) {
it('destroys a record with a primary key of something other than id', function() {
var UserDestroy = this.sequelize.define('UserDestroy', {
newId: {
type: DataTypes.STRING,
......@@ -1746,63 +1603,58 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
email: DataTypes.STRING
});
UserDestroy.sync().success(function() {
UserDestroy.create({newId: '123ABC', email: 'hello'}).success(function() {
UserDestroy.find({where: {email: 'hello'}}).success(function(user) {
user.destroy().done(done);
return UserDestroy.sync().then(function() {
return UserDestroy.create({newId: '123ABC', email: 'hello'}).then(function() {
return UserDestroy.find({where: {email: 'hello'}}).then(function(user) {
return user.destroy();
});
});
});
});
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() {
var self = this;
this.ParanoidUser.create({ username: 'fnord' }).success(function() {
self.ParanoidUser.findAll().success(function(users) {
users[0].destroy().success(function(user) {
return this.ParanoidUser.create({ username: 'fnord' }).then(function() {
return self.ParanoidUser.findAll().then(function(users) {
return users[0].destroy().then(function(user) {
expect(user.deletedAt.getMonth).to.exist;
done();
});
});
});
});
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() {
var self = this;
this.ParanoidUser.create({ username: 'fnord' }).success(function() {
self.ParanoidUser.findAll().success(function(users) {
users[0].updateAttributes({username: 'newFnord'}).success(function(user) {
return this.ParanoidUser.create({ username: 'fnord' }).then(function() {
return self.ParanoidUser.findAll().then(function(users) {
return users[0].updateAttributes({username: 'newFnord'}).then(function(user) {
expect(user.deletedAt).not.to.exist;
done();
});
});
});
});
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() {
var self = this;
this.ParanoidUser.create({ username: 'fnord' }).success(function() {
self.ParanoidUser.findAll().success(function(users) {
self.ParanoidUser.create({ username: 'linkedFnord' }).success(function(linkedUser) {
users[0].setParanoidUser(linkedUser).success(function(user) {
return this.ParanoidUser.create({ username: 'fnord' }).then(function() {
return self.ParanoidUser.findAll().then(function(users) {
return self.ParanoidUser.create({ username: 'linkedFnord' }).then(function(linkedUser) {
return users[0].setParanoidUser(linkedUser).then(function(user) {
expect(user.deletedAt).not.to.exist;
done();
});
});
});
});
});
it('can reuse query option objects', function(done) {
it('can reuse query option objects', function() {
var self = this;
this.User.create({ username: 'fnord' }).success(function() {
return this.User.create({ username: 'fnord' }).then(function() {
var query = { where: { username: 'fnord' }};
self.User.findAll(query).success(function(users) {
return self.User.findAll(query).then(function(users) {
expect(users[0].username).to.equal('fnord');
self.User.findAll(query).success(function(users) {
return self.User.findAll(query).then(function(users) {
expect(users[0].username).to.equal('fnord');
done();
});
});
});
......@@ -1810,22 +1662,19 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
describe('find', function() {
it('can reuse query option objects', function(done) {
it('can reuse query option objects', function() {
var self = this;
this.User.create({ username: 'fnord' }).success(function() {
return this.User.create({ username: 'fnord' }).then(function() {
var query = { where: { username: 'fnord' }};
self.User.find(query).success(function(user) {
return self.User.find(query).then(function(user) {
expect(user.username).to.equal('fnord');
self.User.find(query).success(function(user) {
return self.User.find(query).then(function(user) {
expect(user.username).to.equal('fnord');
done();
});
});
});
});
it('returns null for null, undefined, and unset boolean values', function(done) {
it('returns null for null, undefined, and unset boolean values', function() {
var Setting = this.sequelize.define('SettingHelper', {
setting_key: DataTypes.STRING,
bool_value: { type: DataTypes.BOOLEAN, allowNull: true },
......@@ -1833,13 +1682,12 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
bool_value3: { type: DataTypes.BOOLEAN, allowNull: true }
}, { timestamps: false, logging: false });
Setting.sync({ force: true }).success(function() {
Setting.create({ setting_key: 'test', bool_value: null, bool_value2: undefined }).success(function() {
Setting.find({ where: { setting_key: 'test' } }).success(function(setting) {
return Setting.sync({ force: true }).then(function() {
return Setting.create({ setting_key: 'test', bool_value: null, bool_value2: undefined }).then(function() {
return Setting.find({ where: { setting_key: 'test' } }).then(function(setting) {
expect(setting.bool_value).to.equal(null);
expect(setting.bool_value2).to.equal(null);
expect(setting.bool_value3).to.equal(null);
done();
});
});
});
......@@ -1847,48 +1695,44 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
describe('equals', function() {
it('can compare records with Date field', function(done) {
it('can compare records with Date field', function() {
var self = this;
this.User.create({ username: 'fnord' }).success(function(user1) {
var query = { where: { username: 'fnord' }};
self.User.find(query).success(function(user2) {
return this.User.create({ username: 'fnord' }).then(function(user1) {
return self.User.find({ where: { username: 'fnord' }}).then(function(user2) {
expect(user1.equals(user2)).to.be.true;
done();
});
});
});
});
describe('values', function() {
it('returns all values', function(done) {
it('returns all values', function() {
var User = this.sequelize.define('UserHelper', {
username: DataTypes.STRING
}, { timestamps: false, logging: false });
User.sync().success(function() {
return User.sync().then(function() {
var user = User.build({ username: 'foo' });
expect(user.values).to.deep.equal({ username: 'foo', id: null });
done();
});
});
});
describe('destroy', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING });
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.destroy({ transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function(user) {
return sequelize.transaction().then(function(t) {
return user.destroy({ transaction: t }).then(function() {
return User.count().then(function(count1) {
return User.count({ transaction: t }).then(function(count2) {
expect(count1).to.equal(1);
expect(count2).to.equal(0);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1899,20 +1743,19 @@ describe(Support.getTestDialectTeaser('Instance'), 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() {
var UserDestroy = this.sequelize.define('UserDestroy', {
name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT
});
UserDestroy.sync({ force: true }).success(function() {
UserDestroy.create({name: 'hallo', bio: 'welt'}).success(function(u) {
UserDestroy.all().success(function(users) {
return UserDestroy.sync({ force: true }).then(function() {
return UserDestroy.create({name: 'hallo', bio: 'welt'}).then(function(u) {
return UserDestroy.findAll().then(function(users) {
expect(users.length).to.equal(1);
u.destroy().success(function() {
UserDestroy.all().success(function(users) {
return u.destroy().then(function() {
return UserDestroy.findAll().then(function(users) {
expect(users.length).to.equal(0);
done();
});
});
});
......@@ -1920,20 +1763,19 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('allows sql logging of delete statements', function(done) {
it('allows sql logging of delete statements', function() {
var UserDelete = this.sequelize.define('UserDelete', {
name: Support.Sequelize.STRING,
bio: Support.Sequelize.TEXT
});
UserDelete.sync({ force: true }).success(function() {
UserDelete.create({name: 'hallo', bio: 'welt'}).success(function(u) {
UserDelete.all().success(function(users) {
return UserDelete.sync({ force: true }).then(function() {
return UserDelete.create({name: 'hallo', bio: 'welt'}).then(function(u) {
return UserDelete.findAll().then(function(users) {
expect(users.length).to.equal(1);
u.destroy().on('sql', function(sql) {
return u.destroy().on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('DELETE')).to.be.above(-1);
done();
});
});
});
......
......@@ -171,7 +171,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
var applyFailTest = function applyFailTest(validatorDetails, i, validator) {
var failingValue = validatorDetails.fail[i];
it('correctly specifies an instance as invalid using a value of "' + failingValue + '" for the validation "' + validator + '"', function(done) {
it('correctly specifies an instance as invalid using a value of "' + failingValue + '" for the validation "' + validator + '"', function() {
var validations = {}
, message = validator + '(' + failingValue + ')';
......@@ -192,17 +192,16 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
var failingUser = UserFail.build({ name: failingValue });
failingUser.validate().done(function(err, _errors) {
return failingUser.validate().then(function(_errors) {
expect(_errors).not.to.be.null;
expect(_errors).to.be.an.instanceOf(Error);
expect(_errors.get('name')[0].message).to.equal(message);
done();
});
});
}
, applyPassTest = function applyPassTest(validatorDetails, j, validator) {
var succeedingValue = validatorDetails.pass[j];
it('correctly specifies an instance as valid using a value of "' + succeedingValue + '" for the validation "' + validator + '"', function(done) {
it('correctly specifies an instance as valid using a value of "' + succeedingValue + '" for the validation "' + validator + '"', function() {
var validations = {};
if (validatorDetails.hasOwnProperty('spec')) {
......@@ -220,12 +219,10 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
var successfulUser = UserSuccess.build({ name: succeedingValue });
successfulUser.validate().success(function(errors) {
return successfulUser.validate().then(function(errors) {
expect(errors).to.be.undefined;
done();
}).error(function(err) {
}).catch(function(err) {
expect(err).to.deep.equal({});
done();
});
});
};
......@@ -251,7 +248,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
describe('#update', function() {
it('should allow us to update specific columns without tripping the validations', function(done) {
it('should allow us to update specific columns without tripping the validations', function() {
var User = this.sequelize.define('model', {
username: Sequelize.STRING,
email: {
......@@ -265,22 +262,21 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User.sync({ force: true }).success(function() {
User.create({ username: 'bob', email: 'hello@world.com' }).success(function(user) {
User
return User.sync({ force: true }).then(function() {
return User.create({ username: 'bob', email: 'hello@world.com' }).then(function(user) {
return User
.update({ username: 'toni' }, { where: {id: user.id }})
.error(function(err) { console.log(err); })
.success(function() {
User.find(1).success(function(user) {
.catch(function(err) { console.log(err); })
.then(function() {
return User.find(1).then(function(user) {
expect(user.username).to.equal('toni');
done();
});
});
});
});
});
it('should be able to emit an error upon updating when a validation has failed from an instance', function(done) {
it('should be able to emit an error upon updating when a validation has failed from an instance', function() {
var Model = this.sequelize.define('model', {
name: {
type: Sequelize.STRING,
......@@ -291,18 +287,17 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function(model) {
model.updateAttributes({name: ''}).error(function(err) {
return Model.sync({ force: true }).then(function() {
return Model.create({name: 'World'}).then(function(model) {
return model.updateAttributes({name: ''}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('name')[0].message).to.equal('Validation notEmpty failed');
done();
});
});
});
});
it('should be able to emit an error upon updating when a validation has failed from the factory', function(done) {
it('should be able to emit an error upon updating when a validation has failed from the factory', function() {
var Model = this.sequelize.define('model', {
name: {
type: Sequelize.STRING,
......@@ -313,12 +308,11 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
Model.sync({ force: true }).success(function() {
Model.create({name: 'World'}).success(function() {
Model.update({name: ''}, {where: {id: 1}}).error(function(err) {
return Model.sync({ force: true }).then(function() {
return Model.create({name: 'World'}).then(function() {
return Model.update({name: ''}, {where: {id: 1}}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('name')[0].message).to.equal('Validation notEmpty failed');
done();
});
});
});
......@@ -327,7 +321,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
describe('#create', function() {
describe('generic', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
var Project = this.sequelize.define('Project', {
......@@ -348,29 +342,26 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
Project.hasOne(Task);
Task.belongsTo(Project);
this.sequelize.sync({ force: true }).success(function() {
return this.sequelize.sync({ force: true }).then(function() {
self.Project = Project;
self.Task = Task;
done();
});
});
it('correctly throws an error using create method ', function(done) {
this.Project.create({name: 'nope'}).error(function(err) {
it('correctly throws an error using create method ', function() {
return this.Project.create({name: 'nope'}).catch(function(err) {
expect(err).to.have.ownProperty('name');
done();
});
});
it('correctly validates using create method ', function(done) {
it('correctly validates using create method ', function() {
var self = this;
this.Project.create({}).success(function(project) {
self.Task.create({something: 1}).success(function(task) {
project.setTask(task).success(function(task) {
return this.Project.create({}).then(function(project) {
return self.Task.create({something: 1}).then(function(task) {
return project.setTask(task).then(function(task) {
expect(task.ProjectId).to.not.be.null;
task.setProject(project).success(function(project) {
return task.setProject(project).then(function(project) {
expect(project.ProjectId).to.not.be.null;
done();
});
});
});
......@@ -379,7 +370,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
});
describe('explicitly validating primary/auto incremented columns', function() {
it('should emit an error when we try to enter in a string for the id key without validation arguments', function(done) {
it('should emit an error when we try to enter in a string for the id key without validation arguments', function() {
var User = this.sequelize.define('UserId', {
id: {
type: Sequelize.INTEGER,
......@@ -391,16 +382,15 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User.sync({ force: true }).success(function() {
User.create({id: 'helloworld'}).error(function(err) {
return User.sync({ force: true }).then(function() {
return User.create({id: 'helloworld'}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('id')[0].message).to.equal('Validation isInt failed');
done();
});
});
});
it('should emit an error when we try to enter in a string for an auto increment key (not named id)', function(done) {
it('should emit an error when we try to enter in a string for an auto increment key (not named id)', function() {
var User = this.sequelize.define('UserId', {
username: {
type: Sequelize.INTEGER,
......@@ -412,17 +402,16 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User.sync({ force: true }).success(function() {
User.create({username: 'helloworldhelloworld'}).error(function(err) {
return User.sync({ force: true }).then(function() {
return User.create({username: 'helloworldhelloworld'}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('username')[0].message).to.equal('Username must be an integer!');
done();
});
});
});
describe("primaryKey with the name as id with arguments for it's validation", function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('UserId', {
id: {
type: Sequelize.INTEGER,
......@@ -434,41 +423,36 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
it('should emit an error when we try to enter in a string for the id key with validation arguments', function(done) {
this.User.create({id: 'helloworld'}).error(function(err) {
it('should emit an error when we try to enter in a string for the id key with validation arguments', function() {
return this.User.create({id: 'helloworld'}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('id')[0].message).to.equal('ID must be an integer!');
done();
});
});
it('should emit an error when we try to enter in a string for an auto increment key through .build().validate()', function(done) {
it('should emit an error when we try to enter in a string for an auto increment key through .build().validate()', function() {
var user = this.User.build({id: 'helloworld'});
user.validate().success(function(err) {
return user.validate().then(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('id')[0].message).to.equal('ID must be an integer!');
done();
});
});
it('should emit an error when we try to .save()', function(done) {
it('should emit an error when we try to .save()', function() {
var user = this.User.build({id: 'helloworld'});
user.save().error(function(err) {
return user.save().catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
expect(err.get('id')[0].message).to.equal('ID must be an integer!');
done();
});
});
});
});
describe('Pass all paths when validating', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
var Project = this.sequelize.define('Project', {
name: {
......@@ -496,27 +480,25 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
Project.hasOne(Task);
Task.belongsTo(Project);
Project.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
return Project.sync({ force: true }).then(function() {
return Task.sync({ force: true }).then(function() {
self.Project = Project;
self.Task = Task;
done();
});
});
});
it('produce 3 errors', function(done) {
this.Project.create({}).error(function(err) {
it('produce 3 errors', function() {
return this.Project.create({}).catch(function(err) {
expect(err).to.be.an.instanceOf(Error);
delete err.stack; // longStackTraces
expect(Object.keys(err)).to.have.length(3);
done();
});
});
});
});
it('correctly validates using custom validation methods', function(done) {
it('correctly validates using custom validation methods', function() {
var User = this.sequelize.define('User' + config.rand(), {
name: {
type: Sequelize.STRING,
......@@ -534,20 +516,18 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
var failingUser = User.build({ name: '3' });
failingUser.validate().success(function(error) {
return failingUser.validate().then(function(error) {
expect(error).to.be.an.instanceOf(Error);
expect(error.get('name')[0].message).to.equal("name should equal '2'");
var successfulUser = User.build({ name: '2' });
successfulUser.validate().success(function(err) {
return successfulUser.validate().then(function(err) {
expect(err).not.to.be.defined;
done();
});
});
});
it('supports promises with custom validation methods', function(done) {
it('supports promises with custom validation methods', function() {
var self = this
, User = this.sequelize.define('User' + config.rand(), {
name: {
......@@ -565,20 +545,19 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User.sync().success(function() {
User.build({ name: 'error' }).validate().success(function(error) {
return User.sync().then(function() {
return User.build({ name: 'error' }).validate().then(function(error) {
expect(error).to.be.an.instanceOf(self.sequelize.ValidationError);
expect(error.get('name')[0].message).to.equal('Invalid username');
User.build({ name: 'no error' }).validate().success(function(errors) {
return User.build({ name: 'no error' }).validate().then(function(errors) {
expect(errors).not.to.be.defined;
done();
});
});
});
});
it('skips other validations if allowNull is true and the value is null', function(done) {
it('skips other validations if allowNull is true and the value is null', function() {
var User = this.sequelize.define('User' + config.rand(), {
age: {
type: Sequelize.INTEGER,
......@@ -589,62 +568,23 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User
return User
.build({ age: -1 })
.validate()
.success(function(error) {
.then(function(error) {
expect(error).not.to.be.null;
expect(error).to.be.an.instanceOf(Error);
expect(error.get('age')[0].message).to.equal('must be positive');
User.build({ age: null }).validate().success(function() {
User.build({ age: 1 }).validate().success(function() {
done();
});
// TODO: This does not test anything
// Check what the original intention was
return User.build({ age: null }).validate().then(function() {
return User.build({ age: 1 }).validate();
});
});
});
it('validates a model with custom model-wide validation methods', function(done) {
var Foo = this.sequelize.define('Foo' + config.rand(), {
field1: {
type: Sequelize.INTEGER,
allowNull: true
},
field2: {
type: Sequelize.INTEGER,
allowNull: true
}
}, {
validate: {
xnor: function(done) {
if ((this.field1 === null) === (this.field2 === null)) {
done('xnor failed');
} else {
done();
}
}
}
});
Foo
.build({ field1: null, field2: null })
.validate()
.success(function(error) {
expect(error).not.to.be.null;
expect(error).to.be.an.instanceOf(Error);
expect(error.get('xnor')[0].message).to.equal('xnor failed');
Foo
.build({ field1: 33, field2: null })
.validate()
.success(function(errors) {
expect(errors).not.exist;
done();
});
});
});
it('validates a model with no async callback', function(done) {
it('validates a model with custom model-wide validation methods', function() {
var Foo = this.sequelize.define('Foo' + config.rand(), {
field1: {
type: Sequelize.INTEGER,
......@@ -664,25 +604,23 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
Foo
return Foo
.build({ field1: null, field2: null })
.validate()
.success(function(error) {
.then(function(error) {
expect(error).not.to.be.null;
expect(error).to.be.an.instanceOf(Error);
expect(error.get('xnor')[0].message).to.equal('xnor failed');
Foo
return Foo
.build({ field1: 33, field2: null })
.validate()
.success(function(errors) {
.then(function(errors) {
expect(errors).not.exist;
done();
});
});
});
it('validates model with a validator whose arg is an Array successfully twice in a row', function(done) {
it('validates model with a validator whose arg is an Array successfully twice in a row', function() {
var Foo = this.sequelize.define('Foo' + config.rand(), {
bar: {
type: Sequelize.STRING,
......@@ -693,11 +631,10 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}), foo;
foo = Foo.build({bar: 'a'});
foo.validate().success(function(errors) {
return foo.validate().then(function(errors) {
expect(errors).not.to.exist;
foo.validate().success(function(errors) {
return foo.validate().then(function(errors) {
expect(errors).not.to.exist;
done();
});
});
});
......@@ -717,14 +654,14 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
var failingBar = Bar.build({ field: 'value3' });
failingBar.validate().success(function(errors) {
return failingBar.validate().then(function(errors) {
expect(errors).not.to.be.null;
expect(errors.get('field')).to.have.length(1);
expect(errors.get('field')[0].message).to.equal('Validation isIn failed');
});
});
it('skips validations for the given fields', function(done) {
it('skips validations for the given fields', function() {
var values = ['value1', 'value2'];
var Bar = this.sequelize.define('Bar' + config.rand(), {
......@@ -739,9 +676,8 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
var failingBar = Bar.build({ field: 'value3' });
failingBar.validate({ skip: ['field'] }).success(function(errors) {
return failingBar.validate({ skip: ['field'] }).then(function(errors) {
expect(errors).not.to.exist;
done();
});
});
......@@ -764,7 +700,7 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
});
});
it('raises an error if saving a different value into an immutable field', function(done) {
it('raises an error if saving a different value into an immutable field', function() {
var User = this.sequelize.define('User', {
name: {
type: Sequelize.STRING,
......@@ -774,22 +710,21 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
}
});
User.sync({force: true}).success(function() {
User.create({ name: 'RedCat' }).success(function(user) {
return User.sync({force: true}).then(function() {
return User.create({ name: 'RedCat' }).then(function(user) {
expect(user.getDataValue('name')).to.equal('RedCat');
user.setDataValue('name', 'YellowCat');
user.save()
.done(function(errors) {
return user.save()
.catch(function(errors) {
expect(errors).to.not.be.null;
expect(errors).to.be.an.instanceOf(Error);
expect(errors.get('name')[0].message).to.eql('Validation isImmutable failed');
done();
});
});
});
});
it('allows setting an immutable field if the record is unsaved', function(done) {
it('allows setting an immutable field if the record is unsaved', function() {
var User = this.sequelize.define('User', {
name: {
type: Sequelize.STRING,
......@@ -803,114 +738,106 @@ describe(Support.getTestDialectTeaser('InstanceValidator'), function() {
expect(user.getDataValue('name')).to.equal('RedCat');
user.setDataValue('name', 'YellowCat');
user.validate().success(function(errors) {
return user.validate().then(function(errors) {
expect(errors).not.to.be.ok;
done();
});
});
it('raises an error for array on a STRING', function(done) {
it('raises an error for array on a STRING', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
});
User.build({
return User.build({
email: ['iama', 'dummy.com']
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('raises an error for array on a STRING(20)', function(done) {
it('raises an error for array on a STRING(20)', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING(20)
}
});
User.build({
return User.build({
email: ['iama', 'dummy.com']
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('raises an error for array on a TEXT', function(done) {
it('raises an error for array on a TEXT', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.TEXT
}
});
User.build({
return User.build({
email: ['iama', 'dummy.com']
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('raises an error for {} on a STRING', function(done) {
it('raises an error for {} on a STRING', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
});
User.build({
return User.build({
email: {lol: true}
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('raises an error for {} on a STRING(20)', function(done) {
it('raises an error for {} on a STRING(20)', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING(20)
}
});
User.build({
return User.build({
email: {lol: true}
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('raises an error for {} on a TEXT', function(done) {
it('raises an error for {} on a TEXT', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.TEXT
}
});
User.build({
return User.build({
email: {lol: true}
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).to.be.an.instanceof(Sequelize.ValidationError);
done();
});
});
it('does not raise an error for null on a STRING (where null is allowed)', function(done) {
it('does not raise an error for null on a STRING (where null is allowed)', function() {
var User = this.sequelize.define('User', {
'email': {
type: Sequelize.STRING
}
});
User.build({
return User.build({
email: null
}).validate().success(function(errors) {
}).validate().then(function(errors) {
expect(errors).not.to.be.ok;
done();
});
});
......
......@@ -60,19 +60,19 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Support.Sequelize.STRING });
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function(user) {
sequelize.transaction().then(function(t) {
user.update({ username: 'bar' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function(user) {
return sequelize.transaction().then(function(t) {
return user.update({ username: 'bar' }, { transaction: t }).then(function() {
return User.findAll().then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
expect(users1[0].username).to.equal('foo');
expect(users2[0].username).to.equal('bar');
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -325,88 +325,84 @@ describe(Support.getTestDialectTeaser('Instance'), function() {
});
});
it('updates attributes in the database', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
it('updates attributes in the database', function() {
return this.User.create({ username: 'user' }).then(function(user) {
expect(user.username).to.equal('user');
user.update({ username: 'person' }).success(function(user) {
return user.update({ username: 'person' }).then(function(user) {
expect(user.username).to.equal('person');
done();
});
});
});
it('ignores unknown attributes', function(done) {
this.User.create({ username: 'user' }).success(function(user) {
user.update({ username: 'person', foo: 'bar'}).success(function(user) {
it('ignores unknown attributes', function() {
return this.User.create({ username: 'user' }).then(function(user) {
return user.update({ username: 'person', foo: 'bar'}).then(function(user) {
expect(user.username).to.equal('person');
expect(user.foo).not.to.exist;
done();
});
});
});
it("doesn't update primary keys or timestamps", function(done) {
it("doesn't update primary keys or timestamps", function() {
var User = this.sequelize.define('User' + config.rand(), {
name: DataTypes.STRING,
bio: DataTypes.TEXT,
identifier: {type: DataTypes.STRING, primaryKey: true}
});
User.sync({ force: true }).success(function() {
User.create({
return User.sync({ force: true }).then(function() {
return User.create({
name: 'snafu',
identifier: 'identifier'
}).success(function(user) {
}).then(function(user) {
var oldCreatedAt = user.createdAt
, oldUpdatedAt = user.updatedAt
, oldIdentifier = user.identifier;
setTimeout(function() {
user.update({
return this.sequelize.Promise.delay(1000).then(function() {
return user.update({
name: 'foobar',
createdAt: new Date(2000, 1, 1),
identifier: 'another identifier'
}).success(function(user) {
}).then(function(user) {
expect(new Date(user.createdAt)).to.equalDate(new Date(oldCreatedAt));
expect(new Date(user.updatedAt)).to.not.equalTime(new Date(oldUpdatedAt));
expect(user.identifier).to.equal(oldIdentifier);
done();
});
}, 1000);
});
});
});
});
it('stores and restores null values', function(done) {
it('stores and restores null values', function() {
var Download = this.sequelize.define('download', {
startedAt: DataTypes.DATE,
canceledAt: DataTypes.DATE,
finishedAt: DataTypes.DATE
});
Download.sync().success(function() {
Download.create({
return Download.sync().then(function() {
return Download.create({
startedAt: new Date()
}).success(function(download) {
}).then(function(download) {
expect(download.startedAt instanceof Date).to.be.true;
expect(download.canceledAt).to.not.be.ok;
expect(download.finishedAt).to.not.be.ok;
download.update({
return download.update({
canceledAt: new Date()
}).success(function(download) {
}).then(function(download) {
expect(download.startedAt instanceof Date).to.be.true;
expect(download.canceledAt instanceof Date).to.be.true;
expect(download.finishedAt).to.not.be.ok;
Download.all({
return Download.findAll({
where: (dialect === 'postgres' || dialect === 'mssql' ? '"finishedAt" IS NULL' : '`finishedAt` IS NULL')
}).success(function(downloads) {
}).then(function(downloads) {
downloads.forEach(function(download) {
expect(download.startedAt instanceof Date).to.be.true;
expect(download.canceledAt instanceof Date).to.be.true;
expect(download.finishedAt).to.not.be.ok;
done();
});
});
});
......
......@@ -295,7 +295,7 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(product.toJSON()).to.deep.equal({withTaxes: 1250, price: 1000, id: null});
});
it('should work with save', function(done) {
it('should work with save', function() {
var Contact = this.sequelize.define('Contact', {
first: { type: Sequelize.STRING },
last: { type: Sequelize.STRING },
......@@ -311,7 +311,7 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
}
});
this.sequelize.sync().done(function() {
return this.sequelize.sync().then(function() {
var contact = Contact.build({
first: 'My',
last: 'Name',
......@@ -319,10 +319,8 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
});
expect(contact.get('tags')).to.deep.equal(['yes', 'no']);
contact.save().done(function(err, me) {
expect(err).not.to.be.ok;
return contact.save().then(function(me) {
expect(me.get('tags')).to.deep.equal(['yes', 'no']);
done();
});
});
});
......@@ -380,18 +378,16 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
});
describe('changed', function() {
it('should return false if object was built from database', function(done) {
it('should return false if object was built from database', function() {
var User = this.sequelize.define('User', {
name: {type: DataTypes.STRING}
});
User.sync().done(function() {
User.create({name: 'Jan Meier'}).done(function(err, user) {
expect(err).not.to.be.ok;
return User.sync().then(function() {
return User.create({name: 'Jan Meier'}).then(function(user) {
expect(user.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok;
expect(user.isDirty).to.be.false;
done();
});
});
});
......@@ -410,12 +406,12 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(user.isDirty).to.be.true;
});
it('should return false immediately after saving', function(done) {
it('should return false immediately after saving', function() {
var User = this.sequelize.define('User', {
name: {type: DataTypes.STRING}
});
User.sync().done(function() {
return User.sync().then(function() {
var user = User.build({
name: 'Jan Meier'
});
......@@ -424,12 +420,10 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(user.changed()).to.be.ok;
expect(user.isDirty).to.be.true;
user.save().done(function(err) {
expect(err).not.to.be.ok;
return user.save().then(function() {
expect(user.changed('name')).to.be.false;
expect(user.changed()).not.to.be.ok;
expect(user.isDirty).to.be.false;
done();
});
});
});
......@@ -472,7 +466,6 @@ describe(Support.getTestDialectTeaser('DAO'), function() {
expect(changed).to.be.ok;
expect(changed.length).to.be.ok;
expect(changed.indexOf('name') > -1).to.be.ok;
expect(user.changed()).not.to.be.ok;
});
});
......
......@@ -117,7 +117,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}).to.throw(Error, 'A model validator function must not have the same name as a field. Model: Foo, field/validation name: field');
});
it('should allow me to set a default value for createdAt and updatedAt', function(done) {
it('should allow me to set a default value for createdAt and updatedAt', function() {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER,
createdAt: {
......@@ -130,27 +130,26 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
}, { timestamps: true });
UserTable.sync({ force: true }).success(function() {
UserTable.create({aNumber: 5}).success(function(user) {
UserTable.bulkCreate([
return UserTable.sync({ force: true }).then(function() {
return UserTable.create({aNumber: 5}).then(function(user) {
return UserTable.bulkCreate([
{aNumber: 10},
{aNumber: 12}
]).success(function() {
UserTable.all({where: {aNumber: { gte: 10 }}}).success(function(users) {
]).then(function() {
return UserTable.findAll({where: {aNumber: { gte: 10 }}}).then(function(users) {
expect(moment(user.createdAt).format('YYYY-MM-DD')).to.equal('2012-01-01');
expect(moment(user.updatedAt).format('YYYY-MM-DD')).to.equal('2012-01-02');
users.forEach(function(u) {
expect(moment(u.createdAt).format('YYYY-MM-DD')).to.equal('2012-01-01');
expect(moment(u.updatedAt).format('YYYY-MM-DD')).to.equal('2012-01-02');
});
done();
});
});
});
});
});
it('should allow me to set a function as default value', function(done) {
it('should allow me to set a function as default value', function() {
var defaultFunction = sinon.stub().returns(5);
var UserTable = this.sequelize.define('UserCol', {
aNumber: {
......@@ -159,19 +158,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
}, { timestamps: true });
UserTable.sync({ force: true }).success(function() {
UserTable.create().success(function(user) {
UserTable.create().success(function(user2) {
return UserTable.sync({ force: true }).then(function() {
return UserTable.create().then(function(user) {
return UserTable.create().then(function(user2) {
expect(user.aNumber).to.equal(5);
expect(user2.aNumber).to.equal(5);
expect(defaultFunction.callCount).to.equal(2);
done();
});
});
});
});
it('should allow me to override updatedAt, createdAt, and deletedAt fields', function(done) {
it('should allow me to override updatedAt, createdAt, and deletedAt fields', function() {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
}, {
......@@ -182,13 +180,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
paranoid: true
});
UserTable.sync({force: true}).success(function() {
UserTable.create({aNumber: 4}).success(function(user) {
return UserTable.sync({force: true}).then(function() {
return UserTable.create({aNumber: 4}).then(function(user) {
expect(user.updatedOn).to.exist;
expect(user.dateCreated).to.exist;
user.destroy().success(function(user) {
return user.destroy().then(function(user) {
expect(user.deletedAtThisTime).to.exist;
done();
});
});
});
......@@ -217,14 +214,13 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(user.updatedAt).not.to.exist;
return user.destroy().then(function(user) {
expect(user.deletedAtThisTime).to.exist;
});
});
});
});
});
it('should allow me to override updatedAt, createdAt, and deletedAt fields with underscored being true', function(done) {
it('should allow me to override updatedAt, createdAt, and deletedAt fields with underscored being true', function() {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
}, {
......@@ -236,19 +232,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
underscored: true
});
UserTable.sync({force: true}).success(function() {
UserTable.create({aNumber: 4}).success(function(user) {
return UserTable.sync({force: true}).then(function() {
return UserTable.create({aNumber: 4}).then(function(user) {
expect(user.updated_on).to.exist;
expect(user.date_created).to.exist;
user.destroy().success(function(user) {
return user.destroy().then(function(user) {
expect(user.deleted_at_this_time).to.exist;
done();
});
});
});
});
it('returns proper defaultValues after save when setter is set', function(done) {
it('returns proper defaultValues after save when setter is set', function() {
var titleSetter = sinon.spy()
, Task = this.sequelize.define('TaskBuild', {
title: {
......@@ -262,18 +257,16 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
Task.sync({force: true}).success(function() {
Task.build().save().success(function(record) {
return Task.sync({force: true}).then(function() {
return Task.build().save().then(function(record) {
expect(record.title).to.be.a('string');
expect(record.title).to.equal('');
expect(titleSetter.notCalled).to.be.ok; // The setter method should not be invoked for default values
done();
}).error(done);
}).error(done);
});
});
});
it('should work with both paranoid and underscored being true', function(done) {
it('should work with both paranoid and underscored being true', function() {
var UserTable = this.sequelize.define('UserCol', {
aNumber: Sequelize.INTEGER
}, {
......@@ -281,11 +274,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
underscored: true
});
UserTable.sync({force: true}).success(function() {
UserTable.create({aNumber: 30}).success(function(user) {
UserTable.count().success(function(c) {
return UserTable.sync({force: true}).then(function() {
return UserTable.create({aNumber: 30}).then(function(user) {
return UserTable.count().then(function(c) {
expect(c).to.equal(1);
done();
});
});
});
......@@ -499,15 +491,14 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('build', function() {
it("doesn't create database entries", function(done) {
it("doesn't create database entries", function() {
this.User.build({ username: 'John Wayne' });
this.User.all().success(function(users) {
return this.User.findAll().then(function(users) {
expect(users).to.have.length(0);
done();
});
});
it('fills the objects with default values', function(done) {
it('fills the objects with default values', function() {
var Task = this.sequelize.define('TaskBuild', {
title: {type: Sequelize.STRING, defaultValue: 'a task!'},
foo: {type: Sequelize.INTEGER, defaultValue: 2},
......@@ -521,10 +512,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(Task.build().bar).to.not.be.ok;
expect(Task.build().foobar).to.equal('asd');
expect(Task.build().flag).to.be.false;
done();
});
it('fills the objects with default values', function(done) {
it('fills the objects with default values', function() {
var Task = this.sequelize.define('TaskBuild', {
title: {type: Sequelize.STRING, defaultValue: 'a task!'},
foo: {type: Sequelize.INTEGER, defaultValue: 2},
......@@ -537,10 +527,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(Task.build().bar).to.not.be.ok;
expect(Task.build().foobar).to.equal('asd');
expect(Task.build().flag).to.be.false;
done();
});
it('attaches getter and setter methods from attribute definition', function(done) {
it('attaches getter and setter methods from attribute definition', function() {
var Product = this.sequelize.define('ProductWithSettersAndGetters1', {
price: {
type: Sequelize.INTEGER,
......@@ -560,10 +549,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
p.price = 0;
expect(p.price).to.equal('answer = 42');
done();
});
it('attaches getter and setter methods from options', function(done) {
it('attaches getter and setter methods from options', function() {
var Product = this.sequelize.define('ProductWithSettersAndGetters2', {
priceInCents: Sequelize.INTEGER
},{
......@@ -585,10 +573,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(Product.build({price: 20}).priceInCents).to.equal(20 * 100);
expect(Product.build({priceInCents: 30 * 100}).price).to.equal('$' + 30);
done();
});
it('attaches getter and setter methods from options only if not defined in attribute', function(done) {
it('attaches getter and setter methods from options only if not defined in attribute', function() {
var Product = this.sequelize.define('ProductWithSettersAndGetters3', {
price1: {
type: Sequelize.INTEGER,
......@@ -611,7 +598,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(p.price1).to.equal(10);
expect(p.price2).to.equal(20);
done();
});
describe('include', function() {
......@@ -712,16 +698,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('find', function() {
if (current.dialect.supports.transactions) {
it('supports the transaction option in the first parameter', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports the transaction option in the first parameter', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({ where: { username: 'foo' }, transaction: t }).success(function(user) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.find({ where: { username: 'foo' }, transaction: t }).then(function(user) {
expect(user).to.not.be.null;
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -730,10 +715,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('should not fail if model is paranoid and where is an empty array', function(done) {
it('should not fail if model is paranoid and where is an empty array', function() {
var User = this.sequelize.define('User', { username: Sequelize.STRING }, { paranoid: true });
User.sync({ force: true })
return User.sync({ force: true })
.then(function() {
return User.create({ username: 'A fancy name' });
})
......@@ -742,10 +727,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
})
.then(function(u) {
expect(u.username).to.equal('A fancy name');
done();
})
.catch (function(err) {
done(err);
});
});
});
......@@ -753,21 +734,21 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('findOrInitialize', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING, foo: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findOrInitialize({
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.findOrInitialize({
where: {username: 'foo'}
}).spread(function(user1) {
User.findOrInitialize({
return User.findOrInitialize({
where: {username: 'foo'},
transaction: t
}).spread(function(user2) {
User.findOrInitialize({
return User.findOrInitialize({
where: {username: 'foo'},
defaults: { foo: 'asd' },
transaction: t
......@@ -775,7 +756,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(user1.isNewRecord).to.be.true;
expect(user2.isNewRecord).to.be.false;
expect(user3.isNewRecord).to.be.false;
t.commit().success(function() { done(); });
return t.commit();
});
});
});
......@@ -787,26 +768,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
describe('returns an instance if it already exists', function() {
it('with a single find field', function(done) {
it('with a single find field', function() {
var self = this;
this.User.create({ username: 'Username' }).success(function(user) {
self.User.findOrInitialize({
return this.User.create({ username: 'Username' }).then(function(user) {
return self.User.findOrInitialize({
where: { username: user.username }
}).spread(function(_user, initialized) {
expect(_user.id).to.equal(user.id);
expect(_user.username).to.equal('Username');
expect(initialized).to.be.false;
done();
});
});
});
it('with multiple find fields', function(done) {
it('with multiple find fields', function() {
var self = this;
this.User.create({ username: 'Username', data: 'data' }).success(function(user) {
self.User.findOrInitialize({ where: {
return this.User.create({ username: 'Username', data: 'data' }).then(function(user) {
return self.User.findOrInitialize({ where: {
username: user.username,
data: user.data
}}).spread(function(_user, initialized) {
......@@ -814,12 +794,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(_user.username).to.equal('Username');
expect(_user.data).to.equal('data');
expect(initialized).to.be.false;
done();
});
});
});
it('builds a new instance with default value.', function(done) {
it('builds a new instance with default value.', function() {
var data = {
username: 'Username'
},
......@@ -827,7 +806,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
data: 'ThisIsData'
};
this.User.findOrInitialize({
return this.User.findOrInitialize({
where: data,
defaults: default_values
}).spread(function(user, initialized) {
......@@ -837,7 +816,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(initialized).to.be.true;
expect(user.isNewRecord).to.be.true;
expect(user.isDirty).to.be.true;
done();
});
});
});
......@@ -858,19 +836,19 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).done(function() {
User.create({ username: 'foo' }).done(function() {
sequelize.transaction().then(function(t) {
User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).done(function(err) {
User.all().done(function(err, users1) {
User.all({ transaction: t }).done(function(err, users2) {
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function() {
return sequelize.transaction().then(function(t) {
return User.update({ username: 'bar' }, {where: {username: 'foo'}, transaction: t }).then(function() {
return User.findAll().then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
expect(users1[0].username).to.equal('foo');
expect(users2[0].username).to.equal('bar');
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -881,7 +859,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('updates the attributes that we select only without updating createdAt', function(done) {
it('updates the attributes that we select only without updating createdAt', function() {
var User = this.sequelize.define('User1', {
username: Sequelize.STRING,
secretValue: Sequelize.STRING
......@@ -889,22 +867,20 @@ describe(Support.getTestDialectTeaser('Model'), function() {
paranoid: true
});
User.sync({ force: true }).success(function() {
User.create({username: 'Peter', secretValue: '42'}).success(function(user) {
user.updateAttributes({ secretValue: '43' }, ['secretValue']).on('sql', function(sql) {
return User.sync({ force: true }).then(function() {
return User.create({username: 'Peter', secretValue: '42'}).then(function(user) {
return user.updateAttributes({ secretValue: '43' }, ['secretValue']).on('sql', function(sql) {
if (dialect === 'mssql') {
expect(sql).to.not.contain('createdAt');
} else {
expect(sql).to.match(/UPDATE\s+[`"]+User1s[`"]+\s+SET\s+[`"]+secretValue[`"]='43',[`"]+updatedAt[`"]+='[^`",]+'\s+WHERE [`"]+id[`"]+\s=\s1/);
}
done();
});
});
});
});
it('allows sql logging of updated statements', function(done) {
it('allows sql logging of updated statements', function() {
var User = this.sequelize.define('User', {
name: Sequelize.STRING,
bio: Sequelize.TEXT
......@@ -912,70 +888,64 @@ describe(Support.getTestDialectTeaser('Model'), function() {
paranoid: true
});
User.sync({ force: true }).success(function() {
User.create({ name: 'meg', bio: 'none' }).success(function(u) {
return User.sync({ force: true }).then(function() {
return User.create({ name: 'meg', bio: 'none' }).then(function(u) {
expect(u).to.exist;
expect(u).not.to.be.null;
u.updateAttributes({name: 'brian'}).on('sql', function(sql) {
return u.updateAttributes({name: 'brian'}).on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('UPDATE')).to.be.above(-1);
done();
});
});
});
});
it('updates only values that match filter', function(done) {
it('updates only values that match filter', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }];
this.User.bulkCreate(data).success(function() {
self.User.update({username: 'Bill'}, {where: {secretValue: '42'}})
.success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).to.equal(3);
users.forEach(function(user) {
if (user.secretValue === '42') {
expect(user.username).to.equal('Bill');
} else {
expect(user.username).to.equal('Bob');
}
});
return this.User.bulkCreate(data).then(function() {
return self.User.update({username: 'Bill'}, {where: {secretValue: '42'}}).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(3);
done();
users.forEach(function(user) {
if (user.secretValue === '42') {
expect(user.username).to.equal('Bill');
} else {
expect(user.username).to.equal('Bob');
}
});
});
});
});
});
it('updates with casting', function(done) {
it('updates with casting', function() {
var self = this;
this.User.create({
return this.User.create({
username: 'John'
}).success(function(user) {
self.User.update({username: self.sequelize.cast('1', dialect === 'mssql' ? 'nvarchar' : 'char')}, {where: {username: 'John'}}).success(function() {
self.User.all().success(function(users) {
}).then(function(user) {
return self.User.update({username: self.sequelize.cast('1', dialect === 'mssql' ? 'nvarchar' : 'char')}, {where: {username: 'John'}}).then(function() {
return self.User.findAll().then(function(users) {
expect(users[0].username).to.equal('1');
done();
});
});
});
});
it('updates with function and column value', function(done) {
it('updates with function and column value', function() {
var self = this;
this.User.create({
return this.User.create({
username: 'John'
}).success(function(user) {
self.User.update({username: self.sequelize.fn('upper', self.sequelize.col('username'))}, {where: {username: 'John'}}).success(function() {
self.User.all().success(function(users) {
}).then(function(user) {
return self.User.update({username: self.sequelize.fn('upper', self.sequelize.col('username'))}, {where: {username: 'John'}}).then(function() {
return self.User.findAll().then(function(users) {
expect(users[0].username).to.equal('JOHN');
done();
});
});
});
......@@ -1010,65 +980,54 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('returns the number of affected rows', function(_done) {
it('returns the number of affected rows', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }]
, done = _.after(2, _done);
{ username: 'Bob', secretValue: '43' }];
this.User.bulkCreate(data).success(function() {
self.User.update({username: 'Bill'}, {where: {secretValue: '42'}}).spread(function(affectedRows) {
return this.User.bulkCreate(data).then(function() {
return self.User.update({username: 'Bill'}, {where: {secretValue: '42'}}).spread(function(affectedRows) {
expect(affectedRows).to.equal(2);
done();
});
self.User.update({username: 'Bill'}, {where: {secretValue: '44'}}).spread(function(affectedRows) {
expect(affectedRows).to.equal(0);
done();
}).then(function() {
return self.User.update({username: 'Bill'}, {where: {secretValue: '44'}}).spread(function(affectedRows) {
expect(affectedRows).to.equal(0);
});
});
});
});
if (dialect === 'postgres') {
it('returns the affected rows if `options.returning` is true', function(_done) {
it('returns the affected rows if `options.returning` is true', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }]
, done = _.after(2, _done);
{ username: 'Bob', secretValue: '43' }];
this.User.bulkCreate(data).success(function() {
self.User.update({ username: 'Bill' }, { where: {secretValue: '42' }, returning: true }).spread(function(count, rows) {
return this.User.bulkCreate(data).then(function() {
return self.User.update({ username: 'Bill' }, { where: {secretValue: '42' }, returning: true }).spread(function(count, rows) {
expect(count).to.equal(2);
expect(rows).to.have.length(2);
done();
});
self.User.update({ username: 'Bill'}, { where: {secretValue: '44' }, returning: true }).spread(function(count, rows) {
expect(count).to.equal(0);
expect(rows).to.have.length(0);
done();
}).then(function() {
return self.User.update({ username: 'Bill'}, { where: {secretValue: '44' }, returning: true }).spread(function(count, rows) {
expect(count).to.equal(0);
expect(rows).to.have.length(0);
});
});
});
});
}
if (Support.dialectIsMySQL()) {
it('supports limit clause', function(done) {
it('supports limit clause', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Peter', secretValue: '42' },
{ username: 'Peter', secretValue: '42' }];
this.User.bulkCreate(data).success(function() {
self.User.update({secretValue: '43'}, {where: {username: 'Peter'}, limit: 1}).spread(function(affectedRows) {
return this.User.bulkCreate(data).then(function() {
return self.User.update({secretValue: '43'}, {where: {username: 'Peter'}, limit: 1}).spread(function(affectedRows) {
expect(affectedRows).to.equal(1);
done();
});
});
});
......@@ -1126,22 +1085,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function() {
sequelize.transaction().then(function(t) {
User.destroy({
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function() {
return sequelize.transaction().then(function(t) {
return User.destroy({
where: {},
transaction: t
}).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
}).then(function() {
return User.count().then(function(count1) {
return User.count({ transaction: t }).then(function(count2) {
expect(count1).to.equal(1);
expect(count2).to.equal(0);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1152,19 +1111,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('deletes values that match filter', function(done) {
it('deletes values that match filter', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42' },
{ username: 'Paul', secretValue: '42' },
{ username: 'Bob', secretValue: '43' }];
this.User.bulkCreate(data).success(function() {
self.User.destroy({where: {secretValue: '42'}})
.success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.destroy({where: {secretValue: '42'}})
.then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal('Bob');
done();
});
});
});
......@@ -1260,26 +1218,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe("can't find records marked as deleted with paranoid being true", function() {
it('with the DAOFactory', function(done) {
it('with the DAOFactory', function() {
var User = this.sequelize.define('UserCol', {
username: Sequelize.STRING
}, { paranoid: true });
User.sync({ force: true }).success(function() {
User.bulkCreate([
return User.sync({ force: true }).then(function() {
return User.bulkCreate([
{username: 'Toni'},
{username: 'Tobi'},
{username: 'Max'}
]).success(function() {
User.find(1).success(function(user) {
user.destroy().success(function() {
User.find(1).success(function(user) {
]).then(function() {
return User.find(1).then(function(user) {
return user.destroy().then(function() {
return User.find(1).then(function(user) {
expect(user).to.be.null;
User.count().success(function(cnt) {
return User.count().then(function(cnt) {
expect(cnt).to.equal(2);
User.all().success(function(users) {
return User.findAll().then(function(users) {
expect(users).to.have.length(2);
done();
});
});
});
......@@ -1490,16 +1447,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('equals', function() {
it('correctly determines equality of objects', function(done) {
this.User.create({username: 'hallo', data: 'welt'}).success(function(u) {
it('correctly determines equality of objects', function() {
return this.User.create({username: 'hallo', data: 'welt'}).then(function(u) {
expect(u.equals(u)).to.be.ok;
done();
});
});
// sqlite can't handle multiple primary keys
if (dialect !== 'sqlite') {
it('correctly determines equality with multiple primary keys', function(done) {
it('correctly determines equality with multiple primary keys', function() {
var userKeys = this.sequelize.define('userkeys', {
foo: {type: Sequelize.STRING, primaryKey: true},
bar: {type: Sequelize.STRING, primaryKey: true},
......@@ -1507,10 +1463,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
bio: Sequelize.TEXT
});
userKeys.sync({ force: true }).success(function() {
userKeys.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).success(function(u) {
return userKeys.sync({ force: true }).then(function() {
return userKeys.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).then(function(u) {
expect(u.equals(u)).to.be.ok;
done();
});
});
});
......@@ -1520,7 +1475,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('equalsOneOf', function() {
// sqlite can't handle multiple primary keys
if (dialect !== 'sqlite') {
beforeEach(function(done) {
beforeEach(function() {
this.userKey = this.sequelize.define('userKeys', {
foo: {type: Sequelize.STRING, primaryKey: true},
bar: {type: Sequelize.STRING, primaryKey: true},
......@@ -1528,22 +1483,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
bio: Sequelize.TEXT
});
this.userKey.sync({ force: true }).success(function() {
done();
});
return this.userKey.sync({ force: true });
});
it('determines equality if one is matching', function(done) {
this.userKey.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).success(function(u) {
it('determines equality if one is matching', function() {
return this.userKey.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).then(function(u) {
expect(u.equalsOneOf([u, {a: 1}])).to.be.ok;
done();
});
});
it("doesn't determine equality if none is matching", function(done) {
this.userKey.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).success(function(u) {
it("doesn't determine equality if none is matching", function() {
return this.userKey.create({foo: '1', bar: '2', name: 'hallo', bio: 'welt'}).then(function(u) {
expect(u.equalsOneOf([{b: 2}, {a: 1}])).to.not.be.ok;
done();
});
});
}
......@@ -1551,18 +1502,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('count', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.count().then(function(count1) {
return User.count({ transaction: t }).then(function(count2) {
expect(count1).to.equal(0);
expect(count2).to.equal(1);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1572,12 +1523,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('counts all created objects', function(done) {
it('counts all created objects', function() {
var self = this;
this.User.bulkCreate([{username: 'user1'}, {username: 'user2'}]).success(function() {
self.User.count().success(function(count) {
return this.User.bulkCreate([{username: 'user1'}, {username: 'user2'}]).then(function() {
return self.User.count().then(function(count) {
expect(count).to.equal(2);
done();
});
});
});
......@@ -1597,48 +1547,44 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('does not modify the passed arguments', function(done) {
it('does not modify the passed arguments', function() {
var options = { where: ['username = ?', 'user1']};
this.User.count(options).success(function(count) {
return this.User.count(options).then(function(count) {
expect(options).to.deep.equal({ where: ['username = ?', 'user1']});
done();
});
});
it('allows sql logging', function(done) {
this.User.count().on('sql', function(sql) {
it('allows sql logging', function() {
return this.User.count().on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('SELECT')).to.be.above(-1);
done();
});
});
it('filters object', function(done) {
it('filters object', function() {
var self = this;
this.User.create({username: 'user1'}).success(function() {
self.User.create({username: 'foo'}).success(function() {
self.User.count({where: "username LIKE '%us%'"}).success(function(count) {
return this.User.create({username: 'user1'}).then(function() {
return self.User.create({username: 'foo'}).then(function() {
return self.User.count({where: "username LIKE '%us%'"}).then(function(count) {
expect(count).to.equal(1);
done();
});
});
});
});
it('supports distinct option', function(done) {
it('supports distinct option', function() {
var Post = this.sequelize.define('Post', {});
var PostComment = this.sequelize.define('PostComment', {});
Post.hasMany(PostComment);
Post.sync({ force: true }).success(function() {
PostComment.sync({ force: true }).success(function() {
Post.create({}).success(function(post) {
PostComment.bulkCreate([{ PostId: post.id },{ PostId: post.id }]).success(function() {
Post.count({ include: [{ model: PostComment, required: false }] }).success(function(count1) {
Post.count({ distinct: true, include: [{ model: PostComment, required: false }] }).success(function(count2) {
return Post.sync({ force: true }).then(function() {
return PostComment.sync({ force: true }).then(function() {
return Post.create({}).then(function(post) {
return PostComment.bulkCreate([{ PostId: post.id },{ PostId: post.id }]).then(function() {
return Post.count({ include: [{ model: PostComment, required: false }] }).then(function(count1) {
return Post.count({ distinct: true, include: [{ model: PostComment, required: false }] }).then(function(count2) {
expect(count1).to.equal(2);
expect(count2).to.equal(1);
done();
});
});
});
......@@ -1650,7 +1596,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('min', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.UserWithAge = this.sequelize.define('UserWithAge', {
age: Sequelize.INTEGER
......@@ -1660,26 +1606,24 @@ describe(Support.getTestDialectTeaser('Model'), function() {
value: Sequelize.DECIMAL(10, 3)
});
this.UserWithAge.sync({ force: true }).success(function() {
self.UserWithDec.sync({ force: true }).success(function() {
done();
});
return this.UserWithAge.sync({ force: true }).then(function() {
return self.UserWithDec.sync({ force: true });
});
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.min('age').success(function(min1) {
User.min('age', { transaction: t }).success(function(min2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).then(function() {
return User.min('age').then(function(min1) {
return User.min('age', { transaction: t }).then(function(min2) {
expect(min1).to.be.not.ok;
expect(min2).to.equal(2);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1689,58 +1633,53 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('should return the min value', function(done) {
it('should return the min value', function() {
var self = this;
this.UserWithAge.bulkCreate([{age: 3}, { age: 2 }]).success(function() {
self.UserWithAge.min('age').success(function(min) {
return this.UserWithAge.bulkCreate([{age: 3}, { age: 2 }]).then(function() {
return self.UserWithAge.min('age').then(function(min) {
expect(min).to.equal(2);
done();
});
});
});
it('allows sql logging', function(done) {
this.UserWithAge.min('age').on('sql', function(sql) {
it('allows sql logging', function() {
return this.UserWithAge.min('age').on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('SELECT')).to.be.above(-1);
done();
});
});
it('should allow decimals in min', function(done) {
it('should allow decimals in min', function() {
var self = this;
this.UserWithDec.bulkCreate([{value: 5.5}, {value: 3.5}]).success(function() {
self.UserWithDec.min('value').success(function(min) {
return this.UserWithDec.bulkCreate([{value: 5.5}, {value: 3.5}]).then(function() {
return self.UserWithDec.min('value').then(function(min) {
expect(min).to.equal(3.5);
done();
});
});
});
it('should allow strings in min', function(done) {
it('should allow strings in min', function() {
var self = this;
this.User.bulkCreate([{username: 'bbb'}, {username: 'yyy'}]).success(function() {
self.User.min('username').success(function(min) {
return this.User.bulkCreate([{username: 'bbb'}, {username: 'yyy'}]).then(function() {
return self.User.min('username').then(function(min) {
expect(min).to.equal('bbb');
done();
});
});
});
it('should allow dates in min', function(done) {
it('should allow dates in min', function() {
var self = this;
this.User.bulkCreate([{theDate: new Date(2000, 1, 1)}, {theDate: new Date(1990, 1, 1)}]).success(function() {
self.User.min('theDate').success(function(min) {
return this.User.bulkCreate([{theDate: new Date(2000, 1, 1)}, {theDate: new Date(1990, 1, 1)}]).then(function() {
return self.User.min('theDate').then(function(min) {
expect(min).to.be.a('Date');
expect(new Date(1990, 1, 1)).to.equalDate(min);
done();
});
});
});
});
describe('max', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.UserWithAge = this.sequelize.define('UserWithAge', {
age: Sequelize.INTEGER,
......@@ -1751,26 +1690,24 @@ describe(Support.getTestDialectTeaser('Model'), function() {
value: Sequelize.DECIMAL(10, 3)
});
this.UserWithAge.sync({ force: true }).success(function() {
self.UserWithDec.sync({ force: true }).success(function() {
done();
});
return this.UserWithAge.sync({ force: true }).then(function() {
return self.UserWithDec.sync({ force: true });
});
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { age: Sequelize.INTEGER });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).success(function() {
User.max('age').success(function(min1) {
User.max('age', { transaction: t }).success(function(min2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.bulkCreate([{ age: 2 }, { age: 5 }, { age: 3 }], { transaction: t }).then(function() {
return User.max('age').then(function(min1) {
return User.max('age', { transaction: t }).then(function(min2) {
expect(min1).to.be.not.ok;
expect(min2).to.equal(5);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1780,71 +1717,65 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
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() {
var self = this;
this.UserWithAge.bulkCreate([{age: 2, order: 3}, {age: 3, order: 5}]).success(function() {
self.UserWithAge.max('order').success(function(max) {
return this.UserWithAge.bulkCreate([{age: 2, order: 3}, {age: 3, order: 5}]).then(function() {
return self.UserWithAge.max('order').then(function(max) {
expect(max).to.equal(5);
done();
});
});
});
it('should return the max value', function(done) {
it('should return the max value', function() {
var self = this;
self.UserWithAge.bulkCreate([{age: 2}, {age: 3}]).success(function() {
self.UserWithAge.max('age').success(function(max) {
return self.UserWithAge.bulkCreate([{age: 2}, {age: 3}]).then(function() {
return self.UserWithAge.max('age').then(function(max) {
expect(max).to.equal(3);
done();
});
});
});
it('should allow decimals in max', function(done) {
it('should allow decimals in max', function() {
var self = this;
this.UserWithDec.bulkCreate([{value: 3.5}, {value: 5.5}]).success(function() {
self.UserWithDec.max('value').success(function(max) {
return this.UserWithDec.bulkCreate([{value: 3.5}, {value: 5.5}]).then(function() {
return self.UserWithDec.max('value').then(function(max) {
expect(max).to.equal(5.5);
done();
});
});
});
it('should allow dates in max', function(done) {
it('should allow dates in max', function() {
var self = this;
this.User.bulkCreate([
return this.User.bulkCreate([
{theDate: new Date(2013, 11, 31)},
{theDate: new Date(2000, 1, 1)}
]).success(function() {
self.User.max('theDate').success(function(max) {
]).then(function() {
return self.User.max('theDate').then(function(max) {
expect(max).to.be.a('Date');
expect(max).to.equalDate(new Date(2013, 11, 31));
done();
});
});
});
it('should allow strings in max', function(done) {
it('should allow strings in max', function() {
var self = this;
this.User.bulkCreate([{username: 'aaa'}, {username: 'zzz'}]).success(function() {
self.User.max('username').success(function(max) {
return this.User.bulkCreate([{username: 'aaa'}, {username: 'zzz'}]).then(function() {
return self.User.max('username').then(function(max) {
expect(max).to.equal('zzz');
done();
});
});
});
it('allows sql logging', function(done) {
this.UserWithAge.max('age').on('sql', function(sql) {
it('allows sql logging', function() {
return this.UserWithAge.max('age').on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('SELECT')).to.be.above(-1);
done();
});
});
});
describe('sum', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.UserWithAge = this.sequelize.define('UserWithAge', {
age: Sequelize.INTEGER,
......@@ -1856,66 +1787,59 @@ describe(Support.getTestDialectTeaser('Model'), function() {
value: Sequelize.DECIMAL(10, 3)
});
this.UserWithAge.sync({ force: true }).success(function() {
self.UserWithDec.sync({ force: true }).success(function() {
done();
});
return this.UserWithAge.sync({ force: true }).then(function() {
return self.UserWithDec.sync({ force: true });
});
});
it('should return the sum of the values for a field named the same as an SQL reserved keyword', function(done) {
it('should return the sum of the values for a field named the same as an SQL reserved keyword', function() {
var self = this;
this.UserWithAge.bulkCreate([{age: 2, order: 3}, {age: 3, order: 5}]).success(function() {
self.UserWithAge.sum('order').success(function(sum) {
return this.UserWithAge.bulkCreate([{age: 2, order: 3}, {age: 3, order: 5}]).then(function() {
return self.UserWithAge.sum('order').then(function(sum) {
expect(sum).to.equal(8);
done();
});
});
});
it('should return the sum of a field in various records', function(done) {
it('should return the sum of a field in various records', function() {
var self = this;
self.UserWithAge.bulkCreate([{age: 2}, {age: 3}]).success(function() {
self.UserWithAge.sum('age').success(function(sum) {
return self.UserWithAge.bulkCreate([{age: 2}, {age: 3}]).then(function() {
return self.UserWithAge.sum('age').then(function(sum) {
expect(sum).to.equal(5);
done();
});
});
});
it('should allow decimals in sum', function(done) {
it('should allow decimals in sum', function() {
var self = this;
this.UserWithDec.bulkCreate([{value: 3.5}, {value: 5.25}]).success(function() {
self.UserWithDec.sum('value').success(function(sum) {
return this.UserWithDec.bulkCreate([{value: 3.5}, {value: 5.25}]).then(function() {
return self.UserWithDec.sum('value').then(function(sum) {
expect(sum).to.equal(8.75);
done();
});
});
});
it('should accept a where clause', function(done) {
it('should accept a where clause', function() {
var options = { where: { 'gender': 'male' }};
var self = this;
self.UserWithAge.bulkCreate([{age: 2, gender: 'male'}, {age: 3, gender: 'female'}]).success(function() {
self.UserWithAge.sum('age', options).success(function(sum) {
return self.UserWithAge.bulkCreate([{age: 2, gender: 'male'}, {age: 3, gender: 'female'}]).then(function() {
return self.UserWithAge.sum('age', options).then(function(sum) {
expect(sum).to.equal(2);
done();
});
});
});
it('allows sql logging', function(done) {
this.UserWithAge.sum('age').on('sql', function(sql) {
it('allows sql logging', function() {
return this.UserWithAge.sum('age').on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('SELECT')).to.be.above(-1);
done();
});
});
});
describe('schematic support', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.UserPublic = this.sequelize.define('UserPublic', {
......@@ -1926,12 +1850,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
age: Sequelize.INTEGER
});
self.sequelize.dropAllSchemas().success(function() {
self.sequelize.createSchema('schema_test').success(function() {
self.sequelize.createSchema('special').success(function() {
self.UserSpecial.schema('special').sync({force: true}).success(function(UserSpecialSync) {
return self.sequelize.dropAllSchemas().then(function() {
return self.sequelize.createSchema('schema_test').then(function() {
return self.sequelize.createSchema('special').then(function() {
return self.UserSpecial.schema('special').sync({force: true}).then(function(UserSpecialSync) {
self.UserSpecialSync = UserSpecialSync;
done();
});
});
});
......@@ -1942,8 +1865,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.UserSpecial.drop();
});
it('should be able to list schemas', function(done) {
this.sequelize.showAllSchemas().then(function(schemas) {
it('should be able to list schemas', function() {
return this.sequelize.showAllSchemas().then(function(schemas) {
expect(schemas).to.be.instanceof(Array);
// FIXME: reenable when schema support is properly added
......@@ -1953,23 +1876,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(schemas).to.have.length((dialect === 'postgres' ? 2 : 1));
}
done();
});
});
if (Support.dialectIsMySQL() || dialect === 'sqlite') {
it('should take schemaDelimiter into account if applicable', function(done) {
it('should take schemaDelimiter into account if applicable', function() {
var UserSpecialUnderscore = this.sequelize.define('UserSpecialUnderscore', {age: Sequelize.INTEGER}, {schema: 'hello', schemaDelimiter: '_'});
var UserSpecialDblUnderscore = this.sequelize.define('UserSpecialDblUnderscore', {age: Sequelize.INTEGER});
UserSpecialUnderscore.sync({force: true}).success(function(User) {
UserSpecialDblUnderscore.schema('hello', '__').sync({force: true}).success(function(DblUser) {
DblUser.create({age: 3}).on('sql', function(dblSql) {
User.create({age: 3}).on('sql', function(sql) {
expect(dblSql).to.exist;
expect(dblSql.indexOf('INSERT INTO `hello__UserSpecialDblUnderscores`')).to.be.above(-1);
return UserSpecialUnderscore.sync({force: true}).then(function(User) {
return UserSpecialDblUnderscore.schema('hello', '__').sync({force: true}).then(function(DblUser) {
return DblUser.create({age: 3}).on('sql', function(dblSql) {
expect(dblSql).to.exist;
expect(dblSql.indexOf('INSERT INTO `hello__UserSpecialDblUnderscores`')).to.be.above(-1);
}).then(function() {
return User.create({age: 3}).on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.indexOf('INSERT INTO `hello_UserSpecialUnderscores`')).to.be.above(-1);
done();
});
});
});
......@@ -1977,44 +1899,43 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('should describeTable using the default schema settings', function(done) {
it('should describeTable using the default schema settings', function() {
var self = this
, UserPublic = this.sequelize.define('Public', {
username: Sequelize.STRING
});
var _done = _.after(2, function() {
done();
});
})
, count = 0;
UserPublic.sync({ force: true }).success(function() {
UserPublic.schema('special').sync({ force: true }).success(function() {
self.sequelize.queryInterface.describeTable('Publics')
return UserPublic.sync({ force: true }).then(function() {
return UserPublic.schema('special').sync({ force: true }).then(function() {
return self.sequelize.queryInterface.describeTable('Publics')
.on('sql', function(sql) {
if (dialect === 'sqlite' || Support.dialectIsMySQL() || dialect === 'mssql') {
expect(sql).to.not.contain('special');
_done();
count++;
}
})
.success(function(table) {
.then(function(table) {
if (dialect === 'postgres') {
expect(table.id.defaultValue).to.not.contain('special');
_done();
count++;
}
self.sequelize.queryInterface.describeTable('Publics', 'special')
return self.sequelize.queryInterface.describeTable('Publics', 'special')
.on('sql', function(sql) {
if (dialect === 'sqlite' || Support.dialectIsMySQL() || dialect === 'mssql') {
expect(sql).to.contain('special');
_done();
count++;
}
})
.success(function(table) {
.then(function(table) {
if (dialect === 'postgres') {
expect(table.id.defaultValue).to.contain('special');
_done();
count++;
}
});
}).then(function() {
expect(count).to.equal(2);
});
});
});
......@@ -2061,38 +1982,41 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
it('should be able to create and update records under any valid schematic', function(done) {
it('should be able to create and update records under any valid schematic', function() {
var self = this;
self.UserPublic.sync({ force: true }).done(function(err, UserPublicSync) {
expect(err).not.to.be.ok;
UserPublicSync.create({age: 3}).on('sql', function(UserPublic) {
self.UserSpecialSync.schema('special').create({age: 3})
return self.UserPublic.sync({ force: true }).then(function(UserPublicSync) {
return UserPublicSync.create({age: 3}).on('sql', function(UserPublic) {
expect(UserPublic).to.exist;
if (dialect === 'postgres') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('"special"."UserSpecials"');
expect(UserPublic.indexOf('INSERT INTO "UserPublics"')).to.be.above(-1);
} else if (dialect === 'sqlite') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('`special.UserSpecials`');
expect(UserPublic.indexOf('INSERT INTO `UserPublics`')).to.be.above(-1);
} else if (dialect === 'mssql') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('[special].[UserSpecials]');
expect(UserPublic.indexOf('INSERT INTO [UserPublics]')).to.be.above(-1);
} else {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('`special.UserSpecials`');
expect(UserPublic.indexOf('INSERT INTO `UserPublics`')).to.be.above(-1);
}
})
.then(function(UserPublic) {
return self.UserSpecialSync.schema('special').create({age: 3})
.on('sql', function(UserSpecial) {
expect(UserSpecial).to.exist;
expect(UserPublic).to.exist;
if (dialect === 'postgres') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('"special"."UserSpecials"');
expect(UserSpecial.indexOf('INSERT INTO "special"."UserSpecials"')).to.be.above(-1);
expect(UserPublic.indexOf('INSERT INTO "UserPublics"')).to.be.above(-1);
} else if (dialect === 'sqlite') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('`special.UserSpecials`');
expect(UserSpecial.indexOf('INSERT INTO `special.UserSpecials`')).to.be.above(-1);
expect(UserPublic.indexOf('INSERT INTO `UserPublics`')).to.be.above(-1);
} else if (dialect === 'mssql') {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('[special].[UserSpecials]');
expect(UserSpecial.indexOf('INSERT INTO [special].[UserSpecials]')).to.be.above(-1);
expect(UserPublic.indexOf('INSERT INTO [UserPublics]')).to.be.above(-1);
} else {
expect(self.UserSpecialSync.getTableName().toString()).to.equal('`special.UserSpecials`');
expect(UserSpecial.indexOf('INSERT INTO `special.UserSpecials`')).to.be.above(-1);
expect(UserPublic.indexOf('INSERT INTO `UserPublics`')).to.be.above(-1);
}
})
.done(function(err, UserSpecial) {
expect(err).not.to.be.ok;
UserSpecial.updateAttributes({age: 5})
.then(function(UserSpecial) {
return UserSpecial.updateAttributes({age: 5})
.on('sql', function(user) {
expect(user).to.exist;
if (dialect === 'postgres') {
......@@ -2102,13 +2026,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} else {
expect(user.indexOf('UPDATE `special.UserSpecials`')).to.be.above(-1);
}
done();
}).error(function(err) {
expect(err).not.to.be.ok;
});
});
}).error(function(err) {
expect(err).not.to.be.ok;
});
});
});
......@@ -2187,7 +2106,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
})});
});
it('emits an error event as the referenced table name is invalid', function(done) {
it('emits an error event as the referenced table name is invalid', function() {
var self = this
, Post = this.sequelize.define('post', {
title: Sequelize.STRING,
......@@ -2202,15 +2121,13 @@ describe(Support.getTestDialectTeaser('Model'), function() {
Post.belongsTo(this.Author);
// The posts table gets dropped in the before filter.
Post.sync().success(function() {
return Post.sync().then(function() {
if (dialect === 'sqlite') {
// sorry ... but sqlite is too stupid to understand whats going on ...
expect(1).to.equal(1);
done();
} else {
// the parser should not end up here ...
expect(2).to.equal(1);
done();
}
return;
......@@ -2229,8 +2146,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} else {
throw new Error('Undefined dialect!');
}
done();
});
});
......@@ -2270,27 +2185,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('should return a buffer when fetching a blob', function(done) {
it('should return a buffer when fetching a blob', function() {
var self = this;
this.BlobUser.create({
return this.BlobUser.create({
data: new Buffer('Sequelize')
}).success(function(user) {
self.BlobUser.find(user.id).success(function(user) {
}).then(function(user) {
return self.BlobUser.find(user.id).then(function(user) {
expect(user.data).to.be.an.instanceOf(Buffer);
expect(user.data.toString()).to.have.string('Sequelize');
done();
});
});
});
it('should work when the database returns null', function(done) {
it('should work when the database returns null', function() {
var self = this;
this.BlobUser.create({
return this.BlobUser.create({
// create a null column
}).success(function(user) {
self.BlobUser.find(user.id).success(function(user) {
}).then(function(user) {
return self.BlobUser.find(user.id).then(function(user) {
expect(user.data).to.be.null;
done();
});
});
});
......@@ -2303,24 +2216,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
// data is passed in, in string form? Very unclear, and very different.
describe('strings', function() {
it('should be able to take a string as parameter to a BLOB field', function(done) {
this.BlobUser.create({
it('should be able to take a string as parameter to a BLOB field', function() {
return this.BlobUser.create({
data: 'Sequelize'
}).success(function(user) {
}).then(function(user) {
expect(user).to.be.ok;
done();
});
});
it('should return a buffer when fetching a BLOB, even when the BLOB was inserted as a string', function(done) {
it('should return a buffer when fetching a BLOB, even when the BLOB was inserted as a string', function() {
var self = this;
this.BlobUser.create({
return this.BlobUser.create({
data: 'Sequelize'
}).success(function(user) {
self.BlobUser.find(user.id).success(function(user) {
}).then(function(user) {
return self.BlobUser.find(user.id).then(function(user) {
expect(user.data).to.be.an.instanceOf(Buffer);
expect(user.data.toString()).to.have.string('Sequelize');
done();
});
});
});
......@@ -2331,7 +2242,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('paranoid is true and where is an array', function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {username: DataTypes.STRING }, { paranoid: true });
this.Project = this.sequelize.define('Project', { title: DataTypes.STRING }, { paranoid: true });
......@@ -2339,32 +2250,30 @@ describe(Support.getTestDialectTeaser('Model'), function() {
this.User.hasMany(this.Project);
var self = this;
this.sequelize.sync({ force: true }).success(function() {
self.User.bulkCreate([{
return this.sequelize.sync({ force: true }).then(function() {
return self.User.bulkCreate([{
username: 'leia'
}, {
username: 'luke'
}, {
username: 'vader'
}]).success(function() {
self.Project.bulkCreate([{
}]).then(function() {
return self.Project.bulkCreate([{
title: 'republic'
},{
title: 'empire'
}]).success(function() {
self.User.findAll().success(function(users) {
self.Project.findAll().success(function(projects) {
}]).then(function() {
return self.User.findAll().then(function(users) {
return self.Project.findAll().then(function(projects) {
var leia = users[0]
, luke = users[1]
, vader = users[2]
, republic = projects[0]
, empire = projects[1];
leia.setProjects([republic]).success(function() {
luke.setProjects([republic]).success(function() {
vader.setProjects([empire]).success(function() {
leia.destroy().success(function() {
done();
});
return leia.setProjects([republic]).then(function() {
return luke.setProjects([republic]).then(function() {
return vader.setProjects([empire]).then(function() {
return leia.destroy();
});
});
});
......@@ -2375,8 +2284,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('should not fail when array contains Sequelize.or / and', function(done) {
this.User.findAll({
it('should not fail when array contains Sequelize.or / and', function() {
return this.User.findAll({
where: [
this.sequelize.or({ username: 'vader' }, { username: 'luke' }),
this.sequelize.and({ id: [1, 2, 3] })
......@@ -2384,38 +2293,29 @@ describe(Support.getTestDialectTeaser('Model'), function() {
})
.then(function(res) {
expect(res).to.have.length(2);
done();
})
.catch (function(e) { done(e); });
});
});
it('should not fail with an include', function(done) {
this.User.findAll({
it('should not fail with an include', function() {
return this.User.findAll({
where: [
this.sequelize.queryInterface.QueryGenerator.quoteIdentifiers('Projects.title') + ' = ' + this.sequelize.queryInterface.QueryGenerator.escape('republic')
],
include: [
{model: this.Project}
]
}).done(function(err, users) {
expect(err).not.to.be.ok;
try {
expect(users.length).to.be.equal(1);
expect(users[0].username).to.be.equal('luke');
done();
}catch (e) {
done(e);
}
}).then(function(users) {
expect(users.length).to.be.equal(1);
expect(users[0].username).to.be.equal('luke');
});
});
it('should not overwrite a specified deletedAt by setting paranoid: false', function(done) {
it('should not overwrite a specified deletedAt by setting paranoid: false', function() {
var tableName = '';
if (this.User.name) {
tableName = this.sequelize.queryInterface.QueryGenerator.quoteIdentifier(this.User.name) + '.';
}
this.User.findAll({
return this.User.findAll({
paranoid: false,
where: [
tableName + this.sequelize.queryInterface.QueryGenerator.quoteIdentifier('deletedAt') + ' IS NOT NULL '
......@@ -2423,20 +2323,14 @@ describe(Support.getTestDialectTeaser('Model'), function() {
include: [
{model: this.Project}
]
}).success(function(users) {
try {
expect(users.length).to.be.equal(1);
expect(users[0].username).to.be.equal('leia');
done();
}catch (e) {
done(e);
}
}).error(done);
}).then(function(users) {
expect(users.length).to.be.equal(1);
expect(users[0].username).to.be.equal('leia');
});
});
it('should not overwrite a specified deletedAt (complex query) by setting paranoid: false', function(done) {
this.User.findAll({
it('should not overwrite a specified deletedAt (complex query) by setting paranoid: false', function() {
return this.User.findAll({
paranoid: false,
where: [
this.sequelize.or({ username: 'leia' }, { username: 'luke' }),
......@@ -2448,9 +2342,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
})
.then(function(res) {
expect(res).to.have.length(2);
done();
})
.catch (function(e) { done(e); });
});
});
});
......@@ -2458,7 +2350,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
if (dialect !== 'sqlite' && current.dialect.supports.transactions) {
it('supports multiple async transactions', function(done) {
this.timeout(25000);
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
var testAsync = function(i, done) {
sequelize.transaction().then(function(t) {
......@@ -2490,7 +2382,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return t.rollback();
}).nodeify(done);
};
User.sync({ force: true }).success(function() {
User.sync({ force: true }).then(function() {
var tasks = [];
for (var i = 0; i < 1000; i++) {
tasks.push(testAsync.bind(this, i));
......@@ -2560,30 +2452,32 @@ describe(Support.getTestDialectTeaser('Model'), function() {
return this.sequelize.sync({force: true});
});
});
it('should return array of errors if validate and individualHooks are true in bulkCreate', function() {
var self = this
, data = [{ username: null },
{ username: null },
{ username: null }];
describe('bulkCreate errors', function() {
it('should return array of errors if validate and individualHooks are true', function() {
var self = this
, data = [{ username: null },
{ username: null },
{ username: null }];
var user = this.sequelize.define('Users', {
username: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notNull: true,
notEmpty: true
var user = this.sequelize.define('Users', {
username: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notNull: true,
notEmpty: true
}
}
}
});
});
user.bulkCreate(data, {
validate: true,
individualHooks: true
})
.catch(function(errors) {
expect(errors).to.be.instanceof(Array);
return user.bulkCreate(data, {
validate: true,
individualHooks: true
})
.catch(function(errors) {
expect(errors).to.be.instanceof(Array);
});
});
});
\ No newline at end of file
});
});
......@@ -12,7 +12,7 @@ chai.use(datetime);
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Model'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
......@@ -22,17 +22,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
aBool: DataTypes.BOOLEAN
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
(['or', 'and']).forEach(function(method) {
var word = method.toUpperCase();
describe.skip('Sequelize.' + method, function() {
it('can handle plain strings', function(done) {
this.User.find({
it('can handle plain strings', function() {
return this.User.find({
where: Sequelize[method]('1=1', '2=2')
}).on('sql', function(sql) {
if (dialect === 'mssql') {
......@@ -40,12 +38,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}else {
expect(sql).to.contain('WHERE (1=1 ' + word + ' 2=2) LIMIT 1');
}
done();
});
});
it('can handle arrays', function(done) {
this.User.find({
it('can handle arrays', function() {
return this.User.find({
where: Sequelize[method](['1=?', 1], ['2=?', 2])
}).on('sql', function(sql) {
if (dialect === 'mssql') {
......@@ -53,12 +50,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}else {
expect(sql).to.contain('WHERE (1=1 ' + word + ' 2=2) LIMIT 1');
}
done();
});
});
it('can handle objects', function(done) {
this.User.find({
it('can handle objects', function() {
return this.User.find({
where: Sequelize[method]({ username: 'foo', intVal: 2 }, { secretValue: 'bar' })
}).on('sql', function(sql) {
var expectation = ({
......@@ -75,13 +71,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
expect(sql).to.contain(expectation);
done();
});
});
it('can handle numbers', function(done) {
this.User.find({
it('can handle numbers', function() {
return this.User.find({
where: Sequelize[method](1, 2)
}).on('sql', function(sql) {
var expectation = ({
......@@ -98,16 +92,14 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
expect(sql).to.contain(expectation);
done();
});
});
});
});
describe.skip('Combinations of Sequelize.and and Sequelize.or', function() {
it('allows nesting of Sequelize.or', function(done) {
this.User.find({
it('allows nesting of Sequelize.or', function() {
return this.User.find({
where: Sequelize.and(Sequelize.or('1=1', '2=2'), Sequelize.or('3=3', '4=4'))
}).on('sql', function(sql) {
if (dialect === 'mssql') {
......@@ -115,12 +107,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}else {
expect(sql).to.contain('WHERE ((1=1 OR 2=2) AND (3=3 OR 4=4)) LIMIT 1');
}
done();
});
});
it('allows nesting of Sequelize.or using object notation', function(done) {
this.User.find({
it('allows nesting of Sequelize.or using object notation', function() {
return this.User.find({
where: Sequelize.and(Sequelize.or({username: {eq: 'foo'}}, {username: {eq: 'bar'}}),
Sequelize.or({id: {eq: 1}}, {id: {eq: 4}}))
}).on('sql', function(sql) {
......@@ -138,12 +129,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
expect(sql).to.contain(expectation);
done();
});
});
it('allows nesting of Sequelize.and', function(done) {
this.User.find({
it('allows nesting of Sequelize.and', function() {
return this.User.find({
where: Sequelize.or(Sequelize.and('1=1', '2=2'), Sequelize.and('3=3', '4=4'))
}).on('sql', function(sql) {
if (dialect === 'mssql') {
......@@ -151,12 +141,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}else {
expect(sql).to.contain('WHERE ((1=1 AND 2=2) OR (3=3 AND 4=4)) LIMIT 1');
}
done();
});
});
it('allows nesting of Sequelize.and using object notation', function(done) {
this.User.find({
it('allows nesting of Sequelize.and using object notation', function() {
return this.User.find({
where: Sequelize.or(Sequelize.and({username: {eq: 'foo'}}, {username: {eq: 'bar'}}),
Sequelize.and({id: {eq: 1}}, {id: {eq: 4}}))
}).on('sql', function(sql) {
......@@ -174,24 +163,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
expect(sql).to.contain(expectation);
done();
});
});
if (dialect !== 'postgres') {
it('still allows simple arrays lookups', function(done) {
this.User.find({
it('still allows simple arrays lookups', function() {
return this.User.find({
where: ['id IN (?) OR id IN (?)', [1, 2], [3, 4]]
}).on('sql', function(sql) {
expect(sql).to.contain('id IN (1, 2) OR id IN (3, 4)');
done();
});
});
}
(['find', 'findAll']).forEach(function(finderMethod) {
it('correctly handles complex combinations', function(done) {
this.User[finderMethod]({
it('correctly handles complex combinations', function() {
return this.User[finderMethod]({
where: [
42, '2=2', ['1=?', 1], { username: 'foo' },
Sequelize.or(
......@@ -258,8 +245,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
')'
);
}
done();
});
});
});
......
......@@ -44,16 +44,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('findOrCreate', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
it('supports transactions', function() {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username' }, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.User.count().success(function(count) {
return this.sequelize.transaction().then(function(t) {
return self.User.findOrCreate({ where: { username: 'Username' }, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
return self.User.count().then(function(count) {
expect(count).to.equal(0);
t.commit().success(function() {
self.User.count().success(function(count) {
return t.commit().then(function() {
return self.User.count().then(function(count) {
expect(count).to.equal(1);
done();
});
});
});
......@@ -61,14 +60,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('supports more than one models per transaction', function(done) {
it('supports more than one models per transaction', function() {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.findOrCreate({ where: { username: 'Username'}, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
self.Account.findOrCreate({ where: { accountName: 'accountName'}}, { transaction: t}).then(function() {
t.commit().success(function() {
done();
});
return this.sequelize.transaction().then(function(t) {
return self.User.findOrCreate({ where: { username: 'Username'}, defaults: { data: 'some data' }}, { transaction: t }).then(function() {
return self.Account.findOrCreate({ where: { accountName: 'accountName'}}, { transaction: t}).then(function() {
return t.commit();
});
});
});
......@@ -101,7 +98,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
}).then(function () {
throw new Error('I should have been rejected');
}, function (err) {
}).catch(function (err) {
expect(err instanceof Sequelize.UniqueConstraintError).to.be.ok;
expect(err.fields).to.be.ok;
});
......@@ -235,43 +232,41 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('returns instance if already existent. Single find field.', function(done) {
it('returns instance if already existent. Single find field.', function() {
var self = this,
data = {
username: 'Username'
};
this.User.create(data).success(function(user) {
self.User.findOrCreate({ where: {
return this.User.create(data).then(function(user) {
return self.User.findOrCreate({ where: {
username: user.username
}}).spread(function(_user, created) {
expect(_user.id).to.equal(user.id);
expect(_user.username).to.equal('Username');
expect(created).to.be.false;
done();
});
});
});
it('Returns instance if already existent. Multiple find fields.', function(done) {
it('Returns instance if already existent. Multiple find fields.', function() {
var self = this,
data = {
username: 'Username',
data: 'ThisIsData'
};
this.User.create(data).success(function(user) {
self.User.findOrCreate({where: data}).done(function(err, _user, created) {
return this.User.create(data).then(function(user) {
return self.User.findOrCreate({where: data}).spread(function(_user, created) {
expect(_user.id).to.equal(user.id);
expect(_user.username).to.equal('Username');
expect(_user.data).to.equal('ThisIsData');
expect(created).to.be.false;
done();
});
});
});
it('creates new instance with default value.', function(done) {
it('creates new instance with default value.', function() {
var data = {
username: 'Username'
},
......@@ -279,25 +274,21 @@ describe(Support.getTestDialectTeaser('Model'), function() {
data: 'ThisIsData'
};
this.User.findOrCreate({ where: data, defaults: default_values}).success(function(user, created) {
return this.User.findOrCreate({ where: data, defaults: default_values}).spread(function(user, created) {
expect(user.username).to.equal('Username');
expect(user.data).to.equal('ThisIsData');
expect(created).to.be.true;
done();
});
});
it('supports .or() (only using default values)', function(done) {
this.User.findOrCreate({
it('supports .or() (only using default values)', function() {
return this.User.findOrCreate({
where: Sequelize.or({username: 'Fooobzz'}, {secretValue: 'Yolo'}),
defaults: {username: 'Fooobzz', secretValue: 'Yolo'}
}).done(function(err, user, created) {
expect(err).not.to.be.ok;
}).spread(function(user, created) {
expect(user.username).to.equal('Fooobzz');
expect(user.secretValue).to.equal('Yolo');
expect(created).to.be.true;
done();
});
});
......@@ -382,7 +373,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
}).then(function () {
throw new Error('I should have ben rejected');
}, function (err) {
}).catch(function (err) {
expect(err instanceof Sequelize.UniqueConstraintError).to.be.ok;
expect(err.fields).to.be.ok;
}),
......@@ -395,7 +386,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
}).then(function () {
throw new Error('I should have ben rejected');
}, function (err) {
}).catch(function (err) {
expect(err instanceof Sequelize.UniqueConstraintError).to.be.ok;
expect(err.fields).to.be.ok;
})
......@@ -428,7 +419,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('create', function() {
it('works with non-integer primary keys with a default value', function(done) {
it('works with non-integer primary keys with a default value', function() {
var User = this.sequelize.define('User', {
'id': {
primaryKey: true,
......@@ -441,18 +432,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
this.sequelize.sync({force: true}).done(function(err) {
expect(err).not.to.be.ok;
User.create({}).done(function(err, user) {
expect(err).not.to.be.ok;
return this.sequelize.sync({force: true}).then(function() {
return User.create({}).then(function(user) {
expect(user).to.be.ok;
expect(user.id).to.be.ok;
done();
});
});
});
it('should return an error for a unique constraint error', function(done) {
it('should return an error for a unique constraint error', function() {
var User = this.sequelize.define('User', {
'email': {
type: DataTypes.STRING,
......@@ -464,16 +452,13 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
this.sequelize.sync({force: true}).done(function(err) {
expect(err).not.to.be.ok;
User.create({email: 'hello@sequelize.com'}).done(function(err) {
expect(err).not.to.be.ok;
User.create({email: 'hello@sequelize.com'}).then(function() {
return this.sequelize.sync({force: true}).then(function() {
return User.create({email: 'hello@sequelize.com'}).then(function() {
return User.create({email: 'hello@sequelize.com'}).then(function() {
assert(false);
}, function(err) {
}).catch(function(err) {
expect(err).to.be.ok;
expect(err).to.be.an.instanceof(Error);
done();
});
});
});
......@@ -536,16 +521,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
it('supports transactions', function() {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User.create({ username: 'user' }, { transaction: t }).success(function() {
self.User.count().success(function(count) {
return this.sequelize.transaction().then(function(t) {
return self.User.create({ username: 'user' }, { transaction: t }).then(function() {
return self.User.count().then(function(count) {
expect(count).to.equal(0);
t.commit().success(function() {
self.User.count().success(function(count) {
return t.commit().then(function() {
return self.User.count().then(function(count) {
expect(count).to.equal(1);
done();
});
});
});
......@@ -587,39 +571,35 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('is possible to use casting when creating an instance', function(done) {
it('is possible to use casting when creating an instance', function() {
var self = this
, type = Support.dialectIsMySQL() ? 'signed' : 'integer'
, _done = _.after(2, function() {
done();
});
, match = false;
this.User.create({
return this.User.create({
intVal: this.sequelize.cast('1', type)
}).on('sql', function(sql) {
expect(sql).to.match(new RegExp("CAST\\('1' AS " + type.toUpperCase() + '\\)'));
_done();
match = true;
})
.success(function(user) {
self.User.find(user.id).success(function(user) {
.then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.intVal).to.equal(1);
_done();
expect(match).to.equal(true);
});
});
});
it('is possible to use casting multiple times mixed in with other utilities', function(done) {
it('is possible to use casting multiple times mixed in with other utilities', function() {
var self = this
, type = this.sequelize.cast(this.sequelize.cast(this.sequelize.literal('1-2'), 'integer'), 'integer')
, _done = _.after(2, function() {
done();
});
, match = false;
if (Support.dialectIsMySQL()) {
type = this.sequelize.cast(this.sequelize.cast(this.sequelize.literal('1-2'), 'unsigned'), 'signed');
}
this.User.create({
return this.User.create({
intVal: type
}).on('sql', function(sql) {
if (Support.dialectIsMySQL()) {
......@@ -628,36 +608,34 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(sql).to.contain('CAST(CAST(1-2 AS INTEGER) AS INTEGER)');
}
_done();
}).success(function(user) {
self.User.find(user.id).success(function(user) {
match = true;
}).then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.intVal).to.equal(-1);
_done();
expect(match).to.equal(true);
});
});
});
it('is possible to just use .literal() to bypass escaping', function(done) {
it('is possible to just use .literal() to bypass escaping', function() {
var self = this;
this.User.create({
return this.User.create({
intVal: this.sequelize.literal('CAST(1-2 AS ' + (Support.dialectIsMySQL() ? 'SIGNED' : 'INTEGER') + ')')
}).success(function(user) {
self.User.find(user.id).success(function(user) {
}).then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.intVal).to.equal(-1);
done();
});
});
});
it('is possible to use funtions when creating an instance', function(done) {
it('is possible to use funtions when creating an instance', function() {
var self = this;
this.User.create({
return this.User.create({
secretValue: this.sequelize.fn('upper', 'sequelize')
}).success(function(user) {
self.User.find(user.id).success(function(user) {
}).then(function(user) {
return self.User.find(user.id).then(function(user) {
expect(user.secretValue).to.equal('SEQUELIZE');
done();
});
});
});
......@@ -674,12 +652,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('is possible to use functions as default values', function(done) {
it('is possible to use functions as default values', function() {
var self = this
, userWithDefaults;
if (dialect.indexOf('postgres') === 0) {
this.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"').success(function() {
return this.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"').then(function() {
userWithDefaults = self.sequelize.define('userWithDefaults', {
uuid: {
type: 'UUID',
......@@ -687,11 +665,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
userWithDefaults.sync({force: true}).success(function() {
userWithDefaults.create({}).success(function(user) {
return userWithDefaults.sync({force: true}).then(function() {
return userWithDefaults.create({}).then(function(user) {
// uuid validation regex taken from http://stackoverflow.com/a/13653180/800016
expect(user.uuid).to.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i);
done();
});
});
});
......@@ -705,12 +682,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
userWithDefaults.sync({force: true}).done(function(err) {
expect(err).not.to.be.ok;
userWithDefaults.create({}).done(function(err, user) {
expect(err).not.to.be.ok;
userWithDefaults.find(user.id).done(function(err, user) {
expect(err).not.to.be.ok;
return userWithDefaults.sync({force: true}).then(function() {
return userWithDefaults.create({}).then(function(user) {
return userWithDefaults.find(user.id).then(function(user) {
var now = new Date()
, pad = function(number) {
if (number > 9) {
......@@ -720,20 +694,19 @@ describe(Support.getTestDialectTeaser('Model'), function() {
};
expect(user.year).to.equal(now.getUTCFullYear() + '-' + pad(now.getUTCMonth() + 1) + '-' + pad(now.getUTCDate()));
done();
});
});
});
} else {
// functions as default values are not supported in mysql, see http://stackoverflow.com/a/270338/800016
done();
return void(0);
}
});
it('casts empty arrays correctly for postgresql insert', function(done) {
it('casts empty arrays correctly for postgresql insert', function() {
if (dialect !== 'postgres') {
expect('').to.equal('');
return done();
return void(0);
}
var User = this.sequelize.define('UserWithArray', {
......@@ -741,19 +714,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
User.sync({force: true}).success(function() {
User.create({myvals: [], mystr: []}).on('sql', function(sql) {
return User.sync({force: true}).then(function() {
return User.create({myvals: [], mystr: []}).on('sql', function(sql) {
expect(sql.indexOf('ARRAY[]::INTEGER[]')).to.be.above(-1);
expect(sql.indexOf('ARRAY[]::VARCHAR[]')).to.be.above(-1);
done();
});
});
});
it('casts empty array correct for postgres update', function(done) {
it('casts empty array correct for postgres update', function() {
if (dialect !== 'postgres') {
expect('').to.equal('');
return done();
return void(0);
}
var User = this.sequelize.define('UserWithArray', {
......@@ -761,35 +733,34 @@ describe(Support.getTestDialectTeaser('Model'), function() {
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
});
User.sync({force: true}).success(function() {
User.create({myvals: [1, 2, 3, 4], mystr: ['One', 'Two', 'Three', 'Four']}).on('success', function(user) {
return User.sync({force: true}).then(function() {
return User.create({myvals: [1, 2, 3, 4], mystr: ['One', 'Two', 'Three', 'Four']}).then(function(user) {
user.myvals = [];
user.mystr = [];
user.save().on('sql', function(sql) {
return user.save().on('sql', function(sql) {
expect(sql.indexOf('ARRAY[]::INTEGER[]')).to.be.above(-1);
expect(sql.indexOf('ARRAY[]::VARCHAR[]')).to.be.above(-1);
done();
});
});
});
});
it("doesn't allow duplicated records with unique:true", function(done) {
it("doesn't allow duplicated records with unique:true", function() {
var self = this
, User = this.sequelize.define('UserWithUniqueUsername', {
username: { type: Sequelize.STRING, unique: true }
});
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function() {
User.create({ username: 'foo' }).catch (self.sequelize.UniqueConstraintError, function(err) {
done();
return User.sync({ force: true }).then(function() {
return User.create({ username: 'foo' }).then(function() {
return User.create({ username: 'foo' }).catch(self.sequelize.UniqueConstraintError, function(err) {
expect(err).to.be.ok;
});
});
});
});
it('raises an error if created object breaks definition contraints', function(done) {
it('raises an error if created object breaks definition contraints', function() {
var UserNull = this.sequelize.define('UserWithNonNullSmth', {
username: { type: Sequelize.STRING, unique: true },
smth: { type: Sequelize.STRING, allowNull: false }
......@@ -797,10 +768,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
this.sequelize.options.omitNull = false;
UserNull.sync({ force: true }).success(function() {
UserNull.create({ username: 'foo2', smth: null }).error(function(err) {
return UserNull.sync({ force: true }).then(function() {
return UserNull.create({ username: 'foo2', smth: null }).catch(function(err) {
expect(err).to.exist;
expect(err.get('smth')[0].path).to.equal('smth');
if (Support.dialectIsMySQL()) {
// We need to allow two different errors for MySQL, see:
......@@ -812,11 +782,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} else {
expect(err.get('smth')[0].type).to.match(/notNull Violation/);
}
done();
});
});
});
it('raises an error if created object breaks definition contraints', function(done) {
it('raises an error if created object breaks definition contraints', function() {
var self = this
, UserNull = this.sequelize.define('UserWithNonNullSmth', {
username: { type: Sequelize.STRING, unique: true },
......@@ -825,39 +794,37 @@ describe(Support.getTestDialectTeaser('Model'), function() {
this.sequelize.options.omitNull = false;
UserNull.sync({ force: true }).success(function() {
UserNull.create({ username: 'foo', smth: 'foo' }).success(function() {
UserNull.create({ username: 'foo', smth: 'bar' }).catch (self.sequelize.UniqueConstraintError, function(err) {
done();
return UserNull.sync({ force: true }).then(function() {
return UserNull.create({ username: 'foo', smth: 'foo' }).then(function() {
return UserNull.create({ username: 'foo', smth: 'bar' }).catch (self.sequelize.UniqueConstraintError, function(err) {
expect(err).to.be.ok;
});
});
});
});
it('raises an error if saving an empty string into a column allowing null or URL', function(done) {
it('raises an error if saving an empty string into a column allowing null or URL', function() {
var StringIsNullOrUrl = this.sequelize.define('StringIsNullOrUrl', {
str: { type: Sequelize.STRING, allowNull: true, validate: { isURL: true } }
});
this.sequelize.options.omitNull = false;
StringIsNullOrUrl.sync({ force: true }).success(function() {
StringIsNullOrUrl.create({ str: null }).success(function(str1) {
return StringIsNullOrUrl.sync({ force: true }).then(function() {
return StringIsNullOrUrl.create({ str: null }).then(function(str1) {
expect(str1.str).to.be.null;
StringIsNullOrUrl.create({ str: 'http://sequelizejs.org' }).success(function(str2) {
return StringIsNullOrUrl.create({ str: 'http://sequelizejs.org' }).then(function(str2) {
expect(str2.str).to.equal('http://sequelizejs.org');
StringIsNullOrUrl.create({ str: '' }).error(function(err) {
return StringIsNullOrUrl.create({ str: '' }).catch(function(err) {
expect(err).to.exist;
expect(err.get('str')[0].message).to.match(/Validation isURL failed/);
done();
});
});
}).error(done);
});
});
});
it('raises an error if you mess up the datatype', function(done) {
it('raises an error if you mess up the datatype', function() {
var self = this;
expect(function() {
self.sequelize.define('UserBadDataType', {
......@@ -870,40 +837,36 @@ describe(Support.getTestDialectTeaser('Model'), function() {
activity_date: {type: Sequelize.DATe}
});
}).to.throw(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() {
var User = this.sequelize.define('UserWithBigIntFields', {
big: Sequelize.BIGINT
});
User.sync({ force: true }).success(function() {
User.create({ big: '9223372036854775807' }).on('success', function(user) {
return User.sync({ force: true }).then(function() {
return User.create({ big: '9223372036854775807' }).then(function(user) {
expect(user.big).to.be.equal('9223372036854775807');
done();
});
});
});
it('sets auto increment fields', function(done) {
it('sets auto increment fields', function() {
var User = this.sequelize.define('UserWithAutoIncrementField', {
userid: { type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true, allowNull: false }
});
User.sync({ force: true }).success(function() {
User.create({}).on('success', function(user) {
return User.sync({ force: true }).then(function() {
return User.create({}).then(function(user) {
expect(user.userid).to.equal(1);
User.create({}).on('success', function(user) {
return User.create({}).then(function(user) {
expect(user.userid).to.equal(2);
done();
});
});
});
});
it('allows the usage of options as attribute', function(done) {
it('allows the usage of options as attribute', function() {
var User = this.sequelize.define('UserWithNameAndOptions', {
name: Sequelize.STRING,
options: Sequelize.TEXT
......@@ -911,56 +874,52 @@ describe(Support.getTestDialectTeaser('Model'), function() {
var options = JSON.stringify({ foo: 'bar', bar: 'foo' });
User.sync({ force: true }).success(function() {
User
return User.sync({ force: true }).then(function() {
return User
.create({ name: 'John Doe', options: options })
.success(function(user) {
.then(function(user) {
expect(user.options).to.equal(options);
done();
});
});
});
it('allows sql logging', function(done) {
it('allows sql logging', function() {
var User = this.sequelize.define('UserWithUniqueNameAndNonNullSmth', {
name: {type: Sequelize.STRING, unique: true},
smth: {type: Sequelize.STRING, allowNull: false}
});
User.sync({ force: true }).success(function() {
User
return User.sync({ force: true }).then(function() {
return User
.create({ name: 'Fluffy Bunny', smth: 'else' })
.on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('INSERT')).to.be.above(-1);
done();
});
});
});
it('should only store the values passed in the whitelist', function(done) {
it('should only store the values passed in the whitelist', function() {
var self = this
, data = { username: 'Peter', secretValue: '42' };
this.User.create(data, { fields: ['username'] }).success(function(user) {
self.User.find(user.id).success(function(_user) {
return this.User.create(data, { fields: ['username'] }).then(function(user) {
return self.User.find(user.id).then(function(_user) {
expect(_user.username).to.equal(data.username);
expect(_user.secretValue).not.to.equal(data.secretValue);
expect(_user.secretValue).to.equal(null);
done();
});
});
});
it('should store all values if no whitelist is specified', function(done) {
it('should store all values if no whitelist is specified', function() {
var self = this
, data = { username: 'Peter', secretValue: '42' };
this.User.create(data).success(function(user) {
self.User.find(user.id).success(function(_user) {
return this.User.create(data).then(function(user) {
return self.User.find(user.id).then(function(_user) {
expect(_user.username).to.equal(data.username);
expect(_user.secretValue).to.equal(data.secretValue);
done();
});
});
});
......@@ -984,11 +943,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
chain.add(b.sync({ force: true }));
});
chain.run().success(function() {
chain.run().then(function() {
books.forEach(function(b) {
chain2.add(b.create(data));
});
chain2.run().success(function(results) {
chain2.run().then(function(results) {
results.forEach(function(book, index) {
expect(book.title).to.equal(data.title);
expect(book.author).to.equal(data.author);
......@@ -999,89 +958,77 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('saves data with single quote', function(done) {
it('saves data with single quote', function() {
var quote = "single'quote"
, self = this;
this.User.create({ data: quote }).success(function(user) {
return this.User.create({ data: quote }).then(function(user) {
expect(user.data).to.equal(quote);
self.User.find({where: { id: user.id }}).success(function(user) {
return self.User.find({where: { id: user.id }}).then(function(user) {
expect(user.data).to.equal(quote);
done();
});
});
});
it('saves data with double quote', function(done) {
it('saves data with double quote', function() {
var quote = 'double"quote'
, self = this;
this.User.create({ data: quote }).success(function(user) {
return this.User.create({ data: quote }).then(function(user) {
expect(user.data).to.equal(quote);
self.User.find({where: { id: user.id }}).success(function(user) {
return self.User.find({where: { id: user.id }}).then(function(user) {
expect(user.data).to.equal(quote);
done();
});
});
});
it('saves stringified JSON data', function(done) {
it('saves stringified JSON data', function() {
var json = JSON.stringify({ key: 'value' })
, self = this;
this.User.create({ data: json }).success(function(user) {
return this.User.create({ data: json }).then(function(user) {
expect(user.data).to.equal(json);
self.User.find({where: { id: user.id }}).success(function(user) {
return self.User.find({where: { id: user.id }}).then(function(user) {
expect(user.data).to.equal(json);
done();
});
});
});
it('stores the current date in createdAt', function(done) {
this.User.create({ username: 'foo' }).success(function(user) {
it('stores the current date in createdAt', function() {
return this.User.create({ username: 'foo' }).then(function(user) {
expect(parseInt(+user.createdAt / 5000, 10)).to.be.closeTo(parseInt(+new Date() / 5000, 10), 1.5);
done();
});
});
it('allows setting custom IDs', function(done) {
it('allows setting custom IDs', function() {
var self = this;
this.User.create({ id: 42 }).success(function(user) {
return this.User.create({ id: 42 }).then(function(user) {
expect(user.id).to.equal(42);
self.User.find(42).success(function(user) {
return self.User.find(42).then(function(user) {
expect(user).to.exist;
done();
});
});
});
it('should allow blank creates (with timestamps: false)', function(done) {
it('should allow blank creates (with timestamps: false)', function() {
var Worker = this.sequelize.define('Worker', {}, {timestamps: false});
Worker.sync().done(function() {
Worker.create({}, {fields: []}).done(function(err, worker) {
expect(err).not.to.be.ok;
return Worker.sync().then(function() {
return Worker.create({}, {fields: []}).then(function(worker) {
expect(worker).to.be.ok;
done();
});
});
});
it('should allow truly blank creates', function(done) {
it('should allow truly blank creates', function() {
var Worker = this.sequelize.define('Worker', {}, {timestamps: false});
Worker.sync().done(function() {
Worker.create({}, {fields: []}).done(function(err, worker) {
expect(err).not.to.be.ok;
return Worker.sync().then(function() {
return Worker.create({}, {fields: []}).then(function(worker) {
expect(worker).to.be.ok;
done();
});
});
});
it('should only set passed fields', function(done) {
it('should only set passed fields', function() {
var User = this.sequelize.define('User', {
'email': {
type: DataTypes.STRING
......@@ -1091,47 +1038,40 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
this.sequelize.sync({force: true}).done(function(err) {
expect(err).not.to.be.ok;
User.create({
return this.sequelize.sync({force: true}).then(function() {
return User.create({
name: 'Yolo Bear',
email: 'yolo@bear.com'
}, {
fields: ['name']
}).done(function(err, user) {
expect(err).not.to.be.ok;
}).then(function(user) {
expect(user.name).to.be.ok;
expect(user.email).not.to.be.ok;
User.find(user.id).done(function(err, user) {
expect(err).not.to.be.ok;
return User.find(user.id).then(function(user) {
expect(user.name).to.be.ok;
expect(user.email).not.to.be.ok;
done();
});
});
});
});
describe('enums', function() {
it('correctly restores enum values', function(done) {
it('correctly restores enum values', function() {
var self = this
, Item = self.sequelize.define('Item', {
state: { type: Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] }
});
Item.sync({ force: true }).success(function() {
Item.create({ state: 'available' }).success(function(_item) {
Item.find({ where: { state: 'available' }}).success(function(item) {
return Item.sync({ force: true }).then(function() {
return Item.create({ state: 'available' }).then(function(_item) {
return Item.find({ where: { state: 'available' }}).then(function(item) {
expect(item.id).to.equal(_item.id);
done();
});
});
});
});
it('allows null values', function(done) {
it('allows null values', function() {
var Enum = this.sequelize.define('Enum', {
state: {
type: Sequelize.ENUM,
......@@ -1140,72 +1080,63 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
Enum.sync({ force: true }).success(function() {
Enum.create({state: null}).success(function(_enum) {
return Enum.sync({ force: true }).then(function() {
return Enum.create({state: null}).then(function(_enum) {
expect(_enum.state).to.be.null;
done();
});
});
});
describe('when defined via { field: Sequelize.ENUM }', function() {
it('allows values passed as parameters', function(done) {
it('allows values passed as parameters', function() {
var Enum = this.sequelize.define('Enum', {
state: Sequelize.ENUM('happy', 'sad')
});
Enum.sync({ force: true }).success(function() {
Enum.create({ state: 'happy' }).success(function() {
done();
});
return Enum.sync({ force: true }).then(function() {
return Enum.create({ state: 'happy' });
});
});
it('allows values passed as an array', function(done) {
it('allows values passed as an array', function() {
var Enum = this.sequelize.define('Enum', {
state: Sequelize.ENUM(['happy', 'sad'])
});
Enum.sync({ force: true }).success(function() {
Enum.create({ state: 'happy' }).success(function() {
done();
});
return Enum.sync({ force: true }).then(function() {
return Enum.create({ state: 'happy' });
});
});
});
describe('when defined via { field: { type: Sequelize.ENUM } }', function() {
it('allows values passed as parameters', function(done) {
it('allows values passed as parameters', function() {
var Enum = this.sequelize.define('Enum', {
state: {
type: Sequelize.ENUM('happy', 'sad')
}
});
Enum.sync({ force: true }).success(function() {
Enum.create({ state: 'happy' }).success(function() {
done();
});
return Enum.sync({ force: true }).then(function() {
return Enum.create({ state: 'happy' });
});
});
it('allows values passed as an array', function(done) {
it('allows values passed as an array', function() {
var Enum = this.sequelize.define('Enum', {
state: {
type: Sequelize.ENUM(['happy', 'sad'])
}
});
Enum.sync({ force: true }).success(function() {
Enum.create({ state: 'happy' }).success(function() {
done();
});
return Enum.sync({ force: true }).then(function() {
return Enum.create({ state: 'happy' });
});
});
});
describe('can safely sync multiple times', function() {
it('through the factory', function(done) {
it('through the factory', function() {
var Enum = this.sequelize.define('Enum', {
state: {
type: Sequelize.ENUM,
......@@ -1214,14 +1145,14 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
Enum.sync({ force: true }).success(function() {
Enum.sync().success(function() {
Enum.sync({ force: true }).complete(done);
return Enum.sync({ force: true }).then(function() {
return Enum.sync().then(function() {
return Enum.sync({ force: true });
});
});
});
it('through sequelize', function(done) {
it('through sequelize', function() {
var self = this
, Enum = this.sequelize.define('Enum', {
state: {
......@@ -1231,9 +1162,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
this.sequelize.sync({ force: true }).success(function() {
self.sequelize.sync().success(function() {
self.sequelize.sync({ force: true }).complete(done);
return this.sequelize.sync({ force: true }).then(function() {
return self.sequelize.sync().then(function() {
return self.sequelize.sync({ force: true });
});
});
});
......@@ -1243,17 +1174,17 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('bulkCreate', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
it('supports transactions', function() {
var self = this;
this.sequelize.transaction().then(function(t) {
self.User
return this.sequelize.transaction().then(function(t) {
return self.User
.bulkCreate([{ username: 'foo' }, { username: 'bar' }], { transaction: t })
.success(function() {
self.User.count().success(function(count1) {
self.User.count({ transaction: t }).success(function(count2) {
.then(function() {
return self.User.count().then(function(count1) {
return self.User.count({ transaction: t }).then(function(count2) {
expect(count1).to.equal(0);
expect(count2).to.equal(2);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1307,140 +1238,131 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('properly handles disparate field lists', function(done) {
it('properly handles disparate field lists', function() {
var self = this
, data = [{username: 'Peter', secretValue: '42', uniqueName: '1' },
{username: 'Paul', uniqueName: '2'},
{username: 'Steve', uniqueName: '3'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({where: {username: 'Paul'}}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({where: {username: 'Paul'}}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].username).to.equal('Paul');
expect(users[0].secretValue).to.be.null;
done();
});
});
});
it('inserts multiple values respecting the white list', function(done) {
it('inserts multiple values respecting the white list', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42', uniqueName: '1' },
{ username: 'Paul', secretValue: '23', uniqueName: '2'}];
this.User.bulkCreate(data, { fields: ['username', 'uniqueName'] }).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data, { fields: ['username', 'uniqueName'] }).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(users[0].secretValue).to.be.null;
expect(users[1].username).to.equal('Paul');
expect(users[1].secretValue).to.be.null;
done();
});
});
});
it('should store all values if no whitelist is specified', function(done) {
it('should store all values if no whitelist is specified', function() {
var self = this
, data = [{ username: 'Peter', secretValue: '42', uniqueName: '1' },
{ username: 'Paul', secretValue: '23', uniqueName: '2'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(users[0].secretValue).to.equal('42');
expect(users[1].username).to.equal('Paul');
expect(users[1].secretValue).to.equal('23');
done();
});
});
});
it('saves data with single quote', function(done) {
it('saves data with single quote', function() {
var self = this
, quote = "Single'Quote"
, data = [{ username: 'Peter', data: quote, uniqueName: '1'},
{ username: 'Paul', data: quote, uniqueName: '2'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(users[0].data).to.equal(quote);
expect(users[1].username).to.equal('Paul');
expect(users[1].data).to.equal(quote);
done();
});
});
});
it('saves data with double quote', function(done) {
it('saves data with double quote', function() {
var self = this
, quote = 'Double"Quote'
, data = [{ username: 'Peter', data: quote, uniqueName: '1'},
{ username: 'Paul', data: quote, uniqueName: '2'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(users[0].data).to.equal(quote);
expect(users[1].username).to.equal('Paul');
expect(users[1].data).to.equal(quote);
done();
});
});
});
it('saves stringified JSON data', function(done) {
it('saves stringified JSON data', function() {
var self = this
, json = JSON.stringify({ key: 'value' })
, data = [{ username: 'Peter', data: json, uniqueName: '1'},
{ username: 'Paul', data: json, uniqueName: '2'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(users[0].data).to.equal(json);
expect(users[1].username).to.equal('Paul');
expect(users[1].data).to.equal(json);
done();
});
});
});
it('properly handles a model with a length column', function(done) {
it('properly handles a model with a length column', function() {
var UserWithLength = this.sequelize.define('UserWithLength', {
length: Sequelize.INTEGER
});
UserWithLength.sync({force: true}).success(function() {
UserWithLength.bulkCreate([{ length: 42}, {length: 11}]).success(function() {
done();
});
return UserWithLength.sync({force: true}).then(function() {
return UserWithLength.bulkCreate([{ length: 42}, {length: 11}]);
});
});
it('stores the current date in createdAt', function(done) {
it('stores the current date in createdAt', function() {
var self = this
, data = [{ username: 'Peter', uniqueName: '1'},
{ username: 'Paul', uniqueName: '2'}];
this.User.bulkCreate(data).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return this.User.bulkCreate(data).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].username).to.equal('Peter');
expect(parseInt(+users[0].createdAt / 5000, 10)).to.be.closeTo(parseInt(+new Date() / 5000, 10), 1.5);
expect(users[1].username).to.equal('Paul');
expect(parseInt(+users[1].createdAt / 5000, 10)).to.be.closeTo(parseInt(+new Date() / 5000, 10), 1.5);
done();
});
});
});
it('emits an error when validate is set to true', function(done) {
it('emits an error when validate is set to true', function() {
var Tasks = this.sequelize.define('Task', {
name: {
type: Sequelize.STRING,
......@@ -1454,12 +1376,12 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
Tasks.sync({ force: true }).success(function() {
Tasks.bulkCreate([
return Tasks.sync({ force: true }).then(function() {
return Tasks.bulkCreate([
{name: 'foo', code: '123'},
{code: '1234'},
{name: 'bar', code: '1'}
], { validate: true }).error(function(errors) {
], { validate: true }).catch(function(errors) {
expect(errors).to.not.be.null;
expect(errors).to.be.an('Array');
expect(errors).to.have.length(2);
......@@ -1468,12 +1390,11 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(errors[1].record.name).to.equal('bar');
expect(errors[1].record.code).to.equal('1');
expect(errors[1].errors.get('code')[0].message).to.equal('Validation len failed');
done();
});
});
});
it("doesn't emit an error when validate is set to true but our selectedValues are fine", function(done) {
it("doesn't emit an error when validate is set to true but our selectedValues are fine", function() {
var Tasks = this.sequelize.define('Task', {
name: {
type: Sequelize.STRING,
......@@ -1489,52 +1410,43 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
Tasks.sync({ force: true }).success(function() {
Tasks.bulkCreate([
return Tasks.sync({ force: true }).then(function() {
return Tasks.bulkCreate([
{name: 'foo', code: '123'},
{code: '1234'}
], { fields: ['code'], validate: true }).success(function() {
// we passed!
done();
});
], { fields: ['code'], validate: true });
});
});
it('should allow blank arrays (return immediatly)', function(done) {
it('should allow blank arrays (return immediatly)', function() {
var Worker = this.sequelize.define('Worker', {});
Worker.sync().done(function() {
Worker.bulkCreate([]).done(function(err, workers) {
expect(err).not.to.be.ok;
return Worker.sync().then(function() {
return Worker.bulkCreate([]).then(function(workers) {
expect(workers).to.be.ok;
expect(workers.length).to.equal(0);
done();
});
});
});
it('should allow blank creates (with timestamps: false)', function(done) {
it('should allow blank creates (with timestamps: false)', function() {
var Worker = this.sequelize.define('Worker', {}, {timestamps: false});
Worker.sync().done(function() {
Worker.bulkCreate([{}, {}]).done(function(err, workers) {
expect(err).not.to.be.ok;
return Worker.sync().then(function() {
return Worker.bulkCreate([{}, {}]).then(function(workers) {
expect(workers).to.be.ok;
done();
});
});
});
it('should allow autoincremented attributes to be set', function(done) {
it('should allow autoincremented attributes to be set', function() {
var Worker = this.sequelize.define('Worker', {}, {timestamps: false});
Worker.sync().done(function() {
Worker.bulkCreate([
return Worker.sync().then(function() {
return Worker.bulkCreate([
{id: 5},
{id: 10}
]).done(function(err) {
expect(err).not.to.be.ok;
Worker.findAll({order: 'id ASC'}).done(function(err, workers) {
]).then(function() {
return Worker.findAll({order: 'id ASC'}).then(function(workers) {
expect(workers[0].id).to.equal(5);
expect(workers[1].id).to.equal(10);
done();
});
});
});
......@@ -1563,15 +1475,15 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
if (dialect !== 'postgres' && dialect !== 'mssql') {
it('should support the ignoreDuplicates option', function(done) {
it('should support the ignoreDuplicates option', function() {
var self = this
, data = [{ uniqueName: 'Peter', secretValue: '42' },
{ uniqueName: 'Paul', secretValue: '23' }];
this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'] }).success(function() {
return this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'] }).then(function() {
data.push({ uniqueName: 'Michael', secretValue: '26' });
self.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], ignoreDuplicates: true }).success(function() {
self.User.findAll({order: 'id'}).success(function(users) {
return self.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], ignoreDuplicates: true }).then(function() {
return self.User.findAll({order: 'id'}).then(function(users) {
expect(users.length).to.equal(3);
expect(users[0].uniqueName).to.equal('Peter');
expect(users[0].secretValue).to.equal('42');
......@@ -1579,21 +1491,20 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(users[1].secretValue).to.equal('23');
expect(users[2].uniqueName).to.equal('Michael');
expect(users[2].secretValue).to.equal('26');
done();
});
});
});
});
} else {
it('should throw an error when the ignoreDuplicates option is passed', function(done) {
it('should throw an error when the ignoreDuplicates option is passed', function() {
var self = this
, data = [{ uniqueName: 'Peter', secretValue: '42' },
{ uniqueName: 'Paul', secretValue: '23' }];
this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'] }).success(function() {
return this.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'] }).then(function() {
data.push({ uniqueName: 'Michael', secretValue: '26' });
self.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], ignoreDuplicates: true }).error(function(err) {
return self.User.bulkCreate(data, { fields: ['uniqueName', 'secretValue'], ignoreDuplicates: true }).catch(function(err) {
expect(err).to.exist;
if (dialect === 'mssql') {
console.log(err.message);
......@@ -1601,8 +1512,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
} else {
expect(err.message).to.match(/postgres does not support the \'ignoreDuplicates\' option./);
}
done();
});
});
});
......@@ -1656,18 +1565,17 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
describe('enums', function() {
it('correctly restores enum values', function(done) {
it('correctly restores enum values', function() {
var self = this
, Item = self.sequelize.define('Item', {
state: { type: Sequelize.ENUM, values: ['available', 'in_cart', 'shipped'] },
name: Sequelize.STRING
});
Item.sync({ force: true }).success(function() {
Item.bulkCreate([{state: 'in_cart', name: 'A'}, { state: 'available', name: 'B'}]).success(function() {
Item.find({ where: { state: 'available' }}).success(function(item) {
return Item.sync({ force: true }).then(function() {
return Item.bulkCreate([{state: 'in_cart', name: 'A'}, { state: 'available', name: 'B'}]).then(function() {
return Item.find({ where: { state: 'available' }}).then(function(item) {
expect(item.name).to.equal('B');
done();
});
});
});
......
......@@ -19,7 +19,7 @@ chai.use(datetime);
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Model'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
......@@ -29,32 +29,27 @@ describe(Support.getTestDialectTeaser('Model'), function() {
aBool: DataTypes.BOOLEAN
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
describe('find', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.find({
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.find({
where: { username: 'foo' }
}).success(function(user1) {
User.find({
}).then(function(user1) {
return User.find({
where: { username: 'foo' }
}, { transaction: t }).success(function(user2) {
}, { transaction: t }).then(function(user2) {
expect(user1).to.be.null;
expect(user2).to.not.be.null;
t.rollback().success(function() {
done();
});
return t.rollback();
});
});
});
......@@ -65,9 +60,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
describe('general / basic function', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User.create({username: 'barfooz'}).success(function(user) {
return this.User.create({username: 'barfooz'}).then(function(user) {
self.UserPrimary = self.sequelize.define('UserPrimary', {
specialkey: {
type: DataTypes.STRING,
......@@ -75,10 +70,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
});
self.UserPrimary.sync({force: true}).success(function() {
self.UserPrimary.create({specialkey: 'a string'}).success(function() {
return self.UserPrimary.sync({force: true}).then(function() {
return self.UserPrimary.create({specialkey: 'a string'}).then(function() {
self.user = user;
done();
});
});
});
......@@ -118,159 +112,144 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('does not modify the passed arguments', function(done) {
it('does not modify the passed arguments', function() {
var options = { where: ['specialkey = ?', 'awesome']};
this.UserPrimary.find(options).success(function() {
return this.UserPrimary.find(options).then(function() {
expect(options).to.deep.equal({ where: ['specialkey = ?', 'awesome']});
done();
});
});
it('treats questionmarks in an array', function(done) {
this.UserPrimary.find({
it('treats questionmarks in an array', function() {
return this.UserPrimary.find({
where: ['specialkey = ?', 'awesome']
}).on('sql', function(sql) {
expect(sql).to.contain("WHERE specialkey = 'awesome'");
done();
});
});
it('doesn\'t throw an error when entering in a non integer value for a specified primary field', function(done) {
this.UserPrimary.find('a string').success(function(user) {
it('doesn\'t throw an error when entering in a non integer value for a specified primary field', function() {
return this.UserPrimary.find('a string').then(function(user) {
expect(user.specialkey).to.equal('a string');
done();
});
});
it.skip('doesn\'t throw an error when entering in a non integer value', function(done) {
this.User.find('a string value').success(function(user) {
it.skip('doesn\'t throw an error when entering in a non integer value', function() {
return this.User.find('a string value').then(function(user) {
expect(user).to.be.null;
done();
});
});
it('returns a single dao', function(done) {
it('returns a single dao', function() {
var self = this;
this.User.find(this.user.id).success(function(user) {
return this.User.find(this.user.id).then(function(user) {
expect(Array.isArray(user)).to.not.be.ok;
expect(user.id).to.equal(self.user.id);
expect(user.id).to.equal(1);
done();
});
});
it('returns a single dao given a string id', function(done) {
it('returns a single dao given a string id', function() {
var self = this;
this.User.find(this.user.id + '').success(function(user) {
return this.User.find(this.user.id + '').then(function(user) {
expect(Array.isArray(user)).to.not.be.ok;
expect(user.id).to.equal(self.user.id);
expect(user.id).to.equal(1);
done();
});
});
it('should make aliased attributes available', function(done) {
this.User.find({
it('should make aliased attributes available', function() {
return this.User.find({
where: { id: 1 },
attributes: ['id', ['username', 'name']]
}).success(function(user) {
}).then(function(user) {
expect(user.dataValues.name).to.equal('barfooz');
done();
});
});
it('should not try to convert boolean values if they are not selected', function(done) {
it('should not try to convert boolean values if they are not selected', function() {
var UserWithBoolean = this.sequelize.define('UserBoolean', {
active: Sequelize.BOOLEAN
});
UserWithBoolean.sync({force: true}).success(function() {
UserWithBoolean.create({ active: true }).success(function(user) {
UserWithBoolean.find({ where: { id: user.id }, attributes: ['id'] }).success(function(user) {
return UserWithBoolean.sync({force: true}).then(function() {
return UserWithBoolean.create({ active: true }).then(function(user) {
return UserWithBoolean.find({ where: { id: user.id }, attributes: ['id'] }).then(function(user) {
expect(user.active).not.to.exist;
done();
});
});
});
});
it('finds a specific user via where option', function(done) {
this.User.find({ where: { username: 'barfooz' } }).success(function(user) {
it('finds a specific user via where option', function() {
return this.User.find({ where: { username: 'barfooz' } }).then(function(user) {
expect(user.username).to.equal('barfooz');
done();
});
});
it("doesn't find a user if conditions are not matching", function(done) {
this.User.find({ where: { username: 'foo' } }).success(function(user) {
it("doesn't find a user if conditions are not matching", function() {
return this.User.find({ where: { username: 'foo' } }).then(function(user) {
expect(user).to.be.null;
done();
});
});
it('allows sql logging', function(done) {
this.User.find({ where: { username: 'foo' } }).on('sql', function(sql) {
it('allows sql logging', function() {
return this.User.find({ where: { username: 'foo' } }).on('sql', function(sql) {
expect(sql).to.exist;
expect(sql.toUpperCase().indexOf('SELECT')).to.be.above(-1);
done();
});
});
it('ignores passed limit option', function(done) {
this.User.find({ limit: 10 }).success(function(user) {
it('ignores passed limit option', function() {
return this.User.find({ limit: 10 }).then(function(user) {
// it returns an object instead of an array
expect(Array.isArray(user)).to.not.be.ok;
expect(user.dataValues.hasOwnProperty('username')).to.be.ok;
done();
});
});
it('finds entries via primary keys', function(done) {
it('finds entries via primary keys', function() {
var self = this
, UserPrimary = self.sequelize.define('UserWithPrimaryKey', {
identifier: {type: Sequelize.STRING, primaryKey: true},
name: Sequelize.STRING
});
UserPrimary.sync({ force: true }).success(function() {
UserPrimary.create({
return UserPrimary.sync({ force: true }).then(function() {
return UserPrimary.create({
identifier: 'an identifier',
name: 'John'
}).success(function(u) {
}).then(function(u) {
expect(u.id).not.to.exist;
UserPrimary.find('an identifier').success(function(u2) {
return UserPrimary.find('an identifier').then(function(u2) {
expect(u2.identifier).to.equal('an identifier');
expect(u2.name).to.equal('John');
done();
});
});
});
});
it('finds entries via a string primary key called id', function(done) {
it('finds entries via a string primary key called id', function() {
var self = this
, UserPrimary = self.sequelize.define('UserWithPrimaryKey', {
id: {type: Sequelize.STRING, primaryKey: true},
name: Sequelize.STRING
});
UserPrimary.sync({ force: true }).success(function() {
UserPrimary.create({
return UserPrimary.sync({ force: true }).then(function() {
return UserPrimary.create({
id: 'a string based id',
name: 'Johnno'
}).success(function() {
UserPrimary.find('a string based id').success(function(u2) {
}).then(function() {
return UserPrimary.find('a string based id').then(function(u2) {
expect(u2.id).to.equal('a string based id');
expect(u2.name).to.equal('Johnno');
done();
});
});
});
});
it('always honors ZERO as primary key', function(_done) {
it('always honors ZERO as primary key', function() {
var self = this
, permutations = [
0,
......@@ -278,34 +257,34 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{where: {id: 0}},
{where: {id: '0'}}
]
, done = _.after(2 * permutations.length, _done);
, count = 0;
this.User.bulkCreate([{username: 'jack'}, {username: 'jack'}]).success(function() {
permutations.forEach(function(perm) {
self.User.find(perm).done(function(err, user) {
expect(err).to.be.null;
return this.User.bulkCreate([{username: 'jack'}, {username: 'jack'}]).then(function() {
return self.sequelize.Promise.map(permutations, function(perm) {
return self.User.find(perm).then(function(user) {
expect(user).to.be.null;
done();
count++;
}).on('sql', function(s) {
expect(s.indexOf(0)).not.to.equal(-1);
done();
count++;
});
});
}).then(function() {
expect(count).to.be.equal(2 * permutations.length);
});
});
it('should allow us to find IDs using capital letters', function(done) {
it('should allow us to find IDs using capital letters', function() {
var User = this.sequelize.define('User' + config.rand(), {
ID: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
Login: { type: Sequelize.STRING }
});
User.sync({ force: true }).success(function() {
User.create({Login: 'foo'}).success(function() {
User.find(1).success(function(user) {
return User.sync({ force: true }).then(function() {
return User.create({Login: 'foo'}).then(function() {
return User.find(1).then(function(user) {
expect(user).to.exist;
expect(user.ID).to.equal(1);
done();
});
});
});
......@@ -313,91 +292,84 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('eager loading', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('Task', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('Worker', { name: Sequelize.STRING });
this.init = function(callback) {
self.sequelize.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.sequelize.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
callback();
return callback();
});
});
});
};
done();
});
describe('belongsTo', function() {
describe('generic', function() {
it('throws an error about unexpected input if include contains a non-object', function(done) {
it('throws an error about unexpected input if include contains a non-object', function() {
var self = this;
self.Worker.find({ include: [1] }).catch (function(err) {
return self.Worker.find({ include: [1] }).catch (function(err) {
expect(err.message).to.equal('Include unexpected. Element has to be either a Model, an Association or an object.');
done();
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Worker.find({ include: [self.Task] }).catch (function(err) {
return self.Worker.find({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('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() {
var self = this;
this.Task.belongsTo(this.Worker);
this.init(function() {
self.task.setWorker(self.worker).success(function() {
self.Task.find({
return this.init(function() {
return self.task.setWorker(self.worker).then(function() {
return self.Task.find({
where: { title: 'homework' },
include: [self.Worker]
}).complete(function(err, task) {
expect(err).to.be.null;
}).then(function(task) {
expect(task).to.exist;
expect(task.Worker).to.exist;
expect(task.Worker.name).to.equal('worker');
done();
});
});
});
});
});
it('returns the private and public ip', function(done) {
it('returns the private and public ip', function() {
var self = Object.create(this);
self.Domain = self.sequelize.define('Domain', { ip: Sequelize.STRING });
self.Environment = self.sequelize.define('Environment', { name: Sequelize.STRING });
self.Environment.belongsTo(self.Domain, { as: 'PrivateDomain', foreignKey: 'privateDomainId' });
self.Environment.belongsTo(self.Domain, { as: 'PublicDomain', foreignKey: 'publicDomainId' });
self.Domain.sync({ force: true }).success(function() {
self.Environment.sync({ force: true }).success(function() {
self.Domain.create({ ip: '192.168.0.1' }).success(function(privateIp) {
self.Domain.create({ ip: '91.65.189.19' }).success(function(publicIp) {
self.Environment.create({ name: 'environment' }).success(function(env) {
env.setPrivateDomain(privateIp).success(function() {
env.setPublicDomain(publicIp).success(function() {
self.Environment.find({
return self.Domain.sync({ force: true }).then(function() {
return self.Environment.sync({ force: true }).then(function() {
return self.Domain.create({ ip: '192.168.0.1' }).then(function(privateIp) {
return self.Domain.create({ ip: '91.65.189.19' }).then(function(publicIp) {
return self.Environment.create({ name: 'environment' }).then(function(env) {
return env.setPrivateDomain(privateIp).then(function() {
return env.setPublicDomain(publicIp).then(function() {
return self.Environment.find({
where: { name: 'environment' },
include: [
{ daoFactory: self.Domain, as: 'PrivateDomain' },
{ daoFactory: self.Domain, as: 'PublicDomain' }
]
}).complete(function(err, environment) {
expect(err).to.be.null;
}).then(function(environment) {
expect(environment).to.exist;
expect(environment.PrivateDomain).to.exist;
expect(environment.PrivateDomain.ip).to.equal('192.168.0.1');
expect(environment.PublicDomain).to.exist;
expect(environment.PublicDomain.ip).to.equal('91.65.189.19');
done();
});
});
});
......@@ -408,7 +380,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('eager loads with non-id primary keys', function(done) {
it('eager loads with non-id primary keys', function() {
var self = this;
self.User = self.sequelize.define('UserPKeagerbelong', {
username: {
......@@ -424,27 +396,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
self.User.belongsTo(self.Group);
self.sequelize.sync({ force: true }).success(function() {
self.Group.create({ name: 'people' }).success(function() {
self.User.create({ username: 'someone', GroupPKeagerbelongName: 'people' }).success(function() {
self.User.find({
return self.sequelize.sync({ force: true }).then(function() {
return self.Group.create({ name: 'people' }).then(function() {
return self.User.create({ username: 'someone', GroupPKeagerbelongName: 'people' }).then(function() {
return self.User.find({
where: {
username: 'someone'
},
include: [self.Group]
}).complete(function(err, someUser) {
expect(err).to.be.null;
}).then(function(someUser) {
expect(someUser).to.exist;
expect(someUser.username).to.equal('someone');
expect(someUser.GroupPKeagerbelong.name).to.equal('people');
done();
});
});
});
});
});
it('getting parent data in many to one relationship', function(done) {
it('getting parent data in many to one relationship', function() {
var User = this.sequelize.define('User', {
id: {type: Sequelize.INTEGER, autoIncrement: true, primaryKey: true},
username: {type: Sequelize.STRING}
......@@ -459,20 +429,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
User.hasMany(Message);
Message.belongsTo(User, { foreignKey: 'user_id' });
this.sequelize.sync({ force: true }).success(function() {
User.create({username: 'test_testerson'}).success(function(user) {
Message.create({user_id: user.id, message: 'hi there!'}).success(function() {
Message.create({user_id: user.id, message: 'a second message'}).success(function() {
Message.findAll({
return this.sequelize.sync({ force: true }).then(function() {
return User.create({username: 'test_testerson'}).then(function(user) {
return Message.create({user_id: user.id, message: 'hi there!'}).then(function() {
return Message.create({user_id: user.id, message: 'a second message'}).then(function() {
return Message.findAll({
where: {user_id: user.id},
attributes: [
'user_id',
'message'
],
include: [{ model: User, attributes: ['username'] }]
}).success(function(messages) {
}).then(function(messages) {
expect(messages.length).to.equal(2);
expect(messages[0].message).to.equal('hi there!');
......@@ -480,9 +448,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(messages[1].message).to.equal('a second message');
expect(messages[1].User.username).to.equal('test_testerson');
done();
});
});
});
......@@ -490,58 +455,50 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('allows mulitple assocations of the same model with different alias', function(done) {
it('allows mulitple assocations of the same model with different alias', function() {
var self = this;
this.Worker.belongsTo(this.Task, { as: 'ToDo' });
this.Worker.belongsTo(this.Task, { as: 'DoTo' });
this.init(function() {
self.Worker.find({
return this.init(function() {
return self.Worker.find({
include: [
{ model: self.Task, as: 'ToDo' },
{ model: self.Task, as: 'DoTo' }
]
}).success(function() {
// Just being able to include both shows that this test works, so no assertions needed
done();
});
});
});
});
describe('hasOne', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.Worker.hasOne(this.Task);
this.init(function() {
self.worker.setTask(self.task).success(function() {
done();
});
return this.init(function() {
return self.worker.setTask(self.task);
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Task.find({ include: [self.Worker] }).catch (function(err) {
return self.Task.find({ include: [self.Worker] }).catch (function(err) {
expect(err.message).to.equal('Worker is not associated to Task!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.find({
it('returns the associated task via worker.task', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [this.Task]
}).complete(function(err, worker) {
expect(err).to.be.null;
}).then(function(worker) {
expect(worker).to.exist;
expect(worker.Task).to.exist;
expect(worker.Task.title).to.equal('homework');
done();
});
});
it('eager loads with non-id primary keys', function(done) {
it('eager loads with non-id primary keys', function() {
var self = this;
self.User = self.sequelize.define('UserPKeagerone', {
username: {
......@@ -557,20 +514,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
self.Group.hasOne(self.User);
self.sequelize.sync({ force: true }).success(function() {
self.Group.create({ name: 'people' }).success(function() {
self.User.create({ username: 'someone', GroupPKeageroneName: 'people' }).success(function() {
self.Group.find({
return self.sequelize.sync({ force: true }).then(function() {
return self.Group.create({ name: 'people' }).then(function() {
return self.User.create({ username: 'someone', GroupPKeageroneName: 'people' }).then(function() {
return self.Group.find({
where: {
name: 'people'
},
include: [self.User]
}).complete(function(err, someGroup) {
expect(err).to.be.null;
}).then(function(someGroup) {
expect(someGroup).to.exist;
expect(someGroup.name).to.equal('people');
expect(someGroup.UserPKeagerone.username).to.equal('someone');
done();
});
});
});
......@@ -579,69 +534,59 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('hasOne with alias', function() {
it('throws an error if included DaoFactory is not referenced by alias', function(done) {
it('throws an error if included DaoFactory is not referenced by alias', function() {
var self = this;
self.Worker.find({ include: [self.Task] }).catch (function(err) {
return self.Worker.find({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('Task is not associated to Worker!');
done();
});
});
describe('alias', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.Worker.hasOne(this.Task, { as: 'ToDo' });
this.init(function() {
self.worker.setToDo(self.task).success(function() {
done();
});
return this.init(function() {
return self.worker.setToDo(self.task);
});
});
it('throws an error if alias is not associated', function(done) {
it('throws an error if alias is not associated', function() {
var self = this;
self.Worker.find({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
return self.Worker.find({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
expect(err.message).to.equal('Task (Work) is not associated to Worker!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.find({
it('returns the associated task via worker.task', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [{ daoFactory: this.Task, as: 'ToDo' }]
}).complete(function(err, worker) {
expect(err).to.be.null;
}).then(function(worker) {
expect(worker).to.exist;
expect(worker.ToDo).to.exist;
expect(worker.ToDo.title).to.equal('homework');
done();
});
});
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
this.Worker.find({
it('returns the associated task via worker.task when daoFactory is aliased with model', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [{ model: this.Task, as: 'ToDo' }]
}).complete(function(err, worker) {
}).then(function(worker) {
expect(worker.ToDo.title).to.equal('homework');
done();
});
});
it('allows mulitple assocations of the same model with different alias', function(done) {
it('allows mulitple assocations of the same model with different alias', function() {
var self = this;
this.Worker.hasOne(this.Task, { as: 'DoTo' });
this.init(function() {
self.Worker.find({
return this.init(function() {
return self.Worker.find({
include: [
{ model: self.Task, as: 'ToDo' },
{ model: self.Task, as: 'DoTo' }
]
}).success(function() {
// Just being able to include both shows that this test works, so no assertions needed
done();
});
});
});
......@@ -649,38 +594,33 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('hasMany', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.Worker.hasMany(this.Task);
this.init(function() {
self.worker.setTasks([self.task]).success(function() {
done();
});
return this.init(function() {
return self.worker.setTasks([self.task]);
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Task.find({ include: [self.Worker] }).catch (function(err) {
return self.Task.find({ include: [self.Worker] }).catch (function(err) {
expect(err.message).to.equal('Worker is not associated to Task!');
done();
});
});
it('returns the associated tasks via worker.tasks', function(done) {
this.Worker.find({
it('returns the associated tasks via worker.tasks', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [this.Task]
}).complete(function(err, worker) {
expect(err).to.be.null;
}).then(function(worker) {
expect(worker).to.exist;
expect(worker.Tasks).to.exist;
expect(worker.Tasks[0].title).to.equal('homework');
done();
});
});
it('including two has many relations should not result in duplicate values', function(done) {
it('including two has many relations should not result in duplicate values', function() {
var self = this;
self.Contact = self.sequelize.define('Contact', { name: DataTypes.STRING });
......@@ -690,25 +630,22 @@ describe(Support.getTestDialectTeaser('Model'), function() {
self.Contact.hasMany(self.Photo, { as: 'Photos' });
self.Contact.hasMany(self.PhoneNumber);
self.sequelize.sync({ force: true }).success(function() {
self.Contact.create({ name: 'Boris' }).success(function(someContact) {
self.Photo.create({ img: 'img.jpg' }).success(function(somePhoto) {
self.PhoneNumber.create({ phone: '000000' }).success(function(somePhone1) {
self.PhoneNumber.create({ phone: '111111' }).success(function(somePhone2) {
someContact.setPhotos([somePhoto]).complete(function(err) {
expect(err).to.be.null;
someContact.setPhoneNumbers([somePhone1, somePhone2]).complete(function() {
self.Contact.find({
return self.sequelize.sync({ force: true }).then(function() {
return self.Contact.create({ name: 'Boris' }).then(function(someContact) {
return self.Photo.create({ img: 'img.jpg' }).then(function(somePhoto) {
return self.PhoneNumber.create({ phone: '000000' }).then(function(somePhone1) {
return self.PhoneNumber.create({ phone: '111111' }).then(function(somePhone2) {
return someContact.setPhotos([somePhoto]).then(function() {
return someContact.setPhoneNumbers([somePhone1, somePhone2]).then(function() {
return self.Contact.find({
where: {
name: 'Boris'
},
include: [self.PhoneNumber, { daoFactory: self.Photo, as: 'Photos' }]
}).complete(function(err, fetchedContact) {
expect(err).to.be.null;
}).then(function(fetchedContact) {
expect(fetchedContact).to.exist;
expect(fetchedContact.Photos.length).to.equal(1);
expect(fetchedContact.PhoneNumbers.length).to.equal(2);
done();
});
});
});
......@@ -719,7 +656,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('eager loads with non-id primary keys', function(done) {
it('eager loads with non-id primary keys', function() {
var self = this;
self.User = self.sequelize.define('UserPKeagerone', {
username: {
......@@ -736,22 +673,19 @@ describe(Support.getTestDialectTeaser('Model'), function() {
self.Group.hasMany(self.User);
self.User.hasMany(self.Group);
self.sequelize.sync({ force: true }).success(function() {
self.User.create({ username: 'someone' }).success(function(someUser) {
self.Group.create({ name: 'people' }).success(function(someGroup) {
someUser.setGroupPKeagerones([someGroup]).complete(function(err) {
expect(err).to.be.null;
self.User.find({
return self.sequelize.sync({ force: true }).then(function() {
return self.User.create({ username: 'someone' }).then(function(someUser) {
return self.Group.create({ name: 'people' }).then(function(someGroup) {
return someUser.setGroupPKeagerones([someGroup]).then(function() {
return self.User.find({
where: {
username: 'someone'
},
include: [self.Group]
}).complete(function(err, someUser) {
expect(err).to.be.null;
}).then(function(someUser) {
expect(someUser).to.exist;
expect(someUser.username).to.equal('someone');
expect(someUser.GroupPKeagerones[0].name).to.equal('people');
done();
});
});
});
......@@ -761,69 +695,59 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('hasMany with alias', function() {
it('throws an error if included DaoFactory is not referenced by alias', function(done) {
it('throws an error if included DaoFactory is not referenced by alias', function() {
var self = this;
self.Worker.find({ include: [self.Task] }).catch (function(err) {
return self.Worker.find({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('Task is not associated to Worker!');
done();
});
});
describe('alias', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.Worker.hasMany(this.Task, { as: 'ToDos' });
this.init(function() {
self.worker.setToDos([self.task]).success(function() {
done();
});
return this.init(function() {
return self.worker.setToDos([self.task]);
});
});
it('throws an error if alias is not associated', function(done) {
it('throws an error if alias is not associated', function() {
var self = this;
self.Worker.find({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
return self.Worker.find({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
expect(err.message).to.equal('Task (Work) is not associated to Worker!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.find({
it('returns the associated task via worker.task', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [{ daoFactory: this.Task, as: 'ToDos' }]
}).complete(function(err, worker) {
expect(err).to.be.null;
}).then(function(worker) {
expect(worker).to.exist;
expect(worker.ToDos).to.exist;
expect(worker.ToDos[0].title).to.equal('homework');
done();
});
});
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
this.Worker.find({
it('returns the associated task via worker.task when daoFactory is aliased with model', function() {
return this.Worker.find({
where: { name: 'worker' },
include: [{ model: this.Task, as: 'ToDos' }]
}).complete(function(err, worker) {
}).then(function(worker) {
expect(worker.ToDos[0].title).to.equal('homework');
done();
});
});
it('allows mulitple assocations of the same model with different alias', function(done) {
it('allows mulitple assocations of the same model with different alias', function() {
var self = this;
this.Worker.hasMany(this.Task, { as: 'DoTos' });
this.init(function() {
self.Worker.find({
return this.init(function() {
return self.Worker.find({
include: [
{ model: self.Task, as: 'ToDos' },
{ model: self.Task, as: 'DoTos' }
]
}).success(function() {
// Just being able to include both shows that this test works, so no assertions needed
done();
});
});
});
......@@ -1004,36 +928,32 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('queryOptions', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User.create({username: 'barfooz'}).success(function(user) {
return this.User.create({username: 'barfooz'}).then(function(user) {
self.user = user;
done();
});
});
it('should return a DAO when queryOptions are not set', function(done) {
it('should return a DAO when queryOptions are not set', function() {
var self = this;
this.User.find({ where: { username: 'barfooz'}}).done(function(err, user) {
return this.User.find({ where: { username: 'barfooz'}}).then(function(user) {
expect(user).to.be.instanceOf(self.User.DAO);
done();
});
});
it('should return a DAO when raw is false', function(done) {
it('should return a DAO when raw is false', function() {
var self = this;
this.User.find({ where: { username: 'barfooz'}}, { raw: false }).done(function(err, user) {
return this.User.find({ where: { username: 'barfooz'}}, { raw: false }).then(function(user) {
expect(user).to.be.instanceOf(self.User.DAO);
done();
});
});
it('should return raw data when raw is true', function(done) {
it('should return raw data when raw is true', function() {
var self = this;
this.User.find({ where: { username: 'barfooz'}}, { raw: true }).done(function(err, user) {
return this.User.find({ where: { username: 'barfooz'}}, { raw: true }).then(function(user) {
expect(user).to.not.be.instanceOf(self.User.DAO);
expect(user).to.be.instanceOf(Object);
done();
});
});
});
......
......@@ -11,14 +11,13 @@ var chai = require('chai')
, datetime = require('chai-datetime')
, _ = require('lodash')
, moment = require('moment')
, async = require('async')
, current = Support.sequelize;
chai.use(datetime);
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('Model'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
secretValue: DataTypes.STRING,
......@@ -29,30 +28,25 @@ describe(Support.getTestDialectTeaser('Model'), function() {
binary: DataTypes.STRING(16, true)
});
this.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
describe('findAll', function() {
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAll({ username: 'foo' }).success(function(users1) {
User.findAll({ transaction: t }).success(function(users2) {
User.findAll({ username: 'foo' }, { transaction: t }).success(function(users3) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.findAll({ username: 'foo' }).then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
return User.findAll({ username: 'foo' }, { transaction: t }).then(function(users3) {
expect(users1.length).to.equal(0);
expect(users2.length).to.equal(1);
expect(users3.length).to.equal(1);
t.rollback().success(function() {
done();
});
return t.rollback();
});
});
});
......@@ -64,168 +58,153 @@ describe(Support.getTestDialectTeaser('Model'), function() {
}
describe('special where conditions/smartWhere object', function() {
beforeEach(function(done) {
beforeEach(function() {
this.buf = new Buffer(16);
this.buf.fill('\x01');
this.User.bulkCreate([
return this.User.bulkCreate([
{username: 'boo', intVal: 5, theDate: '2013-01-01 12:00'},
{username: 'boo2', intVal: 10, theDate: '2013-01-10 12:00', binary: this.buf }
]).success(function() {
done();
});
]);
});
it('should be able to find rows where attribute is in a list of values', function(done) {
this.User.findAll({
it('should be able to find rows where attribute is in a list of values', function() {
return this.User.findAll({
where: {
username: ['boo', 'boo2']
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.have.length(2);
done();
});
});
it('should not break when trying to find rows using an array of primary keys', function(done) {
this.User.findAll({
it('should not break when trying to find rows using an array of primary keys', function() {
return this.User.findAll({
where: {
id: [1, 2, 3]
}
}).success(function() {
done();
});
});
it('should not break when using smart syntax on binary fields', function(done) {
this.User.findAll({
it('should not break when using smart syntax on binary fields', function() {
return this.User.findAll({
where: {
binary: [this.buf, this.buf]
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.have.length(1);
expect(users[0].binary).to.be.an.instanceof.string;
expect(users[0].username).to.equal('boo2');
done();
});
});
it('should be able to find a row using like', function(done) {
this.User.findAll({
it('should be able to find a row using like', function() {
return this.User.findAll({
where: {
username: {
like: '%2'
}
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.be.an.instanceof(Array);
expect(users).to.have.length(1);
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row using not like', function(done) {
this.User.findAll({
it('should be able to find a row using not like', function() {
return this.User.findAll({
where: {
username: {
nlike: '%2'
}
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.be.an.instanceof(Array);
expect(users).to.have.length(1);
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
if (dialect === 'postgres') {
it('should be able to find a row using ilike', function(done) {
this.User.findAll({
it('should be able to find a row using ilike', function() {
return this.User.findAll({
where: {
username: {
ilike: '%2'
}
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.be.an.instanceof(Array);
expect(users).to.have.length(1);
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row using not ilike', function(done) {
this.User.findAll({
it('should be able to find a row using not ilike', function() {
return this.User.findAll({
where: {
username: {
notilike: '%2'
}
}
}).success(function(users) {
}).then(function(users) {
expect(users).to.be.an.instanceof(Array);
expect(users).to.have.length(1);
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
}
it('should be able to find a row between a certain date using the between shortcut', function(done) {
this.User.findAll({
it('should be able to find a row between a certain date using the between shortcut', function() {
return this.User.findAll({
where: {
theDate: {
'..': ['2013-01-02', '2013-01-11']
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row not between a certain integer using the not between shortcut', function(done) {
this.User.findAll({
it('should be able to find a row not between a certain integer using the not between shortcut', function() {
return this.User.findAll({
where: {
intVal: {
'!..': [8, 10]
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
it('should be able to handle false/true values just fine...', function(done) {
it('should be able to handle false/true values just fine...', function() {
var User = this.User
, escapeChar = (dialect === 'postgres' || dialect === 'mssql') ? '"' : '`';
User.bulkCreate([
return User.bulkCreate([
{username: 'boo5', aBool: false},
{username: 'boo6', aBool: true}
]).success(function() {
User.all({where: [escapeChar + 'aBool' + escapeChar + ' = ?', false]}).success(function(users) {
]).then(function() {
return User.findAll({where: [escapeChar + 'aBool' + escapeChar + ' = ?', false]}).then(function(users) {
expect(users).to.have.length(1);
expect(users[0].username).to.equal('boo5');
User.all({where: [escapeChar + 'aBool' + escapeChar + ' = ?', true]}).success(function(_users) {
return User.findAll({where: [escapeChar + 'aBool' + escapeChar + ' = ?', true]}).then(function(_users) {
expect(_users).to.have.length(1);
expect(_users[0].username).to.equal('boo6');
done();
});
});
});
});
it('should be able to handle false/true values through associations as well...', function(done) {
it('should be able to handle false/true values through associations as well...', function() {
var User = this.User
, escapeChar = (dialect === 'postgres' || dialect === 'mssql') ? '"' : '`'
, Passports = this.sequelize.define('Passports', {
......@@ -235,29 +214,28 @@ describe(Support.getTestDialectTeaser('Model'), function() {
User.hasMany(Passports);
Passports.belongsTo(User);
User.sync({ force: true }).success(function() {
Passports.sync({ force: true }).success(function() {
User.bulkCreate([
return User.sync({ force: true }).then(function() {
return Passports.sync({ force: true }).then(function() {
return User.bulkCreate([
{username: 'boo5', aBool: false},
{username: 'boo6', aBool: true}
]).success(function() {
Passports.bulkCreate([
]).then(function() {
return Passports.bulkCreate([
{isActive: true},
{isActive: false}
]).success(function() {
User.find(1).success(function(user) {
Passports.find(1).success(function(passport) {
user.setPassports([passport]).success(function() {
User.find(2).success(function(_user) {
Passports.find(2).success(function(_passport) {
_user.setPassports([_passport]).success(function() {
_user.getPassports({where: [escapeChar + 'isActive' + escapeChar + ' = ?', false]}).success(function(theFalsePassport) {
user.getPassports({where: [escapeChar + 'isActive' + escapeChar + ' = ?', true]}).success(function(theTruePassport) {
]).then(function() {
return User.find(1).then(function(user) {
return Passports.find(1).then(function(passport) {
return user.setPassports([passport]).then(function() {
return User.find(2).then(function(_user) {
return Passports.find(2).then(function(_passport) {
return _user.setPassports([_passport]).then(function() {
return _user.getPassports({where: [escapeChar + 'isActive' + escapeChar + ' = ?', false]}).then(function(theFalsePassport) {
return user.getPassports({where: [escapeChar + 'isActive' + escapeChar + ' = ?', true]}).then(function(theTruePassport) {
expect(theFalsePassport).to.have.length(1);
expect(theFalsePassport[0].isActive).to.be.false;
expect(theTruePassport).to.have.length(1);
expect(theTruePassport[0].isActive).to.be.true;
done();
});
});
});
......@@ -272,7 +250,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('should be able to handle binary values through associations as well...', function(done) {
it('should be able to handle binary values through associations as well...', function() {
var User = this.User;
var Binary = this.sequelize.define('Binary', {
id: {
......@@ -287,30 +265,29 @@ describe(Support.getTestDialectTeaser('Model'), function() {
User.belongsTo(Binary, { foreignKey: 'binary' });
this.sequelize.sync({ force: true }).success(function() {
User.bulkCreate([
return this.sequelize.sync({ force: true }).then(function() {
return User.bulkCreate([
{username: 'boo5', aBool: false},
{username: 'boo6', aBool: true}
]).success(function() {
Binary.bulkCreate([
]).then(function() {
return Binary.bulkCreate([
{id: buf1},
{id: buf2}
]).success(function() {
User.find(1).success(function(user) {
Binary.find(buf1).success(function(binary) {
user.setBinary(binary).success(function() {
User.find(2).success(function(_user) {
Binary.find(buf2).success(function(_binary) {
_user.setBinary(_binary).success(function() {
_user.getBinary().success(function(_binaryRetrieved) {
user.getBinary().success(function(binaryRetrieved) {
]).then(function() {
return User.find(1).then(function(user) {
return Binary.find(buf1).then(function(binary) {
return user.setBinary(binary).then(function() {
return User.find(2).then(function(_user) {
return Binary.find(buf2).then(function(_binary) {
return _user.setBinary(_binary).then(function() {
return _user.getBinary().then(function(_binaryRetrieved) {
return user.getBinary().then(function(binaryRetrieved) {
expect(binaryRetrieved.id).to.be.an.instanceof.string;
expect(_binaryRetrieved.id).to.be.an.instanceof.string;
expect(binaryRetrieved.id).to.have.length(16);
expect(_binaryRetrieved.id).to.have.length(16);
expect(binaryRetrieved.id.toString()).to.be.equal(buf1.toString());
expect(_binaryRetrieved.id.toString()).to.be.equal(buf2.toString());
done();
});
});
});
......@@ -324,7 +301,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('should be able to return a record with primaryKey being null for new inserts', function(done) {
it('should be able to return a record with primaryKey being null for new inserts', function() {
var Session = this.sequelize.define('Session', {
token: { type: DataTypes.TEXT, allowNull: false },
lastUpdate: { type: DataTypes.DATE, allowNull: false }
......@@ -346,206 +323,192 @@ describe(Support.getTestDialectTeaser('Model'), function() {
User.hasMany(Session, { as: 'Sessions' });
Session.belongsTo(User);
this.sequelize.sync({ force: true }).success(function() {
User.create({name: 'Name1', password: '123', isAdmin: false}).success(function(user) {
return this.sequelize.sync({ force: true }).then(function() {
return User.create({name: 'Name1', password: '123', isAdmin: false}).then(function(user) {
var sess = Session.build({
lastUpdate: new Date(),
token: '123'
});
user.addSession(sess).success(function(u) {
return user.addSession(sess).then(function(u) {
expect(u.token).to.equal('123');
done();
});
});
});
});
it('should be able to find a row between a certain date', function(done) {
this.User.findAll({
it('should be able to find a row between a certain date', function() {
return this.User.findAll({
where: {
theDate: {
between: ['2013-01-02', '2013-01-11']
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row between a certain date and an additional where clause', function(done) {
this.User.findAll({
it('should be able to find a row between a certain date and an additional where clause', function() {
return this.User.findAll({
where: {
theDate: {
between: ['2013-01-02', '2013-01-11']
},
intVal: 10
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row not between a certain integer', function(done) {
this.User.findAll({
it('should be able to find a row not between a certain integer', function() {
return this.User.findAll({
where: {
intVal: {
nbetween: [8, 10]
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
it('should be able to find a row using not between and between logic', function(done) {
this.User.findAll({
it('should be able to find a row using not between and between logic', function() {
return this.User.findAll({
where: {
theDate: {
between: ['2012-12-10', '2013-01-02'],
nbetween: ['2013-01-04', '2013-01-20']
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
it('should be able to find a row using not between and between logic with dates', function(done) {
this.User.findAll({
it('should be able to find a row using not between and between logic with dates', function() {
return this.User.findAll({
where: {
theDate: {
between: [new Date('2012-12-10'), new Date('2013-01-02')],
nbetween: [new Date('2013-01-04'), new Date('2013-01-20')]
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
it('should be able to find a row using greater than or equal to logic with dates', function(done) {
this.User.findAll({
it('should be able to find a row using greater than or equal to logic with dates', function() {
return this.User.findAll({
where: {
theDate: {
gte: new Date('2013-01-09')
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo2');
expect(users[0].intVal).to.equal(10);
done();
});
});
it('should be able to find a row using greater than or equal to', function(done) {
this.User.find({
it('should be able to find a row using greater than or equal to', function() {
return this.User.find({
where: {
intVal: {
gte: 6
}
}
}).success(function(user) {
}).then(function(user) {
expect(user.username).to.equal('boo2');
expect(user.intVal).to.equal(10);
done();
});
});
it('should be able to find a row using greater than', function(done) {
this.User.find({
it('should be able to find a row using greater than', function() {
return this.User.find({
where: {
intVal: {
gt: 5
}
}
}).success(function(user) {
}).then(function(user) {
expect(user.username).to.equal('boo2');
expect(user.intVal).to.equal(10);
done();
});
});
it('should be able to find a row using lesser than or equal to', function(done) {
this.User.find({
it('should be able to find a row using lesser than or equal to', function() {
return this.User.find({
where: {
intVal: {
lte: 5
}
}
}).success(function(user) {
}).then(function(user) {
expect(user.username).to.equal('boo');
expect(user.intVal).to.equal(5);
done();
});
});
it('should be able to find a row using lesser than', function(done) {
this.User.find({
it('should be able to find a row using lesser than', function() {
return this.User.find({
where: {
intVal: {
lt: 6
}
}
}).success(function(user) {
}).then(function(user) {
expect(user.username).to.equal('boo');
expect(user.intVal).to.equal(5);
done();
});
});
it('should have no problem finding a row using lesser and greater than', function(done) {
this.User.findAll({
it('should have no problem finding a row using lesser and greater than', function() {
return this.User.findAll({
where: {
intVal: {
lt: 6,
gt: 4
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
done();
});
});
it('should be able to find a row using not equal to logic', function(done) {
this.User.find({
it('should be able to find a row using not equal to logic', function() {
return this.User.find({
where: {
intVal: {
ne: 10
}
}
}).success(function(user) {
}).then(function(user) {
expect(user.username).to.equal('boo');
expect(user.intVal).to.equal(5);
done();
});
});
it('should be able to find multiple users with any of the special where logic properties', function(done) {
this.User.findAll({
it('should be able to find multiple users with any of the special where logic properties', function() {
return this.User.findAll({
where: {
intVal: {
lte: 10
}
}
}).success(function(users) {
}).then(function(users) {
expect(users[0].username).to.equal('boo');
expect(users[0].intVal).to.equal(5);
expect(users[1].username).to.equal('boo2');
expect(users[1].intVal).to.equal(10);
done();
});
});
});
......@@ -558,316 +521,274 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('eager loading', function() {
describe('belongsTo', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('TaskBelongsTo', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('Worker', { name: Sequelize.STRING });
self.Task.belongsTo(self.Worker);
self.Worker.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.Worker.sync({ force: true }).then(function() {
return self.Task.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
self.task.setWorker(self.worker).success(function() {
done();
});
return self.task.setWorker(self.worker);
});
});
});
});
});
it('throws an error about unexpected input if include contains a non-object', function(done) {
it('throws an error about unexpected input if include contains a non-object', function() {
var self = this;
self.Worker.all({ include: [1] }).catch (function(err) {
return self.Worker.findAll({ include: [1] }).catch (function(err) {
expect(err.message).to.equal('Include unexpected. Element has to be either a Model, an Association or an object.');
done();
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Worker.all({ include: [self.Task] }).catch (function(err) {
return self.Worker.findAll({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('TaskBelongsTo is not associated to Worker!');
done();
});
});
it('returns the associated worker via task.worker', function(done) {
this.Task.all({
it('returns the associated worker via task.worker', function() {
return this.Task.findAll({
where: { title: 'homework' },
include: [this.Worker]
}).complete(function(err, tasks) {
expect(err).to.be.null;
}).then(function(tasks) {
expect(tasks).to.exist;
expect(tasks[0].Worker).to.exist;
expect(tasks[0].Worker.name).to.equal('worker');
done();
});
});
});
describe('hasOne', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('TaskHasOne', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('Worker', { name: Sequelize.STRING });
self.Worker.hasOne(self.Task);
self.Worker.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.Worker.sync({ force: true }).then(function() {
return self.Task.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
self.worker.setTaskHasOne(self.task).success(function() {
done();
});
return self.worker.setTaskHasOne(self.task);
});
});
});
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Task.all({ include: [self.Worker] }).catch (function(err) {
return self.Task.findAll({ include: [self.Worker] }).catch (function(err) {
expect(err.message).to.equal('Worker is not associated to TaskHasOne!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.all({
it('returns the associated task via worker.task', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [this.Task]
}).complete(function(err, workers) {
expect(err).to.be.null;
}).then(function(workers) {
expect(workers).to.exist;
expect(workers[0].TaskHasOne).to.exist;
expect(workers[0].TaskHasOne.title).to.equal('homework');
done();
});
});
});
describe('hasOne with alias', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('Task', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('Worker', { name: Sequelize.STRING });
self.Worker.hasOne(self.Task, { as: 'ToDo' });
self.Worker.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.Worker.sync({ force: true }).then(function() {
return self.Task.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
self.worker.setToDo(self.task).success(function() {
done();
});
return self.worker.setToDo(self.task);
});
});
});
});
});
it('throws an error if included DaoFactory is not referenced by alias', function(done) {
it('throws an error if included DaoFactory is not referenced by alias', function() {
var self = this;
self.Worker.all({ include: [self.Task] }).catch (function(err) {
return self.Worker.findAll({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('Task is not associated to Worker!');
done();
});
});
it('throws an error if alias is not associated', function(done) {
it('throws an error if alias is not associated', function() {
var self = this;
self.Worker.all({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
return self.Worker.findAll({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
expect(err.message).to.equal('Task (Work) is not associated to Worker!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.all({
it('returns the associated task via worker.task', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [{ daoFactory: this.Task, as: 'ToDo' }]
}).complete(function(err, workers) {
expect(err).to.be.null;
}).then(function(workers) {
expect(workers).to.exist;
expect(workers[0].ToDo).to.exist;
expect(workers[0].ToDo.title).to.equal('homework');
done();
});
});
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
this.Worker.all({
it('returns the associated task via worker.task when daoFactory is aliased with model', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [{ model: this.Task, as: 'ToDo' }]
}).complete(function(err, workers) {
}).then(function(workers) {
expect(workers[0].ToDo.title).to.equal('homework');
done();
});
});
});
describe('hasMany', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('task', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('worker', { name: Sequelize.STRING });
self.Worker.hasMany(self.Task);
self.Worker.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.Worker.sync({ force: true }).then(function() {
return self.Task.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
self.worker.setTasks([self.task]).success(function() {
done();
});
return self.worker.setTasks([self.task]);
});
});
});
});
});
it('throws an error if included DaoFactory is not associated', function(done) {
it('throws an error if included DaoFactory is not associated', function() {
var self = this;
self.Task.findAll({ include: [self.Worker] }).catch (function(err) {
return self.Task.findAll({ include: [self.Worker] }).catch (function(err) {
expect(err.message).to.equal('worker is not associated to task!');
done();
});
});
it('returns the associated tasks via worker.tasks', function(done) {
this.Worker.findAll({
it('returns the associated tasks via worker.tasks', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [this.Task]
}).complete(function(err, workers) {
expect(err).to.be.null;
}).then(function(workers) {
expect(workers).to.exist;
expect(workers[0].tasks).to.exist;
expect(workers[0].tasks[0].title).to.equal('homework');
done();
});
});
});
describe('hasMany with alias', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Task = self.sequelize.define('Task', { title: Sequelize.STRING });
self.Worker = self.sequelize.define('Worker', { name: Sequelize.STRING });
self.Worker.hasMany(self.Task, { as: 'ToDos' });
self.Worker.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.Worker.create({ name: 'worker' }).success(function(worker) {
self.Task.create({ title: 'homework' }).success(function(task) {
return self.Worker.sync({ force: true }).then(function() {
return self.Task.sync({ force: true }).then(function() {
return self.Worker.create({ name: 'worker' }).then(function(worker) {
return self.Task.create({ title: 'homework' }).then(function(task) {
self.worker = worker;
self.task = task;
self.worker.setToDos([self.task]).success(function() {
done();
});
return self.worker.setToDos([self.task]);
});
});
});
});
});
it('throws an error if included DaoFactory is not referenced by alias', function(done) {
it('throws an error if included DaoFactory is not referenced by alias', function() {
var self = this;
self.Worker.findAll({ include: [self.Task] }).catch (function(err) {
return self.Worker.findAll({ include: [self.Task] }).catch (function(err) {
expect(err.message).to.equal('Task is not associated to Worker!');
done();
});
});
it('throws an error if alias is not associated', function(done) {
it('throws an error if alias is not associated', function() {
var self = this;
self.Worker.findAll({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
return self.Worker.findAll({ include: [{ daoFactory: self.Task, as: 'Work' }] }).catch (function(err) {
expect(err.message).to.equal('Task (Work) is not associated to Worker!');
done();
});
});
it('returns the associated task via worker.task', function(done) {
this.Worker.findAll({
it('returns the associated task via worker.task', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [{ daoFactory: this.Task, as: 'ToDos' }]
}).complete(function(err, workers) {
expect(err).to.be.null;
}).then(function(workers) {
expect(workers).to.exist;
expect(workers[0].ToDos).to.exist;
expect(workers[0].ToDos[0].title).to.equal('homework');
done();
});
});
it('returns the associated task via worker.task when daoFactory is aliased with model', function(done) {
this.Worker.findAll({
it('returns the associated task via worker.task when daoFactory is aliased with model', function() {
return this.Worker.findAll({
where: { name: 'worker' },
include: [{ daoFactory: this.Task, as: 'ToDos' }]
}).complete(function(err, workers) {
}).then(function(workers) {
expect(workers[0].ToDos[0].title).to.equal('homework');
done();
});
});
});
describe('queryOptions', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User.create({username: 'barfooz'}).success(function(user) {
return this.User.create({username: 'barfooz'}).then(function(user) {
self.user = user;
done();
});
});
it('should return a DAO when queryOptions are not set', function(done) {
it('should return a DAO when queryOptions are not set', function() {
var self = this;
this.User.findAll({ where: { username: 'barfooz'}}).done(function(err, users) {
return this.User.findAll({ where: { username: 'barfooz'}}).then(function(users) {
users.forEach(function(user) {
expect(user).to.be.instanceOf(self.User.DAO);
});
done();
});
});
it('should return a DAO when raw is false', function(done) {
it('should return a DAO when raw is false', function() {
var self = this;
this.User.findAll({ where: { username: 'barfooz'}}, { raw: false }).done(function(err, users) {
return this.User.findAll({ where: { username: 'barfooz'}}, { raw: false }).then(function(users) {
users.forEach(function(user) {
expect(user).to.be.instanceOf(self.User.DAO);
});
done();
});
});
it('should return raw data when raw is true', function(done) {
it('should return raw data when raw is true', function() {
var self = this;
this.User.findAll({ where: { username: 'barfooz'}}, { raw: true }).done(function(err, users) {
return this.User.findAll({ where: { username: 'barfooz'}}, { raw: true }).then(function(users) {
users.forEach(function(user) {
expect(user).to.not.be.instanceOf(self.User.DAO);
expect(users[0]).to.be.instanceOf(Object);
});
done();
});
});
});
describe('include all', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Continent = this.sequelize.define('continent', { name: Sequelize.STRING });
......@@ -884,61 +805,50 @@ describe(Support.getTestDialectTeaser('Model'), function() {
self.Country.hasMany(self.Person, { as: 'residents', foreignKey: 'CountryResidentId' });
self.Person.belongsTo(self.Country, { as: 'CountryResident', foreignKey: 'CountryResidentId' });
this.sequelize.sync({ force: true }).success(function() {
async.parallel({
europe: function(callback) { self.Continent.create({ name: 'Europe' }).done(callback); },
england: function(callback) { self.Country.create({ name: 'England' }).done(callback); },
coal: function(callback) { self.Industry.create({ name: 'Coal' }).done(callback); },
bob: function(callback) { self.Person.create({ name: 'Bob', lastName: 'Becket' }).done(callback); }
}, function(err, r) {
if (err) throw err;
return this.sequelize.sync({ force: true }).then(function() {
return self.sequelize.Promise.props({
europe: self.Continent.create({ name: 'Europe' }),
england: self.Country.create({ name: 'England' }),
coal: self.Industry.create({ name: 'Coal' }),
bob: self.Person.create({ name: 'Bob', lastName: 'Becket' })
}).then(function(r) {
_.forEach(r, function(item, itemName) {
self[itemName] = item;
});
async.parallel([
function(callback) { self.england.setContinent(self.europe).done(callback); },
function(callback) { self.england.addIndustry(self.coal).done(callback); },
function(callback) { self.bob.setCountry(self.england).done(callback); },
function(callback) { self.bob.setCountryResident(self.england).done(callback); }
], function(err) {
if (err) throw err;
done();
});
return self.sequelize.Promise.all([
self.england.setContinent(self.europe),
self.england.addIndustry(self.coal),
self.bob.setCountry(self.england),
self.bob.setCountryResident(self.england)
]);
});
});
});
it('includes all associations', function(done) {
this.Country.findAll({ include: [{ all: true }] }).done(function(err, countries) {
expect(err).not.to.be.ok;
it('includes all associations', function() {
return this.Country.findAll({ include: [{ all: true }] }).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].continent).to.exist;
expect(countries[0].industries).to.exist;
expect(countries[0].people).to.exist;
expect(countries[0].residents).to.exist;
done();
});
});
it('includes specific type of association', function(done) {
this.Country.findAll({ include: [{ all: 'BelongsTo' }] }).done(function(err, countries) {
expect(err).not.to.be.ok;
it('includes specific type of association', function() {
return this.Country.findAll({ include: [{ all: 'BelongsTo' }] }).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].continent).to.exist;
expect(countries[0].industries).not.to.exist;
expect(countries[0].people).not.to.exist;
expect(countries[0].residents).not.to.exist;
done();
});
});
it('utilises specified attributes', function(done) {
this.Country.findAll({ include: [{ all: 'HasMany', attributes: ['name'] }] }).done(function(err, countries) {
expect(err).not.to.be.ok;
it('utilises specified attributes', function() {
return this.Country.findAll({ include: [{ all: 'HasMany', attributes: ['name'] }] }).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].industries).to.exist;
......@@ -950,7 +860,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(countries[0].residents[0]).to.exist;
expect(countries[0].residents[0].name).not.to.be.undefined;
expect(countries[0].residents[0].lastName).to.be.undefined;
done();
});
});
......@@ -963,9 +872,8 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('includes all nested associations', function(done) {
this.Continent.findAll({ include: [{ all: true, nested: true }] }).done(function(err, continents) {
expect(err).not.to.be.ok;
it('includes all nested associations', function() {
return this.Continent.findAll({ include: [{ all: true, nested: true }] }).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].countries).to.exist;
......@@ -974,7 +882,6 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(continents[0].countries[0].people).to.exist;
expect(continents[0].countries[0].residents).to.exist;
expect(continents[0].countries[0].continent).not.to.exist;
done();
});
});
});
......@@ -982,7 +889,7 @@ describe(Support.getTestDialectTeaser('Model'), function() {
describe('order by eager loaded tables', function() {
describe('HasMany', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Continent = this.sequelize.define('continent', { name: Sequelize.STRING });
......@@ -996,88 +903,78 @@ describe(Support.getTestDialectTeaser('Model'), function() {
self.Country.hasMany(self.Person, { as: 'residents', foreignKey: 'CountryResidentId' });
self.Person.belongsTo(self.Country, { as: 'CountryResident', foreignKey: 'CountryResidentId' });
this.sequelize.sync({ force: true }).success(function() {
async.parallel({
europe: function(callback) { self.Continent.create({ name: 'Europe' }).done(callback); },
asia: function(callback) { self.Continent.create({ name: 'Asia' }).done(callback); },
england: function(callback) { self.Country.create({ name: 'England' }).done(callback); },
france: function(callback) { self.Country.create({ name: 'France' }).done(callback); },
korea: function(callback) { self.Country.create({ name: 'Korea' }).done(callback); },
bob: function(callback) { self.Person.create({ name: 'Bob', lastName: 'Becket' }).done(callback); },
fred: function(callback) { self.Person.create({ name: 'Fred', lastName: 'Able' }).done(callback); },
pierre: function(callback) { self.Person.create({ name: 'Pierre', lastName: 'Paris' }).done(callback); },
kim: function(callback) { self.Person.create({ name: 'Kim', lastName: 'Z' }).done(callback); }
}, function(err, r) {
if (err) throw err;
return this.sequelize.sync({ force: true }).then(function() {
return self.sequelize.Promise.props({
europe: self.Continent.create({ name: 'Europe' }),
asia: self.Continent.create({ name: 'Asia' }),
england: self.Country.create({ name: 'England' }),
france: self.Country.create({ name: 'France' }),
korea: self.Country.create({ name: 'Korea' }),
bob: self.Person.create({ name: 'Bob', lastName: 'Becket' }),
fred: self.Person.create({ name: 'Fred', lastName: 'Able' }),
pierre: self.Person.create({ name: 'Pierre', lastName: 'Paris' }),
kim: self.Person.create({ name: 'Kim', lastName: 'Z' })
}).then(function(r) {
_.forEach(r, function(item, itemName) {
self[itemName] = item;
});
async.parallel([
function(callback) { self.england.setContinent(self.europe).done(callback); },
function(callback) { self.france.setContinent(self.europe).done(callback); },
function(callback) { self.korea.setContinent(self.asia).done(callback); },
function(callback) { self.bob.setCountry(self.england).done(callback); },
function(callback) { self.fred.setCountry(self.england).done(callback); },
function(callback) { self.pierre.setCountry(self.france).done(callback); },
function(callback) { self.kim.setCountry(self.korea).done(callback); },
function(callback) { self.bob.setCountryResident(self.england).done(callback); },
function(callback) { self.fred.setCountryResident(self.france).done(callback); },
function(callback) { self.pierre.setCountryResident(self.korea).done(callback); },
function(callback) { self.kim.setCountryResident(self.england).done(callback); }
], function(err) {
if (err) throw err;
done();
});
return self.sequelize.Promise.all([
self.england.setContinent(self.europe),
self.france.setContinent(self.europe),
self.korea.setContinent(self.asia),
self.bob.setCountry(self.england),
self.fred.setCountry(self.england),
self.pierre.setCountry(self.france),
self.kim.setCountry(self.korea),
self.bob.setCountryResident(self.england),
self.fred.setCountryResident(self.france),
self.pierre.setCountryResident(self.korea),
self.kim.setCountryResident(self.england)
]);
});
});
});
it('sorts simply', function(done) {
it('sorts simply', function() {
var self = this;
async.eachSeries([['ASC', 'Asia'], ['DESC', 'Europe']], function(params, callback) {
self.Continent.findAll({
return this.sequelize.Promise.map([['ASC', 'Asia'], ['DESC', 'Europe']], function(params) {
return self.Continent.findAll({
order: [['name', params[0]]]
}).done(function(err, continents) {
expect(err).not.to.be.ok;
}).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].name).to.equal(params[1]);
callback();
});
}, function() { done(); });
});
});
it('sorts by 1st degree association', function(done) {
it('sorts by 1st degree association', function() {
var self = this;
async.forEach([['ASC', 'Europe', 'England'], ['DESC', 'Asia', 'Korea']], function(params, callback) {
self.Continent.findAll({
return this.sequelize.Promise.map([['ASC', 'Europe', 'England'], ['DESC', 'Asia', 'Korea']], function(params) {
return self.Continent.findAll({
include: [self.Country],
order: [[self.Country, 'name', params[0]]]
}).done(function(err, continents) {
expect(err).not.to.be.ok;
}).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].name).to.equal(params[1]);
expect(continents[0].countries).to.exist;
expect(continents[0].countries[0]).to.exist;
expect(continents[0].countries[0].name).to.equal(params[2]);
callback();
});
}, function() { done(); });
});
});
it('sorts by 2nd degree association', function(done) {
it('sorts by 2nd degree association', function() {
var self = this;
async.forEach([['ASC', 'Europe', 'England', 'Fred'], ['DESC', 'Asia', 'Korea', 'Kim']], function(params, callback) {
self.Continent.findAll({
return this.sequelize.Promise.map([['ASC', 'Europe', 'England', 'Fred'], ['DESC', 'Asia', 'Korea', 'Kim']], function(params) {
return self.Continent.findAll({
include: [{ model: self.Country, include: [self.Person] }],
order: [[self.Country, self.Person, 'lastName', params[0]]]
}).done(function(err, continents) {
expect(err).not.to.be.ok;
}).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].name).to.equal(params[1]);
......@@ -1087,19 +984,17 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(continents[0].countries[0].people).to.exist;
expect(continents[0].countries[0].people[0]).to.exist;
expect(continents[0].countries[0].people[0].name).to.equal(params[3]);
callback();
});
}, function() { done(); });
});
}),
it('sorts by 2nd degree association with alias', function(done) {
it('sorts by 2nd degree association with alias', function() {
var self = this;
async.forEach([['ASC', 'Europe', 'France', 'Fred'], ['DESC', 'Europe', 'England', 'Kim']], function(params, callback) {
self.Continent.findAll({
return this.sequelize.Promise.map([['ASC', 'Europe', 'France', 'Fred'], ['DESC', 'Europe', 'England', 'Kim']], function(params) {
return self.Continent.findAll({
include: [{ model: self.Country, include: [self.Person, {model: self.Person, as: 'residents' }] }],
order: [[self.Country, {model: self.Person, as: 'residents' }, 'lastName', params[0]]]
}).done(function(err, continents) {
expect(err).not.to.be.ok;
}).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].name).to.equal(params[1]);
......@@ -1109,20 +1004,18 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(continents[0].countries[0].residents).to.exist;
expect(continents[0].countries[0].residents[0]).to.exist;
expect(continents[0].countries[0].residents[0].name).to.equal(params[3]);
callback();
});
}, function() { done(); });
});
});
it('sorts by 2nd degree association with alias while using limit', function(done) {
it('sorts by 2nd degree association with alias while using limit', function() {
var self = this;
async.forEach([['ASC', 'Europe', 'France', 'Fred'], ['DESC', 'Europe', 'England', 'Kim']], function(params, callback) {
self.Continent.findAll({
return this.sequelize.Promise.map([['ASC', 'Europe', 'France', 'Fred'], ['DESC', 'Europe', 'England', 'Kim']], function(params) {
return self.Continent.findAll({
include: [{ model: self.Country, include: [self.Person, {model: self.Person, as: 'residents' }] }],
order: [[{ model: self.Country }, {model: self.Person, as: 'residents' }, 'lastName', params[0]]],
limit: 3
}).done(function(err, continents) {
expect(err).not.to.be.ok;
}).then(function(continents) {
expect(continents).to.exist;
expect(continents[0]).to.exist;
expect(continents[0].name).to.equal(params[1]);
......@@ -1132,14 +1025,13 @@ describe(Support.getTestDialectTeaser('Model'), function() {
expect(continents[0].countries[0].residents).to.exist;
expect(continents[0].countries[0].residents[0]).to.exist;
expect(continents[0].countries[0].residents[0].name).to.equal(params[3]);
callback();
});
}, function() { done(); });
});
});
}),
describe('ManyToMany', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
self.Country = this.sequelize.define('country', { name: Sequelize.STRING });
......@@ -1149,205 +1041,179 @@ describe(Support.getTestDialectTeaser('Model'), function() {
self.Country.hasMany(self.Industry, {through: self.IndustryCountry});
self.Industry.hasMany(self.Country, {through: self.IndustryCountry});
this.sequelize.sync({ force: true }).success(function() {
async.parallel({
england: function(callback) { self.Country.create({ name: 'England' }).done(callback); },
france: function(callback) { self.Country.create({ name: 'France' }).done(callback); },
korea: function(callback) { self.Country.create({ name: 'Korea' }).done(callback); },
energy: function(callback) { self.Industry.create({ name: 'Energy' }).done(callback); },
media: function(callback) { self.Industry.create({ name: 'Media' }).done(callback); },
tech: function(callback) { self.Industry.create({ name: 'Tech' }).done(callback); }
}, function(err, r) {
if (err) throw err;
return this.sequelize.sync({ force: true }).then(function() {
return self.sequelize.Promise.props({
england: self.Country.create({ name: 'England' }),
france: self.Country.create({ name: 'France' }),
korea: self.Country.create({ name: 'Korea' }),
energy: self.Industry.create({ name: 'Energy' }),
media: self.Industry.create({ name: 'Media' }),
tech: self.Industry.create({ name: 'Tech' })
}).then(function(r) {
_.forEach(r, function(item, itemName) {
self[itemName] = item;
});
async.parallel([
function(callback) { self.england.addIndustry(self.energy, {numYears: 20}).done(callback); },
function(callback) { self.england.addIndustry(self.media, {numYears: 40}).done(callback); },
function(callback) { self.france.addIndustry(self.media, {numYears: 80}).done(callback); },
function(callback) { self.korea.addIndustry(self.tech, {numYears: 30}).done(callback); }
], function(err) {
if (err) throw err;
done();
});
return self.sequelize.Promise.all([
self.england.addIndustry(self.energy, {numYears: 20}),
self.england.addIndustry(self.media, {numYears: 40}),
self.france.addIndustry(self.media, {numYears: 80}),
self.korea.addIndustry(self.tech, {numYears: 30})
]);
});
});
});
it('sorts by 1st degree association', function(done) {
it('sorts by 1st degree association', function() {
var self = this;
async.forEach([['ASC', 'England', 'Energy'], ['DESC', 'Korea', 'Tech']], function(params, callback) {
self.Country.findAll({
return this.sequelize.Promise.map([['ASC', 'England', 'Energy'], ['DESC', 'Korea', 'Tech']], function(params) {
return self.Country.findAll({
include: [self.Industry],
order: [[self.Industry, 'name', params[0]]]
}).done(function(err, countries) {
expect(err).not.to.be.ok;
}).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].name).to.equal(params[1]);
expect(countries[0].industries).to.exist;
expect(countries[0].industries[0]).to.exist;
expect(countries[0].industries[0].name).to.equal(params[2]);
callback();
});
}, function() { done(); });
});
});
it('sorts by 1st degree association while using limit', function(done) {
it('sorts by 1st degree association while using limit', function() {
var self = this;
async.forEach([['ASC', 'England', 'Energy'], ['DESC', 'Korea', 'Tech']], function(params, callback) {
self.Country.findAll({
return this.sequelize.Promise.map([['ASC', 'England', 'Energy'], ['DESC', 'Korea', 'Tech']], function(params) {
return self.Country.findAll({
include: [self.Industry],
order: [
[self.Industry, 'name', params[0]]
],
limit: 3
}).done(function(err, countries) {
expect(err).not.to.be.ok;
}).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].name).to.equal(params[1]);
expect(countries[0].industries).to.exist;
expect(countries[0].industries[0]).to.exist;
expect(countries[0].industries[0].name).to.equal(params[2]);
callback();
});
}, function() { done(); });
});
});
it('sorts by through table attribute', function(done) {
it('sorts by through table attribute', function() {
var self = this;
async.forEach([['ASC', 'England', 'Energy'], ['DESC', 'France', 'Media']], function(params, callback) {
self.Country.findAll({
return this.sequelize.Promise.map([['ASC', 'England', 'Energy'], ['DESC', 'France', 'Media']], function(params) {
return self.Country.findAll({
include: [self.Industry],
order: [[self.Industry, self.IndustryCountry, 'numYears', params[0]]]
}).done(function(err, countries) {
expect(err).not.to.be.ok;
}).then(function(countries) {
expect(countries).to.exist;
expect(countries[0]).to.exist;
expect(countries[0].name).to.equal(params[1]);
expect(countries[0].industries).to.exist;
expect(countries[0].industries[0]).to.exist;
expect(countries[0].industries[0].name).to.equal(params[2]);
callback();
});
}, function() { done(); });
});
});
});
});
describe('normal findAll', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
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) {
return this.User.create({username: 'user', data: 'foobar', theDate: moment().toDate()}).then(function(user) {
return self.User.create({username: 'user2', data: 'bar', theDate: moment().toDate()}).then(function(user2) {
self.users = [user].concat(user2);
done();
});
});
});
it('finds all entries', function(done) {
this.User.all().on('success', function(users) {
it('finds all entries', function() {
return this.User.findAll().then(function(users) {
expect(users.length).to.equal(2);
done();
});
});
it('does not modify the passed arguments', function(done) {
it('does not modify the passed arguments', function() {
var options = { where: ['username = ?', 'awesome']};
this.User.findAll(options).success(function() {
return this.User.findAll(options).then(function() {
expect(options).to.deep.equal({ where: ['username = ?', 'awesome']});
done();
});
});
it('finds all users matching the passed conditions', function(done) {
this.User.findAll({where: 'id != ' + this.users[1].id}).success(function(users) {
it('finds all users matching the passed conditions', function() {
return this.User.findAll({where: 'id != ' + this.users[1].id}).then(function(users) {
expect(users.length).to.equal(1);
done();
});
});
it('can also handle array notation', function(done) {
it('can also handle array notation', function() {
var self = this;
this.User.findAll({where: ['id = ?', this.users[1].id]}).success(function(users) {
return this.User.findAll({where: ['id = ?', this.users[1].id]}).then(function(users) {
expect(users.length).to.equal(1);
expect(users[0].id).to.equal(self.users[1].id);
done();
});
});
it('sorts the results via id in ascending order', function(done) {
this.User.findAll().success(function(users) {
it('sorts the results via id in ascending order', function() {
return this.User.findAll().then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].id).to.be.below(users[1].id);
done();
});
});
it('sorts the results via id in descending order', function(done) {
this.User.findAll({ order: 'id DESC' }).success(function(users) {
it('sorts the results via id in descending order', function() {
return this.User.findAll({ order: 'id DESC' }).then(function(users) {
expect(users[0].id).to.be.above(users[1].id);
done();
});
});
it('sorts the results via a date column', function(done) {
it('sorts the results via a date column', function() {
var self = this;
self.User.create({username: 'user3', data: 'bar', theDate: moment().add(2, 'hours').toDate()}).success(function() {
self.User.findAll({ order: [['theDate', 'DESC']] }).success(function(users) {
return self.User.create({username: 'user3', data: 'bar', theDate: moment().add(2, 'hours').toDate()}).then(function() {
return self.User.findAll({ order: [['theDate', 'DESC']] }).then(function(users) {
expect(users[0].id).to.be.above(users[2].id);
done();
});
});
});
it('handles offset and limit', function(done) {
it('handles offset and limit', function() {
var self = this;
this.User.bulkCreate([{username: 'bobby'}, {username: 'tables'}]).success(function() {
self.User.findAll({ limit: 2, offset: 2 }).success(function(users) {
return this.User.bulkCreate([{username: 'bobby'}, {username: 'tables'}]).then(function() {
return self.User.findAll({ limit: 2, offset: 2 }).then(function(users) {
expect(users.length).to.equal(2);
expect(users[0].id).to.equal(3);
done();
});
});
});
it('should allow us to find IDs using capital letters', function(done) {
it('should allow us to find IDs using capital letters', function() {
var User = this.sequelize.define('User' + config.rand(), {
ID: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
Login: { type: Sequelize.STRING }
});
User.sync({ force: true }).success(function() {
User.create({Login: 'foo'}).success(function() {
User.findAll({ID: 1}).success(function(user) {
return User.sync({ force: true }).then(function() {
return User.create({Login: 'foo'}).then(function() {
return User.findAll({ID: 1}).then(function(user) {
expect(user).to.be.instanceof(Array);
expect(user).to.have.length(1);
done();
});
});
});
});
it('should be possible to order by sequelize.col()', function(done) {
it('should be possible to order by sequelize.col()', function() {
var self = this;
var Company = this.sequelize.define('Company', {
name: Sequelize.STRING
});
Company.sync().done(function() {
Company.findAll({
return Company.sync().then(function() {
return Company.findAll({
order: [self.sequelize.col('name')]
}).done(function(err) {
expect(err).not.to.be.ok;
done();
});
});
});
......@@ -1355,34 +1221,32 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('findAndCountAll', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.User.bulkCreate([
return this.User.bulkCreate([
{username: 'user', data: 'foobar'},
{username: 'user2', data: 'bar'},
{username: 'bobby', data: 'foo'}
]).success(function() {
self.User.all().success(function(users) {
]).then(function() {
return self.User.findAll().then(function(users) {
self.users = users;
done();
});
});
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.findAndCountAll().success(function(info1) {
User.findAndCountAll({ transaction: t }).success(function(info2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.findAndCountAll().then(function(info1) {
return User.findAndCountAll({ transaction: t }).then(function(info2) {
expect(info1.count).to.equal(0);
expect(info2.count).to.equal(1);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1392,52 +1256,47 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('handles where clause [only]', function(done) {
this.User.findAndCountAll({where: 'id != ' + this.users[0].id}).success(function(info) {
it('handles where clause [only]', function() {
return this.User.findAndCountAll({where: 'id != ' + this.users[0].id}).then(function(info) {
expect(info.count).to.equal(2);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(2);
done();
});
});
it('handles where clause with ordering [only]', function(done) {
this.User.findAndCountAll({where: 'id != ' + this.users[0].id, order: 'id ASC'}).success(function(info) {
it('handles where clause with ordering [only]', function() {
return this.User.findAndCountAll({where: 'id != ' + this.users[0].id, order: 'id ASC'}).then(function(info) {
expect(info.count).to.equal(2);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(2);
done();
});
});
it('handles offset', function(done) {
this.User.findAndCountAll({offset: 1}).success(function(info) {
it('handles offset', function() {
return this.User.findAndCountAll({offset: 1}).then(function(info) {
expect(info.count).to.equal(3);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(2);
done();
});
});
it('handles limit', function(done) {
this.User.findAndCountAll({limit: 1}).success(function(info) {
it('handles limit', function() {
return this.User.findAndCountAll({limit: 1}).then(function(info) {
expect(info.count).to.equal(3);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(1);
done();
});
});
it('handles offset and limit', function(done) {
this.User.findAndCountAll({offset: 1, limit: 1}).success(function(info) {
it('handles offset and limit', function() {
return this.User.findAndCountAll({offset: 1, limit: 1}).then(function(info) {
expect(info.count).to.equal(3);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(1);
done();
});
});
it('handles offset with includes', function(done) {
it('handles offset with includes', function() {
var Election = this.sequelize.define('Election', {
name: Sequelize.STRING
});
......@@ -1451,22 +1310,14 @@ describe(Support.getTestDialectTeaser('Model'), function() {
Citizen.hasMany(Election);
Citizen.hasMany(Election, { as: 'Votes', through: 'ElectionsVotes' });
this.sequelize.sync().done(function(err) {
expect(err).not.be.ok;
return this.sequelize.sync().then(function() {
// Add some data
Citizen.create({ name: 'Alice' }).done(function(err, alice) {
expect(err).not.be.ok;
Citizen.create({ name: 'Bob' }).done(function(err, bob) {
expect(err).not.be.ok;
Election.create({ name: 'Some election' }).done(function(err, election) {
Election.create({ name: 'Some other election' }).done(function(err, election) {
expect(err).not.be.ok;
election.setCitizen(alice).done(function(err) {
expect(err).not.be.ok;
election.setVoters([alice, bob]).done(function(err) {
expect(err).not.be.ok;
return Citizen.create({ name: 'Alice' }).then(function(alice) {
return Citizen.create({ name: 'Bob' }).then(function(bob) {
return Election.create({ name: 'Some election' }).then(function(election) {
return Election.create({ name: 'Some other election' }).then(function(election) {
return election.setCitizen(alice).then(function() {
return election.setVoters([alice, bob]).then(function() {
var criteria = {
offset: 5,
limit: 1,
......@@ -1475,11 +1326,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
{ model: Citizen, as: 'Voters' } // Election voters
]
};
Election.findAndCountAll(criteria).done(function(err, elections) {
expect(err).not.be.ok;
return Election.findAndCountAll(criteria).then(function(elections) {
expect(elections.count).to.equal(2);
expect(elections.rows.length).to.equal(0);
done();
});
});
});
......@@ -1490,41 +1339,38 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
});
it('handles attributes', function(done) {
this.User.findAndCountAll({where: 'id != ' + this.users[0].id, attributes: ['data']}).success(function(info) {
it('handles attributes', function() {
return this.User.findAndCountAll({where: 'id != ' + this.users[0].id, attributes: ['data']}).then(function(info) {
expect(info.count).to.equal(2);
expect(Array.isArray(info.rows)).to.be.ok;
expect(info.rows.length).to.equal(2);
expect(info.rows[0].dataValues).to.not.have.property('username');
expect(info.rows[1].dataValues).to.not.have.property('username');
done();
});
});
});
describe('all', function() {
beforeEach(function(done) {
this.User.bulkCreate([
beforeEach(function() {
return this.User.bulkCreate([
{username: 'user', data: 'foobar'},
{username: 'user2', data: 'bar'}
]).complete(function() {
done();
});
]);
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
it('supports transactions', function() {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING });
User.sync({ force: true }).success(function() {
sequelize.transaction().then(function(t) {
User.create({ username: 'foo' }, { transaction: t }).success(function() {
User.all().success(function(users1) {
User.all({ transaction: t }).success(function(users2) {
return User.sync({ force: true }).then(function() {
return sequelize.transaction().then(function(t) {
return User.create({ username: 'foo' }, { transaction: t }).then(function() {
return User.findAll().then(function(users1) {
return User.findAll({ transaction: t }).then(function(users2) {
expect(users1.length).to.equal(0);
expect(users2.length).to.equal(1);
t.rollback().success(function() { done(); });
return t.rollback();
});
});
});
......@@ -1534,10 +1380,9 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
}
it('should return all users', function(done) {
this.User.all().on('success', function(users) {
it('should return all users', function() {
return this.User.findAll().then(function(users) {
expect(users.length).to.equal(2);
done();
});
});
});
......
......@@ -10,7 +10,6 @@ var chai = require('chai')
, datetime = require('chai-datetime')
, _ = require('lodash')
, moment = require('moment')
, async = require('async')
, current = Support.sequelize;
chai.use(datetime);
......
......@@ -383,7 +383,7 @@ describe(Support.getTestDialectTeaser('Promise'), function() {
resolve('yoohoo');
});
promise.on('success', spy);
promise.then(spy);
promise.then(function() {
expect(spy.calledOnce).to.be.true;
expect(spy.firstCall.args).to.deep.equal(['yoohoo']);
......
......@@ -10,36 +10,23 @@ var chai = require('chai')
chai.config.includeStack = true;
describe(Support.getTestDialectTeaser('QueryInterface'), function() {
beforeEach(function(done) {
beforeEach(function() {
this.sequelize.options.quoteIdenifiers = true;
this.queryInterface = this.sequelize.getQueryInterface();
done();
});
describe('dropAllTables', function() {
it('should drop all tables', function(done) {
it('should drop all tables', function() {
var self = this;
this.queryInterface.dropAllTables().complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null;
return this.queryInterface.dropAllTables().then(function() {
return self.queryInterface.showAllTables().then(function(tableNames) {
expect(tableNames).to.be.empty;
self.queryInterface.createTable('table', { name: DataTypes.STRING }).complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null;
return self.queryInterface.createTable('table', { name: DataTypes.STRING }).then(function() {
return self.queryInterface.showAllTables().then(function(tableNames) {
expect(tableNames).to.have.length(1);
self.queryInterface.dropAllTables().complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null;
return self.queryInterface.dropAllTables().then(function() {
return self.queryInterface.showAllTables().then(function(tableNames) {
expect(tableNames).to.be.empty;
done();
});
});
});
......@@ -48,23 +35,17 @@ describe(Support.getTestDialectTeaser('QueryInterface'), function() {
});
});
it('should be able to skip given tables', function(done) {
it('should be able to skip given tables', function() {
var self = this;
self.queryInterface.createTable('skipme', {
return self.queryInterface.createTable('skipme', {
name: DataTypes.STRING
}).success(function() {
self.queryInterface.dropAllTables({skip: ['skipme']}).complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null;
}).then(function() {
return self.queryInterface.dropAllTables({skip: ['skipme']}).then(function() {
return self.queryInterface.showAllTables().then(function(tableNames) {
if (dialect === 'mssql' /* current.dialect.supports.schemas */) {
tableNames = _.pluck(tableNames, 'tableName');
}
expect(tableNames).to.contain('skipme');
done();
});
});
});
......@@ -72,41 +53,27 @@ describe(Support.getTestDialectTeaser('QueryInterface'), function() {
});
describe('indexes', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
this.queryInterface.dropTable('Group').success(function() {
self.queryInterface.createTable('Group', {
return this.queryInterface.dropTable('Group').then(function() {
return self.queryInterface.createTable('Group', {
username: DataTypes.STRING,
isAdmin: DataTypes.BOOLEAN,
from: DataTypes.STRING
}).success(function() {
done();
});
});
});
it('adds, reads and removes an index to the table', function(done) {
it('adds, reads and removes an index to the table', function() {
var self = this;
this.queryInterface.addIndex('Group', ['username', 'isAdmin']).complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showIndex('Group').complete(function(err, indexes) {
expect(err).to.be.null;
return this.queryInterface.addIndex('Group', ['username', 'isAdmin']).then(function() {
return self.queryInterface.showIndex('Group').then(function(indexes) {
var indexColumns = _.uniq(indexes.map(function(index) { return index.name; }));
expect(indexColumns).to.include('group_username_is_admin');
self.queryInterface.removeIndex('Group', ['username', 'isAdmin']).complete(function(err) {
expect(err).to.be.null;
self.queryInterface.showIndex('Group').complete(function(err, indexes) {
expect(err).to.be.null;
return self.queryInterface.removeIndex('Group', ['username', 'isAdmin']).then(function() {
return self.queryInterface.showIndex('Group').then(function(indexes) {
indexColumns = _.uniq(indexes.map(function(index) { return index.name; }));
expect(indexColumns).to.be.empty;
done();
});
});
});
......@@ -119,7 +86,7 @@ describe(Support.getTestDialectTeaser('QueryInterface'), function() {
});
describe('describeTable', function() {
it('reads the metadata of the table', function(done) {
it('reads the metadata of the table', function() {
var self = this;
var Users = self.sequelize.define('_Users', {
username: DataTypes.STRING,
......@@ -127,9 +94,8 @@ describe(Support.getTestDialectTeaser('QueryInterface'), function() {
enumVals: DataTypes.ENUM('hello', 'world')
}, { freezeTableName: true });
Users.sync({ force: true }).success(function() {
self.queryInterface.describeTable('_Users').complete(function(err, metadata) {
expect(err).to.be.null;
return Users.sync({ force: true }).then(function() {
return self.queryInterface.describeTable('_Users').then(function(metadata) {
var username = metadata.username;
var isAdmin = metadata.isAdmin;
var enumVals = metadata.enumVals;
......@@ -164,7 +130,6 @@ describe(Support.getTestDialectTeaser('QueryInterface'), function() {
expect(enumVals.special).to.be.instanceof(Array);
expect(enumVals.special).to.have.length(2);
}
done();
});
});
});
......
......@@ -44,19 +44,17 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
}
it('should pass the global options correctly', function(done) {
it('should pass the global options correctly', function() {
var sequelize = Support.createSequelizeInstance({ logging: false, define: { underscored: true } })
, DAO = sequelize.define('dao', {name: DataTypes.STRING});
expect(DAO.options.underscored).to.be.ok;
done();
});
it('should correctly set the host and the port', function(done) {
it('should correctly set the host and the port', function() {
var sequelize = Support.createSequelizeInstance({ host: '127.0.0.1', port: 1234 });
expect(sequelize.config.port).to.equal(1234);
expect(sequelize.config.host).to.equal('127.0.0.1');
done();
});
if (dialect === 'sqlite') {
......@@ -87,8 +85,8 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
if (dialect !== 'sqlite') {
describe('authenticate', function() {
describe('with valid credentials', function() {
it('triggers the success event', function(done) {
this.sequelize.authenticate().success(done);
it('triggers the success event', function() {
return this.sequelize.authenticate();
});
});
......@@ -98,22 +96,20 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
this.sequelizeWithInvalidConnection = new Sequelize('wat', 'trololo', 'wow', options);
});
it('triggers the error event', function(done) {
this
it('triggers the error event', function() {
return this
.sequelizeWithInvalidConnection
.authenticate()
.complete(function(err, result) {
.catch(function(err) {
expect(err).to.not.be.null;
done();
});
});
it('triggers the actual adapter error', function(done) {
this
it('triggers the actual adapter error', function() {
return this
.sequelizeWithInvalidConnection
.authenticate()
.complete(function(err, result) {
.catch(function(err) {
console.log(err.message);
expect(
err.message.match(/connect ECONNREFUSED/) ||
......@@ -123,8 +119,6 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
err.message.match(/RangeError: port should be >= 0 and < 65536: 99999/) ||
err.message.match(/ConnectionError: Login failed for user/)
).to.be.ok;
done();
});
});
});
......@@ -134,18 +128,17 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
this.sequelizeWithInvalidCredentials = new Sequelize('localhost', 'wtf', 'lol', this.sequelize.options);
});
it('triggers the error event', function(done) {
this
it('triggers the error event', function() {
return this
.sequelizeWithInvalidCredentials
.authenticate()
.complete(function(err, result) {
.catch(function(err) {
expect(err).to.not.be.null;
done();
});
});
it('triggers the error event when using replication', function(done) {
new Sequelize('sequelize', null, null, {
it('triggers the error event when using replication', function() {
return new Sequelize('sequelize', null, null, {
replication: {
read: {
host: 'localhost',
......@@ -154,9 +147,8 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
}
}
}).authenticate()
.complete(function(err, result) {
.catch(function(err) {
expect(err).to.not.be.null;
done();
});
});
});
......@@ -206,37 +198,26 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
describe('query', function() {
afterEach(function(done) {
afterEach(function() {
this.sequelize.options.quoteIdentifiers = true;
done();
});
beforeEach(function(done) {
beforeEach(function() {
this.User = this.sequelize.define('User', {
username: DataTypes.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.User.sync({ force: true }).success(function() {
done();
});
return this.User.sync({ force: true });
});
it('executes a query the internal way', function(done) {
this.sequelize.query(this.insertQuery, null, { raw: true })
.complete(function(err, result) {
expect(err).to.be.null;
done();
});
it('executes a query the internal way', function() {
return this.sequelize.query(this.insertQuery, null, { raw: true });
});
it('executes a query if only the sql is passed', function(done) {
this.sequelize.query(this.insertQuery)
.complete(function(err, result) {
expect(err).to.be.null;
done();
});
it('executes a query if only the sql is passed', function() {
return this.sequelize.query(this.insertQuery);
});
it('executes select queries correctly', function() {
......@@ -283,16 +264,15 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
if (Support.dialectIsMySQL()) {
it('executes stored procedures', function(done) {
it('executes stored procedures', function() {
var self = this;
self.sequelize.query(this.insertQuery).success(function() {
self.sequelize.query('DROP PROCEDURE IF EXISTS foo').success(function() {
self.sequelize.query(
return self.sequelize.query(this.insertQuery).then(function() {
return self.sequelize.query('DROP PROCEDURE IF EXISTS foo').then(function() {
return self.sequelize.query(
'CREATE PROCEDURE foo()\nSELECT * FROM ' + self.User.tableName + ';'
).success(function() {
self.sequelize.query('CALL foo()').success(function(users) {
).then(function() {
return self.sequelize.query('CALL foo()').then(function(users) {
expect(users.map(function(u) { return u.username; })).to.include('john');
done();
});
});
});
......@@ -313,12 +293,12 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
it('throw an exception if `values` and `options.replacements` are both passed', function() {
var self = this;
expect(function() {
self.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, null, { raw: true, replacements: [1, 2] });
return self.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, null, { raw: true, replacements: [1, 2] });
}).to.throw(Error, 'Both `sql.values` and `options.replacements` cannot be set at the same time');
});
it('uses properties `query` and `values` if query is tagged', function() {
return this.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, null, { type: this.sequelize.QueryTypes.SELECT }).success(function(result) {
return this.sequelize.query({ query: 'select ? as foo, ? as bar', values: [1, 2] }, null, { type: this.sequelize.QueryTypes.SELECT }).then(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2 }]);
});
});
......@@ -330,20 +310,18 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
return expect(this.sequelize.query(sql, null, { raw: true, nest: false }).get(0)).to.eventually.deep.equal([{ 'foo.bar.baz': 1 }]);
});
it('destructs dot separated attributes when doing a raw query using nest', function(done) {
it('destructs dot separated attributes when doing a raw query using nest', function() {
var tickChar = (dialect === 'postgres' || dialect === 'mssql') ? '"' : '`'
, sql = 'select 1 as ' + Sequelize.Utils.addTicks('foo.bar.baz', tickChar);
this.sequelize.query(sql, null, { raw: true, nest: true }).success(function(result) {
return this.sequelize.query(sql, null, { raw: true, nest: true }).then(function(result) {
expect(result).to.deep.equal([{ foo: { bar: { baz: 1 } } }]);
done();
});
});
it('replaces token with the passed array', function(done) {
this.sequelize.query('select ? as foo, ? as bar', null, { type: this.sequelize.QueryTypes.SELECT, replacements: [1, 2] }).success(function(result) {
it('replaces token with the passed array', function() {
return this.sequelize.query('select ? as foo, ? as bar', null, { type: this.sequelize.QueryTypes.SELECT, replacements: [1, 2] }).then(function(result) {
expect(result).to.deep.equal([{ foo: 1, bar: 2 }]);
done();
});
});
......@@ -576,35 +554,31 @@ describe(Support.getTestDialectTeaser('Sequelize'), 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() {
var count = this.sequelize.daoFactoryManager.all.length;
this.sequelize.define('foo', { title: DataTypes.STRING });
expect(this.sequelize.daoFactoryManager.all.length).to.equal(count+1);
done();
});
it('adds a new dao to sequelize.models', function(done) {
it('adds a new dao to sequelize.models', function() {
expect(this.sequelize.models.bar).to.equal(undefined);
var Bar = this.sequelize.define('bar', { title: DataTypes.STRING });
expect(this.sequelize.models.bar).to.equal(Bar);
done();
});
it('overwrites global options', function(done) {
it('overwrites global options', function() {
var sequelize = Support.createSequelizeInstance({ define: { collate: 'utf8_general_ci' } });
var DAO = sequelize.define('foo', {bar: DataTypes.STRING}, {collate: 'utf8_bin'});
expect(DAO.options.collate).to.equal('utf8_bin');
done();
});
it('inherits global collate option', function(done) {
it('inherits global collate option', function() {
var sequelize = Support.createSequelizeInstance({ define: { collate: 'utf8_general_ci' } });
var DAO = sequelize.define('foo', {bar: DataTypes.STRING});
expect(DAO.options.collate).to.equal('utf8_general_ci');
done();
});
it('inherits global classMethods and instanceMethods, and can override global methods with local ones', function(done) {
it('inherits global classMethods and instanceMethods, and can override global methods with local ones', function() {
var globalClassMethod = sinon.spy()
, globalInstanceMethod = sinon.spy()
, localClassMethod = sinon.spy()
......@@ -655,58 +629,53 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
expect(localClassMethod).to.have.been.calledOnce;
expect(localInstanceMethod).to.have.been.calledOnce;
done();
});
it('uses the passed tableName', function(done) {
it('uses the passed tableName', function() {
var self = this
, Photo = this.sequelize.define('Foto', { name: DataTypes.STRING }, { tableName: 'photos' });
Photo.sync({ force: true }).success(function() {
self.sequelize.getQueryInterface().showAllTables().success(function(tableNames) {
return Photo.sync({ force: true }).then(function() {
return self.sequelize.getQueryInterface().showAllTables().then(function(tableNames) {
if (dialect === 'mssql' /* current.dialect.supports.schemas */) {
tableNames = _.pluck(tableNames, 'tableName');
}
expect(tableNames).to.include('photos');
done();
});
});
});
});
describe('sync', function() {
it('synchronizes all daos', function(done) {
it('synchronizes all daos', function() {
var Project = this.sequelize.define('project' + config.rand(), { title: DataTypes.STRING });
var Task = this.sequelize.define('task' + config.rand(), { title: DataTypes.STRING });
Project.sync({ force: true }).success(function() {
Task.sync({ force: true }).success(function() {
Project.create({title: 'bla'}).success(function() {
Task.create({title: 'bla'}).success(function(task) {
return Project.sync({ force: true }).then(function() {
return Task.sync({ force: true }).then(function() {
return Project.create({title: 'bla'}).then(function() {
return Task.create({title: 'bla'}).then(function(task) {
expect(task).to.exist;
expect(task.title).to.equal('bla');
done();
});
});
});
});
});
it('works with correct database credentials', function(done) {
it('works with correct database credentials', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING });
User.sync().success(function() {
return User.sync().then(function() {
expect(true).to.be.true;
done();
});
});
if (dialect !== 'sqlite') {
it('fails with incorrect database credentials (1)', function(done) {
it('fails with incorrect database credentials (1)', function() {
this.sequelizeWithInvalidCredentials = new Sequelize('omg', 'bar', null, _.omit(this.sequelize.options, ['host']));
var User2 = this.sequelizeWithInvalidCredentials.define('User', { name: DataTypes.STRING, bio: DataTypes.TEXT });
User2.sync().error(function(err) {
return User2.sync().catch(function(err) {
if (dialect === 'postgres' || dialect === 'postgres-native') {
assert([
'fe_sendauth: no password supplied',
......@@ -719,11 +688,10 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
} else {
expect(err.message.toString()).to.match(/.*Access\ denied.*/);
}
done();
});
});
it('fails with incorrect database credentials (2)', function(done) {
it('fails with incorrect database credentials (2)', function() {
var sequelize = new Sequelize('db', 'user', 'pass', {
dialect: this.sequelize.options.dialect
});
......@@ -731,13 +699,12 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
var Project = sequelize.define('Project', {title: Sequelize.STRING});
var Task = sequelize.define('Task', {title: Sequelize.STRING});
sequelize.sync({force: true}).done(function(err) {
return sequelize.sync({force: true}).catch(function(err) {
expect(err).to.be.ok;
done();
});
});
it('fails with incorrect database credentials (3)', function(done) {
it('fails with incorrect database credentials (3)', function() {
var sequelize = new Sequelize('db', 'user', 'pass', {
dialect: this.sequelize.options.dialect,
port: 99999
......@@ -746,13 +713,12 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
var Project = sequelize.define('Project', {title: Sequelize.STRING});
var Task = sequelize.define('Task', {title: Sequelize.STRING});
sequelize.sync({force: true}).done(function(err) {
return sequelize.sync({force: true}).catch(function(err) {
expect(err).to.be.ok;
done();
});
});
it('fails with incorrect database credentials (4)', function(done) {
it('fails with incorrect database credentials (4)', function() {
var sequelize = new Sequelize('db', 'user', 'pass', {
dialect: this.sequelize.options.dialect,
port: 99999,
......@@ -762,24 +728,22 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
var Project = sequelize.define('Project', {title: Sequelize.STRING});
var Task = sequelize.define('Task', {title: Sequelize.STRING});
sequelize.sync({force: true}).done(function(err) {
return sequelize.sync({force: true}).catch(function(err) {
expect(err).to.be.ok;
done();
});
});
it('returns an error correctly if unable to sync a foreign key referenced model', function(done) {
it('returns an error correctly if unable to sync a foreign key referenced model', function() {
var Application = this.sequelize.define('Application', {
authorID: { type: Sequelize.BIGINT, allowNull: false, references: 'User', referencesKey: 'id' }
});
this.sequelize.sync().error(function(error) {
return this.sequelize.sync().catch(function(error) {
assert.ok(error);
done();
});
});
it('handles self dependant foreign key constraints', function(done) {
it('handles self dependant foreign key constraints', function() {
var block = this.sequelize.define('block', {
id: { type: DataTypes.INTEGER, primaryKey: true },
name: DataTypes.STRING
......@@ -804,37 +768,33 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
foreignKeyConstraint: true
});
this.sequelize.sync().done(done);
return this.sequelize.sync();
});
}
describe("doesn't emit logging when explicitly saying not to", function() {
afterEach(function(done) {
afterEach(function() {
this.sequelize.options.logging = false;
done();
});
beforeEach(function(done) {
beforeEach(function() {
this.spy = sinon.spy();
var self = this;
this.sequelize.options.logging = function() { self.spy(); };
this.User = this.sequelize.define('UserTest', { username: DataTypes.STRING });
done();
});
it('through Sequelize.sync()', function(done) {
it('through Sequelize.sync()', function() {
var self = this;
this.sequelize.sync({ force: true, logging: false }).success(function() {
return this.sequelize.sync({ force: true, logging: false }).then(function() {
expect(self.spy.notCalled).to.be.true;
done();
});
});
it('through DAOFactory.sync()', function(done) {
it('through DAOFactory.sync()', function() {
var self = this;
this.User.sync({ force: true, logging: false }).success(function() {
return this.User.sync({ force: true, logging: false }).then(function() {
expect(self.spy.notCalled).to.be.true;
done();
});
});
});
......@@ -846,7 +806,7 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
match: /alibabaizshaek/
}).then(function() {
throw new Error('I should not have succeeded!');
}, function(err) {
}).catch(function(err) {
assert(true);
});
});
......@@ -854,26 +814,22 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
describe('drop should work', function() {
it('correctly succeeds', function(done) {
it('correctly succeeds', function() {
var User = this.sequelize.define('Users', {username: DataTypes.STRING });
User.sync({ force: true }).success(function() {
User.drop().success(function() {
expect(true).to.be.true;
done();
});
return User.sync({ force: true }).then(function() {
return User.drop();
});
});
});
describe('import', function() {
it('imports a dao definition from a file absolute path', function(done) {
it('imports a dao definition from a file absolute path', function() {
var Project = this.sequelize.import(__dirname + '/assets/project');
expect(Project).to.exist;
done();
});
it('imports a dao definition from a function', function(done) {
it('imports a dao definition from a function', function() {
var Project = this.sequelize.import('Project', function(sequelize, DataTypes) {
return sequelize.define('Project' + parseInt(Math.random() * 9999999999999999), {
name: DataTypes.STRING
......@@ -881,7 +837,6 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
expect(Project).to.exist;
done();
});
});
......@@ -891,45 +846,39 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
DataTypes.ENUM('scheduled', 'active', 'finished')
].forEach(function(status) {
describe('enum', function() {
beforeEach(function(done) {
beforeEach(function() {
this.Review = this.sequelize.define('review', { status: status });
this.Review.sync({ force: true }).success(function() {
done();
});
return this.Review.sync({ force: true });
});
it('raises an error if no values are defined', function(done) {
it('raises an error if no values are defined', function() {
var self = this;
expect(function() {
self.sequelize.define('omnomnom', {
bla: { type: DataTypes.ENUM }
});
}).to.throw(Error, 'Values for ENUM haven\'t been defined.');
done();
});
it('correctly stores values', function(done) {
this.Review.create({ status: 'active' }).success(function(review) {
it('correctly stores values', function() {
return this.Review.create({ status: 'active' }).then(function(review) {
expect(review.status).to.equal('active');
done();
});
});
it('correctly loads values', function(done) {
it('correctly loads values', function() {
var self = this;
this.Review.create({ status: 'active' }).success(function() {
self.Review.findAll().success(function(reviews) {
return this.Review.create({ status: 'active' }).then(function() {
return self.Review.findAll().then(function(reviews) {
expect(reviews[0].status).to.equal('active');
done();
});
});
});
it("doesn't save an instance if value is not in the range of enums", function(done) {
this.Review.create({status: 'fnord'}).error(function(err) {
it("doesn't save an instance if value is not in the range of enums", function() {
return this.Review.create({status: 'fnord'}).catch(function(err) {
expect(err).to.be.instanceOf(Error);
expect(err.get('status')[0].message).to.equal('Value "fnord" for ENUM status is out of allowed scope. Allowed values: scheduled, active, finished');
done();
});
});
});
......@@ -942,9 +891,9 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
{ id: { type: DataTypes.BIGINT, allowNull: false, primaryKey: true, autoIncrement: true } }
].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() {
var Picture = this.sequelize.define('picture', _.cloneDeep(customAttributes));
Picture.sync({ force: true }).success(function() {
return Picture.sync({ force: true }).then(function() {
Object.keys(customAttributes).forEach(function(attribute) {
Object.keys(customAttributes[attribute]).forEach(function(option) {
var optionValue = customAttributes[attribute][option];
......@@ -955,7 +904,6 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
}
});
});
done();
});
});
......@@ -964,12 +912,11 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
if (current.dialect.supports.transactions) {
describe('transaction', function() {
beforeEach(function(done) {
beforeEach(function() {
var self = this;
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
return Support.prepareTransactionTest(this.sequelize).bind({}).then(function(sequelize) {
self.sequelizeWithTransaction = sequelize;
done();
});
});
......@@ -977,18 +924,16 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
expect(Support.Sequelize).to.respondTo('transaction');
});
it('passes a transaction object to the callback', function(done) {
this.sequelizeWithTransaction.transaction().then(function(t) {
it('passes a transaction object to the callback', function() {
return this.sequelizeWithTransaction.transaction().then(function(t) {
expect(t).to.be.instanceOf(Transaction);
done();
});
});
it('allows me to define a callback on the result', function(done) {
this
.sequelizeWithTransaction
.transaction().then(function(t) { t.commit(); })
.done(done);
it('allows me to define a callback on the result', function() {
return this.sequelizeWithTransaction.transaction().then(function(t) {
return t.commit();
});
});
if (dialect === 'sqlite') {
......@@ -1061,22 +1006,19 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
}
it('supports nested transactions using savepoints', function(done) {
it('supports nested transactions using savepoints', function() {
var self = this;
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING });
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.commit().then(function() {
user.reload({ transaction: t1 }).success(function(newUser) {
return User.sync({ force: true }).then(function() {
return self.sequelizeWithTransaction.transaction().then(function(t1) {
return User.create({ username: 'foo' }, { transaction: t1 }).then(function(user) {
return self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
return user.updateAttributes({ username: 'bar' }, { transaction: t2 }).then(function() {
return t2.commit().then(function() {
return user.reload({ transaction: t1 }).then(function(newUser) {
expect(newUser.username).to.equal('bar');
t1.commit().then(function() {
done();
});
return t1.commit();
});
});
});
......@@ -1149,22 +1091,19 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
});
it('supports rolling back a nested transaction', function(done) {
it('supports rolling back a nested transaction', function() {
var self = this;
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING });
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t2.rollback().then(function() {
user.reload({ transaction: t1 }).success(function(newUser) {
return User.sync({ force: true }).then(function() {
return self.sequelizeWithTransaction.transaction().then(function(t1) {
return User.create({ username: 'foo' }, { transaction: t1 }).then(function(user) {
return self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
return user.updateAttributes({ username: 'bar' }, { transaction: t2 }).then(function() {
return t2.rollback().then(function() {
return user.reload({ transaction: t1 }).then(function(newUser) {
expect(newUser.username).to.equal('foo');
t1.commit().then(function() {
done();
});
return t1.commit();
});
});
});
......@@ -1174,19 +1113,18 @@ describe(Support.getTestDialectTeaser('Sequelize'), function() {
});
});
it('supports rolling back outermost transaction', function(done) {
it('supports rolling back outermost transaction', function() {
var self = this;
var User = this.sequelizeWithTransaction.define('Users', { username: DataTypes.STRING });
User.sync({ force: true }).success(function() {
self.sequelizeWithTransaction.transaction().then(function(t1) {
User.create({ username: 'foo' }, { transaction: t1 }).success(function(user) {
self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
user.updateAttributes({ username: 'bar' }, { transaction: t2 }).success(function() {
t1.rollback().then(function() {
User.findAll().success(function(users) {
return User.sync({ force: true }).then(function() {
return self.sequelizeWithTransaction.transaction().then(function(t1) {
return User.create({ username: 'foo' }, { transaction: t1 }).then(function(user) {
return self.sequelizeWithTransaction.transaction({ transaction: t1 }).then(function(t2) {
return user.updateAttributes({ username: 'bar' }, { transaction: t2 }).then(function() {
return t1.rollback().then(function() {
return User.findAll().then(function(users) {
expect(users.length).to.equal(0);
done();
});
});
});
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!