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

Commit 64349b7b by Sascha Depold

Merge branch 'mocha' of github.com:sequelize/sequelize into mocha

2 parents db577ddb ffc8030e
...@@ -13,4 +13,20 @@ mysql: ...@@ -13,4 +13,20 @@ mysql:
--reporter $(REPORTER) \ --reporter $(REPORTER) \
$(TESTS) $(TESTS)
.PHONY: sqlite mysql postgres:
\ No newline at end of file @DIALECT=postgres ./node_modules/mocha/bin/mocha \
--colors \
--reporter $(REPORTER) \
$(TESTS)
pgsql: postgres
postgres-native:
@DIALECT=postgres-native ./node_modules/mocha/bin/mocha \
--colors \
--reporter $(REPORTER) \
$(TESTS)
postgresn: postgres-native
.PHONY: sqlite mysql postgres pgsql postgres-native postgresn
\ No newline at end of file
...@@ -386,4 +386,4 @@ module.exports = (function() { ...@@ -386,4 +386,4 @@ module.exports = (function() {
} }
return ConnectorManager return ConnectorManager
})() })()
\ No newline at end of file
...@@ -29,9 +29,8 @@ module.exports = (function() { ...@@ -29,9 +29,8 @@ module.exports = (function() {
return Utils._.template(query)({}) return Utils._.template(query)({})
}, },
dropSchema: function() { dropSchema: function(tableName, options) {
var query = "SHOW TABLES" return QueryGenerator.dropTableQuery(tableName, options)
return Utils._.template(query)({})
}, },
showSchemasQuery: function() { showSchemasQuery: function() {
......
...@@ -6,11 +6,12 @@ module.exports = (function() { ...@@ -6,11 +6,12 @@ module.exports = (function() {
var pgModule = config.dialectModulePath || 'pg' var pgModule = config.dialectModulePath || 'pg'
this.sequelize = sequelize this.sequelize = sequelize
this.client = null this.client = null
this.config = config || {} this.config = config || {}
this.config.port = this.config.port || 5432 this.config.port = this.config.port || 5432
this.pooling = (!!this.config.poolCfg && (this.config.poolCfg.maxConnections > 0)) this.pooling = (!!this.config.pool && (this.config.pool.maxConnections > 0))
this.pg = this.config.native ? require(pgModule).native : require(pgModule) this.pg = this.config.native ? require(pgModule).native : require(pgModule)
this.poolIdentifier = null
// Better support for BigInts // Better support for BigInts
// https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935 // https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935
...@@ -18,52 +19,60 @@ module.exports = (function() { ...@@ -18,52 +19,60 @@ module.exports = (function() {
// set pooling parameters if specified // set pooling parameters if specified
if (this.pooling) { if (this.pooling) {
this.pg.defaults.poolSize = this.config.poolCfg.maxConnections this.pg.defaults.poolSize = this.config.pool.maxConnections
this.pg.defaults.poolIdleTimeout = this.config.poolCfg.maxIdleTime this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime
} }
this.disconnectTimeoutId = null this.disconnectTimeoutId = null
this.pendingQueries = 0 this.pendingQueries = 0
this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50) this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50)
process.on('exit', function() {
this.disconnect()
}.bind(this))
} }
Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype) Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype)
var isConnecting = false ConnectorManager.prototype.endQuery = function() {
var isConnected = false
ConnectorManager.prototype.query = function(sql, callee, options) {
var self = this var self = this
if (this.client === null) { if (!self.pooling && self.pendingQueries === 0) {
this.connect() setTimeout(function() {
self.pendingQueries === 0 && self.disconnect.call(self)
}, 100)
} }
var query = new Query(this.client, this.sequelize, callee, options || {})
self.pendingQueries += 1
return query.run(sql)
.success(function() { self.endQuery.call(self) })
.error(function() { self.endQuery.call(self) })
} }
ConnectorManager.prototype.endQuery = function() { ConnectorManager.prototype.query = function(sql, callee, options) {
var self = this var self = this
self.pendingQueries -= 1
if (self.pendingQueries == 0) { self.pendingQueries++
setTimeout(function() {
self.pendingQueries == 0 && self.disconnect.call(self) return new Utils.CustomEventEmitter(function(emitter) {
}, 100) self.connect()
} .on('error', function(err) {
emitter.emit('error', err)
})
.on('success', function(done) {
var query = new Query(self.client, self.sequelize, callee, options || {})
done = done || null
query.run(sql, done)
.success(function(results) { emitter.emit('success', results); self.endQuery.call(self) })
.error(function(err) { emitter.emit('error', err); self.endQuery.call(self) })
.on('sql', function(sql) { emitter.emit('sql', sql) })
})
}).run().complete(function() { self.pendingQueries-- })
} }
ConnectorManager.prototype.connect = function() { ConnectorManager.prototype.connect = function(callback) {
var self = this var self = this
var emitter = new (require('events').EventEmitter)() var emitter = new (require('events').EventEmitter)()
// in case database is slow to connect, prevent orphaning the client // in case database is slow to connect, prevent orphaning the client
if (this.isConnecting) { if (this.isConnecting) {
return emitter.emit('success')
return emitter
} }
this.isConnecting = true this.isConnecting = true
...@@ -71,36 +80,44 @@ module.exports = (function() { ...@@ -71,36 +80,44 @@ module.exports = (function() {
var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config) var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config)
var connectCallback = function(err, client) { var connectCallback = function(err, client, done) {
self.isConnecting = false self.isConnecting = false
if (!!err) { if (!!err) {
switch(err.code) { // release the pool immediately, very important.
case 'ECONNREFUSED': done && done(err)
emitter.emit('error', 'Failed to authenticate for PostgresSQL. Please double check your settings.')
break if (err.code) {
case 'ENOTFOUND': switch(err.code) {
case 'EHOSTUNREACH': case 'ECONNREFUSED':
case 'EINVAL': emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings."))
emitter.emit('error', 'Failed to find PostgresSQL server. Please double check your settings.') break
break case 'ENOTFOUND':
default: case 'EHOSTUNREACH':
emitter.emit('error', err) case 'EINVAL':
emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings."))
break
default:
emitter.emit('error', err)
break
}
} }
} else if (client) { } else if (client) {
client.query("SET TIME ZONE 'UTC'") client.query("SET TIME ZONE 'UTC'").on('end', function() {
.on('end', function() {
self.isConnected = true self.isConnected = true
this.client = client self.client = client
emitter.emit('success', done)
}); });
} else { } else {
this.client = null self.client = null
emitter.emit('success', done)
} }
} }
if (this.pooling) { if (this.pooling) {
// acquire client from pool // acquire client from pool
this.pg.connect(uri, connectCallback) this.poolIdentifier = this.pg.pools.getOrCreate(this.sequelize.config)
this.poolIdentifier.connect(connectCallback)
} else { } else {
//create one-off client //create one-off client
this.client = new this.pg.Client(uri) this.client = new this.pg.Client(uri)
...@@ -111,8 +128,14 @@ module.exports = (function() { ...@@ -111,8 +128,14 @@ module.exports = (function() {
} }
ConnectorManager.prototype.disconnect = function() { ConnectorManager.prototype.disconnect = function() {
var self = this if (this.poolIdentifier) {
if (this.client) this.client.end() this.poolIdentifier.destroyAllNow()
}
if (this.client) {
this.client.end()
}
this.client = null this.client = null
this.isConnecting = false this.isConnecting = false
this.isConnected = false this.isConnected = false
......
...@@ -18,16 +18,17 @@ module.exports = (function() { ...@@ -18,16 +18,17 @@ module.exports = (function() {
} }
Utils.inherit(Query, AbstractQuery) Utils.inherit(Query, AbstractQuery)
Query.prototype.run = function(sql) { Query.prototype.run = function(sql, done) {
this.sql = sql this.sql = sql
var self = this
if (this.options.logging !== false) { if (this.options.logging !== false) {
this.options.logging('Executing: ' + this.sql) this.options.logging('Executing: ' + this.sql)
} }
var receivedError = false var receivedError = false
, query = this.client.query(sql) , query = this.client.query(sql)
, rows = [] , rows = []
query.on('row', function(row) { query.on('row', function(row) {
rows.push(row) rows.push(row)
...@@ -39,13 +40,14 @@ module.exports = (function() { ...@@ -39,13 +40,14 @@ module.exports = (function() {
}.bind(this)) }.bind(this))
query.on('end', function() { query.on('end', function() {
done && done()
this.emit('sql', this.sql) this.emit('sql', this.sql)
if (receivedError) { if (receivedError) {
return return
} }
onSuccess.call(this, rows) onSuccess.call(this, rows, sql)
}.bind(this)) }.bind(this))
return this return this
...@@ -55,11 +57,11 @@ module.exports = (function() { ...@@ -55,11 +57,11 @@ module.exports = (function() {
return 'id' return 'id'
} }
var onSuccess = function(rows) { var onSuccess = function(rows, sql) {
var results = [] var results = []
, self = this , self = this
, isTableNameQuery = (this.sql.indexOf('SELECT table_name FROM information_schema.tables') === 0) , isTableNameQuery = (sql.indexOf('SELECT table_name FROM information_schema.tables') === 0)
, isRelNameQuery = (this.sql.indexOf('SELECT relname FROM pg_class WHERE oid IN') === 0) , isRelNameQuery = (sql.indexOf('SELECT relname FROM pg_class WHERE oid IN') === 0)
if (isTableNameQuery || isRelNameQuery) { if (isTableNameQuery || isRelNameQuery) {
if (isRelNameQuery) { if (isRelNameQuery) {
...@@ -70,7 +72,7 @@ module.exports = (function() { ...@@ -70,7 +72,7 @@ module.exports = (function() {
} }
}) })
} else { } else {
results = rows.map(function(row) { return Utils._.values(row) }) results = rows.map(function(row) { return Utils._.values(row) })
} }
return this.emit('success', results) return this.emit('success', results)
} }
......
...@@ -37,9 +37,8 @@ module.exports = (function() { ...@@ -37,9 +37,8 @@ module.exports = (function() {
return Utils._.template(query)({}) return Utils._.template(query)({})
}, },
dropSchema: function() { dropSchema: function(tableName, options) {
var query = "SELECT name FROM sqlite_master WHERE type='table' and name!='sqlite_sequence';" return this.dropTableQuery(tableName, options)
return Utils._.template(query)({})
}, },
showSchemasQuery: function() { showSchemasQuery: function() {
...@@ -89,6 +88,16 @@ module.exports = (function() { ...@@ -89,6 +88,16 @@ module.exports = (function() {
return this.replaceBooleanDefaults(sql) return this.replaceBooleanDefaults(sql)
}, },
dropTableQuery: function(tableName, options) {
options = options || {}
var query = "DROP TABLE IF EXISTS <%= table %>;"
return Utils._.template(query)({
table: this.quoteIdentifier(tableName)
})
},
addColumnQuery: function() { addColumnQuery: function() {
var sql = MySqlQueryGenerator.addColumnQuery.apply(this, arguments) var sql = MySqlQueryGenerator.addColumnQuery.apply(this, arguments)
return this.replaceBooleanDefaults(sql) return this.replaceBooleanDefaults(sql)
...@@ -134,6 +143,7 @@ module.exports = (function() { ...@@ -134,6 +143,7 @@ module.exports = (function() {
return Utils._.template(query)(replacements) return Utils._.template(query)(replacements)
}, },
selectQuery: function(tableName, options) { selectQuery: function(tableName, options) {
var table = null, var table = null,
joinQuery = "" joinQuery = ""
......
...@@ -54,6 +54,12 @@ module.exports = (function() { ...@@ -54,6 +54,12 @@ module.exports = (function() {
return this return this
} }
CustomEventEmitter.prototype.sql =
function(fct) {
this.on('sql', bindToProcess(fct))
return this;
}
CustomEventEmitter.prototype.proxy = function(emitter) { CustomEventEmitter.prototype.proxy = function(emitter) {
proxyEventKeys.forEach(function (eventKey) { proxyEventKeys.forEach(function (eventKey) {
this.on(eventKey, function (result) { this.on(eventKey, function (result) {
......
...@@ -54,7 +54,7 @@ module.exports = (function() { ...@@ -54,7 +54,7 @@ module.exports = (function() {
var showSchemasSql = self.QueryGenerator.showSchemasQuery() var showSchemasSql = self.QueryGenerator.showSchemasQuery()
self.sequelize.query(showSchemasSql, null, { raw: true }).success(function(schemaNames) { self.sequelize.query(showSchemasSql, null, { raw: true }).success(function(schemaNames) {
self.emit('showAllSchemas', null) self.emit('showAllSchemas', null)
emitter.emit('success', Utils._.flatten(Utils._.map(schemaNames, function(value){ return value.schema_name }))) emitter.emit('success', Utils._.flatten(Utils._.map(schemaNames, function(value){ return (!!value.schema_name ? value.schema_name : value) })))
}).error(function(err) { }).error(function(err) {
self.emit('showAllSchemas', err) self.emit('showAllSchemas', err)
emitter.emit('error', err) emitter.emit('error', err)
...@@ -300,7 +300,6 @@ module.exports = (function() { ...@@ -300,7 +300,6 @@ module.exports = (function() {
emitter.emit('sql', sql) emitter.emit('sql', sql)
}) })
.on('sql', function(sql) { .on('sql', function(sql) {
console.log('SQL!');
emitter.emit('sql', sql) emitter.emit('sql', sql)
}) })
}).run() }).run()
......
...@@ -88,9 +88,12 @@ var Utils = module.exports = { ...@@ -88,9 +88,12 @@ var Utils = module.exports = {
type = typeof where[i] type = typeof where[i]
_where[i] = _where[i] || {} _where[i] = _where[i] || {}
if (Array.isArray(where[i])) { if (where[i] === null) {
// skip nulls
}
else if (Array.isArray(where[i])) {
_where[i].in = _where[i].in || [] _where[i].in = _where[i].in || []
_where[i].in.concat(where[i]); _where[i].in.concat(where[i])
} }
else if (type === "object") { else if (type === "object") {
Object.keys(where[i]).forEach(function(ii) { Object.keys(where[i]).forEach(function(ii) {
......
...@@ -46,14 +46,12 @@ ...@@ -46,14 +46,12 @@
"devDependencies": { "devDependencies": {
"sqlite3": "~2.1.12", "sqlite3": "~2.1.12",
"mysql": "~2.0.0-alpha8", "mysql": "~2.0.0-alpha8",
"pg": "~2.1.0", "pg": "~2.2.0",
"buster": "~0.6.3", "buster": "~0.6.3",
"watchr": "~2.4.3", "watchr": "~2.4.3",
"yuidocjs": "~0.3.36", "yuidocjs": "~0.3.36",
"semver": "~2.0.8",
"chai": "~1.7.2", "chai": "~1.7.2",
"mocha": "~1.12.0", "mocha": "~1.12.0",
"sinon-chai": "~2.4.0",
"chai-datetime": "~1.0.0" "chai-datetime": "~1.0.0"
}, },
"keywords": [ "keywords": [
......
...@@ -26,6 +26,6 @@ module.exports = { ...@@ -26,6 +26,6 @@ module.exports = {
database: 'sequelize_test', database: 'sequelize_test',
username: "postgres", username: "postgres",
port: 5432, port: 5432,
pool: { maxConnections: 5, maxIdleTime: 30} pool: { maxConnections: 5, maxIdleTime: 3000}
} }
} }
var chai = require('chai') var chai = require('chai')
, expect = chai.expect , expect = chai.expect
, semver = require("semver")
, config = require(__dirname + "/config/config") , config = require(__dirname + "/config/config")
, Support = require(__dirname + '/support') , Support = require(__dirname + '/support')
, dialect = Support.getTestDialect() , dialect = Support.getTestDialect()
, Sequelize = require(__dirname + '/../index') , Sequelize = require(__dirname + '/../index')
, noDomains = semver.lt(process.version, '0.8.0')
chai.Assertion.includeStack = true chai.Assertion.includeStack = true
describe(Support.getTestDialectTeaser("Configuration"), function() { describe(Support.getTestDialectTeaser("Configuration"), function() {
describe.skip('Connections problems should fail with a nice message', function() { describe('Connections problems should fail with a nice message', function() {
it("when we don't have the correct server details", function(done) { it("when we don't have the correct server details", function(done) {
if (noDomains === true) { // mysql is not properly supported due to the custom pooling system
console.log('WARNING: Configuration specs requires NodeJS version >= 0.8 for full compatibility') if (dialect !== "postgres" && dialect !== "postgres-native") {
expect('').to.equal('') // Silence Buster! console.log('This dialect doesn\'t support me :(')
done() expect(true).to.be.true // Silence Buster
} else { return done()
var seq = new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {storage: '/path/to/no/where/land', logging: false, host: '0.0.0.1', port: config[dialect].port, dialect: dialect})
, Domain = require('domain')
, domain = Domain.create()
domain.on('error', function(err){
expect(err.toString()).to.match(/Failed to find (.*?) Please double check your settings\./)
domain.remove(seq.query)
done()
})
domain.run(function(){
domain.add(seq.query)
seq.query('select 1 as hello')
.success(function(){})
})
} }
var seq = new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {storage: '/path/to/no/where/land', logging: false, host: '0.0.0.1', port: config[dialect].port, dialect: dialect})
seq.query('select 1 as hello').error(function(err) {
expect(err.message).to.match(/Failed to find (.*?) Please double check your settings\./)
done()
})
}) })
it('when we don\'t have the correct login information', function(done) { it('when we don\'t have the correct login information', function(done) {
if (dialect !== "postgres" && dialect !== "postgres-native" && dialect !== "mysql") { if (dialect !== "postgres" && dialect !== "postgres-native") {
console.log('This dialect doesn\'t support me :(') console.log('This dialect doesn\'t support me :(')
expect('').to.equal('') // Silence Buster expect(true).to.be.true // Silence Buster
return done()
} else if (noDomains === true) {
console.log('WARNING: Configuration specs requires NodeJS version >= 0.8 for full compatibility')
expect('').to.equal('') // Silence Buster!
return done() return done()
} else {
var seq = new Sequelize(config[dialect].database, config[dialect].username, 'fakepass123', {logging: false, host: config[dialect].host, port: 1, dialect: dialect})
, Domain = require('domain')
, domain = Domain.create()
domain.on('error', function(err){
expect(err.toString()).to.match(/^Failed to authenticate/)
domain.remove(seq.query)
done()
})
domain.run(function(){
domain.add(seq.query)
seq.query('select 1 as hello').success(function(){})
})
} }
var seq = new Sequelize(config[dialect].database, config[dialect].username, 'fakepass123', {logging: false, host: config[dialect].host, port: 1, dialect: dialect})
seq.query('select 1 as hello').error(function(err) {
expect(err.message).to.match(/^Failed to authenticate/)
done()
})
}) })
it('when we don\'t have a valid dialect.', function(done) { it('when we don\'t have a valid dialect.', function(done) {
expect(function() { expect(function() {
new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {host: '0.0.0.1', port: config[dialect].port, dialect: undefined}) new Sequelize(config[dialect].database, config[dialect].username, config[dialect].password, {host: '0.0.0.1', port: config[dialect].port, dialect: undefined})
}).to.throw('The dialect undefined is not supported.') }).to.throw(Error, 'The dialect undefined is not supported.')
done() done()
}) })
}) })
......
...@@ -559,7 +559,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -559,7 +559,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
it('stores the current date in createdAt', function(done) { it('stores the current date in createdAt', function(done) {
this.User.create({ username: 'foo' }).success(function(user) { this.User.create({ username: 'foo' }).success(function(user) {
expect(parseInt(+user.createdAt/5000, 10)).to.equal(parseInt(+new Date()/5000, 10)) expect(parseInt(+user.createdAt/5000, 10)).to.be.closeTo(parseInt(+new Date()/5000, 10), 1.5)
done() done()
}) })
}) })
...@@ -907,7 +907,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -907,7 +907,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
describe('special where conditions', function() { describe('special where conditions/smartWhere object', function() {
beforeEach(function(done) { beforeEach(function(done) {
var self = this var self = this
...@@ -919,6 +919,45 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -919,6 +919,45 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
it('should be able to retun a record with primaryKey being null for new inserts', function(done) {
var Session = this.sequelize.define('Session', {
token: { type: DataTypes.TEXT, allowNull: false },
lastUpdate: { type: DataTypes.DATE, allowNull: false }
}, {
charset: 'utf8',
collate: 'utf8_general_ci',
omitNull: true
})
, User = this.sequelize.define('User', {
name: { type: DataTypes.STRING, allowNull: false, unique: true },
password: { type: DataTypes.STRING, allowNull: false },
isAdmin: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false }
}, {
charset: 'utf8',
collate: 'utf8_general_ci'
})
User.hasMany(Session, { as: 'Sessions' })
Session.belongsTo(User)
Session.sync({ force: true }).success(function() {
User.sync({ force: true }).success(function() {
User.create({name: 'Name1', password: '123', isAdmin: false}).success(function(user) {
var sess = Session.build({
lastUpdate: new Date(),
token: '123'
})
user.addSession(sess).success(function(u) {
expect(u.token).to.equal('123')
done()
})
})
})
})
})
it('should be able to find a row between a certain date', function(done) { it('should be able to find a row between a certain date', function(done) {
this.User.findAll({ this.User.findAll({
where: { where: {
...@@ -2310,8 +2349,8 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2310,8 +2349,8 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
self.sequelize.dropAllSchemas().success(function(){ self.sequelize.dropAllSchemas().success(function(){
self.sequelize.createSchema('schema_test').success(function(){ self.sequelize.createSchema('schema_test').success(function(){
self.sequelize.createSchema('special').success(function(){ self.sequelize.createSchema('special').success(function(){
self.UserSpecial.schema('special').sync({force: true}).success(function(UserSpecialSync){ self.UserSpecial.schema('special').sync({force: true}).success(function(UserSpecialSync) {
self.UserSpecialSync = UserSpecialSync; self.UserSpecialSync = UserSpecialSync
done() done()
}) })
}) })
...@@ -2320,10 +2359,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2320,10 +2359,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
it("should be able to list schemas", function(done){ it("should be able to list schemas", function(done){
this.sequelize.showAllSchemas().success(function(schemas){ this.sequelize.showAllSchemas().success(function(schemas) {
expect(schemas).to.exist expect(schemas).to.exist
expect(schemas[0]).to.be.instanceof(Array) expect(schemas[0]).to.be.instanceof(Array)
expect(schemas[0].length).to.equal(2) // sqlite & MySQL doesn't actually create schemas unless Model.sync() is called
// Postgres supports schemas natively
expect(schemas[0]).to.have.length((dialect === "postgres" || dialect === "postgres-native" ? 2 : 1))
done() done()
}) })
}) })
...@@ -2495,7 +2536,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -2495,7 +2536,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
} }
}).error(function(err) { }).error(function(err) {
if (dialect === 'mysql') { if (dialect === 'mysql') {
expect(err.message).to.match(/ER_CANT_CREATE_TABLE/) expect(err.message).to.match(/ER_CANNOT_ADD_FOREIGN/)
} }
else if (dialect === 'sqlite') { else if (dialect === 'sqlite') {
// the parser should not end up here ... see above // the parser should not end up here ... see above
......
/* jshint camelcase: false */ /* jshint camelcase: false */
var chai = require('chai') var chai = require('chai')
, sinonChai = require('sinon-chai')
, expect = chai.expect , expect = chai.expect
, Support = require(__dirname + '/support') , Support = require(__dirname + '/support')
, DataTypes = require(__dirname + "/../lib/data-types") , DataTypes = require(__dirname + "/../lib/data-types")
...@@ -10,7 +9,6 @@ var chai = require('chai') ...@@ -10,7 +9,6 @@ var chai = require('chai')
, datetime = require('chai-datetime') , datetime = require('chai-datetime')
, _ = require('lodash') , _ = require('lodash')
chai.use(sinonChai)
chai.use(datetime) chai.use(datetime)
chai.Assertion.includeStack = true chai.Assertion.includeStack = true
...@@ -994,7 +992,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -994,7 +992,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
createdAt: new Date(2000, 1, 1), createdAt: new Date(2000, 1, 1),
identifier: 'another identifier' identifier: 'another identifier'
}).success(function(user) { }).success(function(user) {
expect(user.createdAt).to.equal(oldCreatedAt) expect((new Date(user.createdAt)).getTime()).to.equal((new Date(oldCreatedAt)).getTime())
expect(user.identifier).to.equal(oldIdentifier) expect(user.identifier).to.equal(oldIdentifier)
done() done()
}) })
......
...@@ -64,7 +64,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -64,7 +64,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
this.init({ from: 20111117063700, to: 20111130161100 }, function(migrator) { this.init({ from: 20111117063700, to: 20111130161100 }, function(migrator) {
migrator.getUndoneMigrations(function(err, migrations) { migrator.getUndoneMigrations(function(err, migrations) {
expect(err).to.be.null expect(err).to.be.null
expect(migrations.length).to.equal(2) expect(migrations).to.have.length(2)
expect(migrations[0].filename).to.equal('20111117063700-createPerson.js') expect(migrations[0].filename).to.equal('20111117063700-createPerson.js')
expect(migrations[1].filename).to.equal('20111130161100-emptyMigration.js') expect(migrations[1].filename).to.equal('20111130161100-emptyMigration.js')
done() done()
...@@ -76,7 +76,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -76,7 +76,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
this.init({ to: 20111130161100 }, function(migrator) { this.init({ to: 20111130161100 }, function(migrator) {
migrator.getUndoneMigrations(function(err, migrations) { migrator.getUndoneMigrations(function(err, migrations) {
expect(err).to.be.null expect(err).to.be.null
expect(migrations.length).to.equal(2) expect(migrations).to.have.length(2)
done() done()
}) })
}) })
...@@ -87,7 +87,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -87,7 +87,7 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
SequelizeMeta.create({ from: null, to: 20111117063700 }).success(function() { SequelizeMeta.create({ from: null, to: 20111117063700 }).success(function() {
migrator.getUndoneMigrations(function(err, migrations) { migrator.getUndoneMigrations(function(err, migrations) {
expect(err).to.be.null expect(err).to.be.null
expect(migrations.length).to.equal(6) expect(migrations).to.have.length(6)
expect(migrations[0].filename).to.equal('20111130161100-emptyMigration.js') expect(migrations[0].filename).to.equal('20111130161100-emptyMigration.js')
done() done()
}) })
...@@ -198,7 +198,11 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -198,7 +198,11 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
expect(signature.allowNull).to.be.true expect(signature.allowNull).to.be.true
expect(isAdmin.allowNull).to.be.false expect(isAdmin.allowNull).to.be.false
expect(isAdmin.defaultValue).to.equal("0") if (dialect === "postgres" || dialect === "postgres-native" || dialect === "sqlite") {
expect(isAdmin.defaultValue).to.be.false
} else {
expect(isAdmin.defaultValue).to.equal("0")
}
expect(shopId.allowNull).to.be.true expect(shopId.allowNull).to.be.true
done() done()
...@@ -221,8 +225,11 @@ describe(Support.getTestDialectTeaser("Migrator"), function() { ...@@ -221,8 +225,11 @@ describe(Support.getTestDialectTeaser("Migrator"), function() {
expect(signature.allowNull).to.be.true expect(signature.allowNull).to.be.true
expect(isAdmin.allowNull).to.be.false expect(isAdmin.allowNull).to.be.false
expect(isAdmin.defaultValue).to.equal('0') if (dialect === "postgres" || dialect === "postgres-native" || dialect === "sqlite") {
expect(isAdmin.defaultValue).to.be.false
} else {
expect(isAdmin.defaultValue).to.equal("0")
}
expect(shopId).to.be.not.ok expect(shopId).to.be.not.ok
done() done()
......
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, dialect = Support.getTestDialect()
, config = require(__dirname + '/../config/config')
, DataTypes = require(__dirname + "/../../lib/data-types")
chai.Assertion.includeStack = true
if (dialect.match(/^postgres/)) {
describe('[POSTGRES 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) {
var Table2 = this.sequelize.define('wp_table2', {foo: DataTypes.STRING})
, Table1 = this.sequelize.define('wp_table1', {foo: DataTypes.STRING})
Table1.hasMany(Table2)
Table2.hasMany(Table1)
expect(this.sequelize.daoFactoryManager.getDAO('wp_table1swp_table2s')).to.exist
done()
})
})
describe('when join table name is specified', function() {
beforeEach(function(done){
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'})
done()
})
it("should not use a combined name", function(done) {
expect(this.sequelize.daoFactoryManager.getDAO('ms_table1sms_table2s')).not.to.exist
done()
})
it("should use the specified name", function(done) {
expect(this.sequelize.daoFactoryManager.getDAO('table1_to_table2')).to.exist
done()
})
})
})
describe('HasMany', function() {
beforeEach(function(done) {
//prevent periods from occurring in the table name since they are used to delimit (table.column)
this.User = this.sequelize.define('User' + config.rand(), { name: DataTypes.STRING })
this.Task = this.sequelize.define('Task' + config.rand(), { name: DataTypes.STRING })
this.users = null
this.tasks = null
this.User.hasMany(this.Task, {as:'Tasks'})
this.Task.hasMany(this.User, {as:'Users'})
var self = this
, users = []
, tasks = []
for (var i = 0; i < 5; ++i) {
users[users.length] = {name: 'User' + Math.random()}
}
for (var x = 0; x < 5; ++x) {
tasks[tasks.length] = {name: 'Task' + Math.random()}
}
self.sequelize.getQueryInterface().dropAllTables().success(function() {
self.User.sync({ force: true }).success(function() {
self.Task.sync({ force: true }).success(function() {
self.User.bulkCreate(users).success(function() {
self.Task.bulkCreate(tasks).success(function() {
done()
})
})
})
})
})
})
describe('addDAO / getDAO', function() {
beforeEach(function(done) {
var self = this
self.user = null
self.task = null
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
self.user = _users[0]
self.task = _tasks[0]
done()
})
})
})
it('should correctly add an association to the dao', function(done) {
var self = this
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks).to.have.length(0)
self.user.addTask(self.task).on('success', function() {
self.user.getTasks().on('success', function(_tasks) {
expect(_tasks).to.have.length(1)
done()
})
})
})
})
})
describe('removeDAO', function() {
beforeEach(function(done) {
var self = this
self.user = null
self.tasks = null
self.User.all().success(function(_users) {
self.Task.all().success(function(_tasks) {
self.user = _users[0]
self.tasks = _tasks
done()
})
})
})
it("should correctly remove associated objects", function(done) {
var self = this
self.user.getTasks().on('success', function(__tasks) {
expect(__tasks).to.have.length(0)
self.user.setTasks(self.tasks).on('success', function() {
self.user.getTasks().on('success', 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) {
expect(_tasks).to.have.length(self.tasks.length - 1)
done()
})
})
})
})
})
})
})
})
})
}
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, dialect = Support.getTestDialect()
, config = require(__dirname + '/../config/config')
, DataTypes = require(__dirname + "/../../lib/data-types")
chai.Assertion.includeStack = true
if (dialect.match(/^postgres/)) {
describe('[POSTGRES Specific] DAO', function() {
beforeEach(function(done) {
this.sequelize.options.quoteIdentifiers = true
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
})
this.User.sync({ force: true }).success(function() {
done()
})
})
afterEach(function(done) {
this.sequelize.options.quoteIdentifiers = true
done()
})
describe('model', function() {
it("create handles array correctly", function(done) {
this.User
.create({ username: 'user', email: ['foo@bar.com', 'bar@baz.com'] })
.success(function(oldUser) {
expect(oldUser.email).to.contain.members(['foo@bar.com', 'bar@baz.com'])
done()
})
.error(function(err) {
console.log(err)
})
})
it("should handle hstore correctly", function(done) {
var self = this
this.User
.create({ username: 'user', email: ['foo@bar.com'], document: { created: { test: '"value"' }}})
.success(function(newUser) {
expect(newUser.document).to.deep.equal({ created: { test: '"value"' }})
// Check to see if updating an hstore field works
newUser.updateAttributes({document: {should: 'update', to: 'this', first: 'place'}}).success(function(oldUser){
// Postgres always returns keys in alphabetical order (ascending)
expect(oldUser.document).to.deep.equal({first: 'place', should: 'update', to: 'this'})
// Check to see if the default value for an hstore field works
self.User.create({ username: 'user2', email: ['bar@baz.com']}).success(function(defaultUser){
expect(defaultUser.document).to.deep.equal({default: 'value'})
done()
})
})
})
.error(console.log)
})
})
describe('[POSTGRES] Unquoted identifiers', function() {
it("can insert and select", function(done) {
var self = this
this.sequelize.options.quoteIdentifiers = false
this.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = false
this.User = this.sequelize.define('Userxs', {
username: DataTypes.STRING,
fullName: DataTypes.STRING // Note mixed case
}, {
quoteIdentifiers: false
})
this.User.sync({ force: true }).success(function() {
self.User
.create({ username: 'user', fullName: "John Smith" })
.success(function(user) {
// We can insert into a table with non-quoted identifiers
expect(user.id).to.exist
expect(user.id).not.to.be.null
expect(user.username).to.equal('user')
expect(user.fullName).to.equal('John Smith')
// We can query by non-quoted identifiers
self.User.find({
where: {fullName: "John Smith"}
})
.success(function(user2) {
self.sequelize.options.quoteIndentifiers = true
self.sequelize.getQueryInterface().QueryGenerator.options.quoteIdentifiers = true
self.sequelize.options.logging = false
// 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')
done()
})
})
})
})
})
})
}
/* jshint camelcase: false */
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, dialect = Support.getTestDialect()
, hstore = require(__dirname + '/../../lib/dialects/postgres/hstore')
chai.Assertion.includeStack = true
if (dialect.match(/^postgres/)) {
describe('[POSTGRES Specific] hstore', function() {
describe('stringifyPart', function() {
it("handles undefined values correctly", function(done) {
expect(hstore.stringifyPart(undefined)).to.equal('NULL')
done()
})
it("handles null values correctly", function(done) {
expect(hstore.stringifyPart(null)).to.equal('NULL')
done()
})
it("handles boolean values correctly", function(done) {
expect(hstore.stringifyPart(false)).to.equal('false')
expect(hstore.stringifyPart(true)).to.equal('true')
done()
})
it("handles strings correctly", function(done) {
expect(hstore.stringifyPart('foo')).to.equal('"foo"')
done()
})
it("handles strings with backslashes correctly", function(done) {
expect(hstore.stringifyPart("\\'literally\\'")).to.equal('"\\\\\'literally\\\\\'"')
done()
})
it("handles arrays correctly", function(done) {
expect(hstore.stringifyPart([1,['2'],'"3"'])).to.equal('"[1,[\\"2\\"],\\"\\\\\\"3\\\\\\"\\"]"')
done()
})
it("handles simple objects correctly", function(done) {
expect(hstore.stringifyPart({ test: 'value' })).to.equal('"{\\"test\\":\\"value\\"}"')
done()
})
it("handles nested objects correctly", function(done) {
expect(hstore.stringifyPart({ test: { nested: 'value' } })).to.equal('"{\\"test\\":{\\"nested\\":\\"value\\"}}"')
done()
})
it("handles objects correctly", function(done) {
expect(hstore.stringifyPart({test: {nested: {value: {including: '"string"'}}}})).to.equal('"{\\"test\\":{\\"nested\\":{\\"value\\":{\\"including\\":\\"\\\\\\"string\\\\\\"\\"}}}}"')
done()
})
})
describe('stringify', function() {
it('should handle empty objects correctly', function(done) {
expect(hstore.stringify({ })).to.equal('')
done()
})
it('should handle null values correctly', function(done) {
expect(hstore.stringify({ null: null })).to.equal('"null"=>NULL')
done()
})
it('should handle simple objects correctly', function(done) {
expect(hstore.stringify({ test: 'value' })).to.equal('"test"=>"value"')
done()
})
it('should handle nested objects correctly', function(done) {
expect(hstore.stringify({ test: { nested: 'value' } })).to.equal('"test"=>"{\\"nested\\":\\"value\\"}"')
done()
})
it('should handle nested arrays correctly', function(done) {
expect(hstore.stringify({ test: [ 1, '2', [ '"3"' ] ] })).to.equal('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"')
done()
})
it('should handle multiple keys with different types of values', function(done) {
expect(hstore.stringify({ true: true, false: false, null: null, undefined: undefined, integer: 1, array: [1,'2'], object: { object: 'value' }})).to.equal('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"')
done()
})
})
describe('parse', function() {
it('should handle empty objects correctly', function(done) {
expect(hstore.parse('')).to.deep.equal({ })
done()
})
it('should handle simple objects correctly', function(done) {
expect(hstore.parse('"test"=>"value"')).to.deep.equal({ test: 'value' })
done()
})
it('should handle nested objects correctly', function(done) {
expect(hstore.parse('"test"=>"{\\"nested\\":\\"value\\"}"')).to.deep.equal({ test: { nested: 'value' } })
done()
})
it('should handle nested arrays correctly', function(done) {
expect(hstore.parse('"test"=>"[1,\\"2\\",[\\"\\\\\\"3\\\\\\"\\"]]"')).to.deep.equal({ test: [ 1, '2', [ '"3"' ] ] })
done()
})
it('should handle multiple keys with different types of values', function(done) {
expect(hstore.parse('"true"=>true,"false"=>false,"null"=>NULL,"undefined"=>NULL,"integer"=>1,"array"=>"[1,\\"2\\"]","object"=>"{\\"object\\":\\"value\\"}"')).to.deep.equal({ true: true, false: false, null: null, undefined: null, integer: "1", array: [1,'2'], object: { object: 'value' }})
done()
})
})
})
}
...@@ -9,11 +9,6 @@ var chai = require('chai') ...@@ -9,11 +9,6 @@ var chai = require('chai')
chai.Assertion.includeStack = true chai.Assertion.includeStack = true
describe(Support.getTestDialectTeaser("QueryGenerators"), function () { describe(Support.getTestDialectTeaser("QueryGenerators"), function () {
before(function(done) {
this.interface = this.sequelize.getQueryInterface()
done()
})
describe("comments", function() { describe("comments", function() {
it("should create a comment for a column", function(done) { it("should create a comment for a column", function(done) {
var self = this var self = this
...@@ -21,7 +16,7 @@ describe(Support.getTestDialectTeaser("QueryGenerators"), function () { ...@@ -21,7 +16,7 @@ describe(Support.getTestDialectTeaser("QueryGenerators"), function () {
username: {type: DataTypes.STRING, comment: 'Some lovely info for my DBA'} username: {type: DataTypes.STRING, comment: 'Some lovely info for my DBA'}
}) })
User.sync({ force: true }).success(function(){ User.sync({ force: true }).success(function() {
var sql = '' var sql = ''
if (dialect === "mysql") { if (dialect === "mysql") {
sql = 'SELECT COLUMN_COMMENT as cmt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \'' + self.sequelize.config.database + '\' AND TABLE_NAME = \'Users\' AND COLUMN_NAME = \'username\''; sql = 'SELECT COLUMN_COMMENT as cmt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = \'' + self.sequelize.config.database + '\' AND TABLE_NAME = \'Users\' AND COLUMN_NAME = \'username\'';
......
...@@ -8,34 +8,35 @@ var chai = require('chai') ...@@ -8,34 +8,35 @@ var chai = require('chai')
chai.Assertion.includeStack = true chai.Assertion.includeStack = true
describe(Support.getTestDialectTeaser("QueryInterface"), function () { describe(Support.getTestDialectTeaser("QueryInterface"), function () {
before(function(done) { beforeEach(function(done) {
this.interface = this.sequelize.getQueryInterface() this.sequelize.options.quoteIdenifiers = true
this.queryInterface = this.sequelize.getQueryInterface()
done() done()
}) })
describe('dropAllTables', function() { describe('dropAllTables', function() {
it("should drop all tables", function(done) { it("should drop all tables", function(done) {
var self = this var self = this
this.interface.dropAllTables().complete(function(err) { this.queryInterface.dropAllTables().complete(function(err) {
expect(err).to.be.null expect(err).to.be.null
self.interface.showAllTables().complete(function(err, tableNames) { self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null expect(err).to.be.null
expect(tableNames.length).to.equal(0) expect(tableNames).to.be.empty
self.interface.createTable('table', { name: DataTypes.STRING }).complete(function(err) { self.queryInterface.createTable('table', { name: DataTypes.STRING }).complete(function(err) {
expect(err).to.be.null expect(err).to.be.null
self.interface.showAllTables().complete(function(err, tableNames) { self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null expect(err).to.be.null
expect(tableNames.length).to.equal(1) expect(tableNames).to.have.length(1)
self.interface.dropAllTables().complete(function(err) { self.queryInterface.dropAllTables().complete(function(err) {
expect(err).to.be.null expect(err).to.be.null
self.interface.showAllTables().complete(function(err, tableNames) { self.queryInterface.showAllTables().complete(function(err, tableNames) {
expect(err).to.be.null expect(err).to.be.null
expect(tableNames.length).to.equal(0) expect(tableNames).to.be.empty
done() done()
}) })
}) })
...@@ -47,28 +48,34 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -47,28 +48,34 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
}) })
describe('indexes', function() { describe('indexes', function() {
beforeEach(function(done) { before(function(done) {
this.interface.createTable('User', { var self = this
username: DataTypes.STRING, this.queryInterface.dropTable('Users').success(function() {
isAdmin: DataTypes.BOOLEAN self.queryInterface.createTable('Users', {
}).success(done) username: DataTypes.STRING,
isAdmin: DataTypes.BOOLEAN
}).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(done) {
var self = this var self = this
this.interface.addIndex('User', ['username', 'isAdmin']).complete(function(err) {
this.queryInterface.addIndex('Users', ['username', 'isAdmin']).complete(function(err) {
expect(err).to.be.null expect(err).to.be.null
self.interface.showIndex('User').complete(function(err, indexes) { self.queryInterface.showIndex('Users').complete(function(err, indexes) {
expect(err).to.be.null expect(err).to.be.null
var indexColumns = _.uniq(indexes.map(function(index) { return index.name })) var indexColumns = _.uniq(indexes.map(function(index) { return index.name }))
expect(indexColumns).to.include('user_username_is_admin') expect(indexColumns).to.include('users_username_is_admin')
self.interface.removeIndex('User', ['username', 'isAdmin']).complete(function(err) { self.queryInterface.removeIndex('Users', ['username', 'isAdmin']).complete(function(err) {
expect(err).to.be.null expect(err).to.be.null
self.interface.showIndex('User').complete(function(err, indexes) { self.queryInterface.showIndex('Users').complete(function(err, indexes) {
expect(err).to.be.null expect(err).to.be.null
indexColumns = _.uniq(indexes.map(function(index) { return index.name })) indexColumns = _.uniq(indexes.map(function(index) { return index.name }))
...@@ -85,14 +92,14 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -85,14 +92,14 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
describe('describeTable', function() { describe('describeTable', function() {
it('reads the metadata of the table', function(done) { it('reads the metadata of the table', function(done) {
var self = this var self = this
var Users = self.sequelize.define('User', { var Users = self.sequelize.define('_Users', {
username: DataTypes.STRING, username: DataTypes.STRING,
isAdmin: DataTypes.BOOLEAN, isAdmin: DataTypes.BOOLEAN,
enumVals: DataTypes.ENUM('hello', 'world') enumVals: DataTypes.ENUM('hello', 'world')
}, { freezeTableName: true }) }, { freezeTableName: true })
Users.sync({ force: true }).success(function() { Users.sync({ force: true }).success(function() {
self.interface.describeTable('User').complete(function(err, metadata) { self.queryInterface.describeTable('_Users').complete(function(err, metadata) {
expect(err).to.be.null expect(err).to.be.null
var username = metadata.username var username = metadata.username
...@@ -109,7 +116,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () { ...@@ -109,7 +116,7 @@ describe(Support.getTestDialectTeaser("QueryInterface"), function () {
if (dialect === "postgres" || dialect === "postgres-native") { if (dialect === "postgres" || dialect === "postgres-native") {
expect(enumVals.special).to.be.instanceof(Array) expect(enumVals.special).to.be.instanceof(Array)
expect(enumVals.special.length).to.equal(2); expect(enumVals.special).to.have.length(2);
} }
done() done()
......
...@@ -52,6 +52,11 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () { ...@@ -52,6 +52,11 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
}) })
describe('query', function() { describe('query', function() {
afterEach(function(done) {
this.sequelize.options.quoteIdentifiers = true
done()
})
beforeEach(function(done) { beforeEach(function(done) {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: DataTypes.STRING username: DataTypes.STRING
...@@ -259,11 +264,21 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () { ...@@ -259,11 +264,21 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
}) })
it("fails with incorrect database credentials", function(done) { it("fails with incorrect database credentials", function(done) {
// sqlite doesn't have a concept of database credentials
if (dialect === "sqlite") {
expect(true).to.be.true
return done()
}
var sequelize2 = Support.getSequelizeInstance('foo', 'bar', null, { logging: false }) var sequelize2 = Support.getSequelizeInstance('foo', 'bar', null, { logging: false })
, User2 = sequelize2.define('User', { name: DataTypes.STRING, bio: DataTypes.TEXT }) , User2 = sequelize2.define('User', { name: DataTypes.STRING, bio: DataTypes.TEXT })
User2.sync().error(function(err) { User2.sync().error(function(err) {
expect(err.message).to.match(/.*Access\ denied.*/) if (dialect === "postgres" || dialect === "postgres-native") {
expect(err.message).to.equal('role "bar" does not exist')
} else {
expect(err.message.toString()).to.match(/.*Access\ denied.*/)
}
done() done()
}) })
}) })
......
...@@ -59,6 +59,8 @@ var Support = { ...@@ -59,6 +59,8 @@ var Support = {
}, },
getSequelizeInstance: function(db, user, pass, options) { getSequelizeInstance: function(db, user, pass, options) {
options = options || {};
options.dialect = options.dialect || this.getTestDialect()
return new Sequelize(db, user, pass, options) return new Sequelize(db, user, pass, options)
}, },
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!