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

Commit 74c6204a by Mick Hansen

First refactoring steps

1 parent 9a219699
...@@ -120,8 +120,9 @@ module.exports = (function() { ...@@ -120,8 +120,9 @@ module.exports = (function() {
} }
}) })
this.primaryKeyCount = Object.keys(this.primaryKeys).length; this.primaryKeyAttributes = Object.keys(this.primaryKeys)
this.options.hasPrimaryKeys = this.hasPrimaryKeys = this.primaryKeyCount > 0; this.primaryKeyCount = this.primaryKeyAttributes.length
this.options.hasPrimaryKeys = this.hasPrimaryKeys = this.primaryKeyCount > 0
if (typeof this.options.defaultScope === "object") { if (typeof this.options.defaultScope === "object") {
Utils.injectScope.call(this, this.options.defaultScope) Utils.injectScope.call(this, this.options.defaultScope)
...@@ -141,6 +142,25 @@ module.exports = (function() { ...@@ -141,6 +142,25 @@ module.exports = (function() {
this.DAO.prototype.rawAttributes = this.rawAttributes; this.DAO.prototype.rawAttributes = this.rawAttributes;
this.DAO.prototype._hasPrimaryKeys = this.options.hasPrimaryKeys
this.DAO.prototype._isPrimaryKey = Utils._.memoize(function (key) {
return self.primaryKeyAttributes.indexOf(key) !== -1
})
if (this.options.timestamps) {
var readOnlyAttributes = []
readOnlyAttributes.push(Utils._.underscoredIf(this.options.createdAt, this.options.underscored))
readOnlyAttributes.push(Utils._.underscoredIf(this.options.updatedAt, this.options.underscored))
readOnlyAttributes.push(Utils._.underscoredIf(this.options.deletedAt, this.options.underscored))
this.DAO.prototype._readOnlyAttributes = readOnlyAttributes
}
this.DAO.prototype._hasReadOnlyAttributes = this.DAO.prototype._readOnlyAttributes && this.DAO.prototype._readOnlyAttributes.length
this.DAO.prototype._isReadOnlyAttribute = Utils._.memoize(function (key) {
return self.DAO.prototype._hasReadOnlyAttributes && self.DAO.prototype._readOnlyAttributes.indexOf(key) !== -1
})
if (this.options.instanceMethods) { if (this.options.instanceMethods) {
Utils._.each(this.options.instanceMethods, function(fct, name) { Utils._.each(this.options.instanceMethods, function(fct, name) {
self.DAO.prototype[name] = fct self.DAO.prototype[name] = fct
...@@ -167,6 +187,11 @@ module.exports = (function() { ...@@ -167,6 +187,11 @@ module.exports = (function() {
} }
}) })
this.DAO.prototype._hasBooleanAttributes = !!this.DAO.prototype.booleanValues
this.DAO.prototype._isBooleanAttribute = Utils._.memoize(function (key) {
return self.DAO.prototype.booleanValues.indexOf(key) !== -1
})
this.DAO.prototype.__factory = this this.DAO.prototype.__factory = this
this.DAO.prototype.daoFactory = this this.DAO.prototype.daoFactory = this
this.DAO.prototype.Model = this this.DAO.prototype.Model = this
...@@ -180,31 +205,43 @@ module.exports = (function() { ...@@ -180,31 +205,43 @@ module.exports = (function() {
var self = this var self = this
, attributeManipulation = {}; , attributeManipulation = {};
this.DAO.prototype._customGetters = {}
this.DAO.prototype._customSetters = {}
Utils._.each(['get', 'set'], function(type) { Utils._.each(['get', 'set'], function(type) {
var opt = type + 'terMethods' var opt = type + 'terMethods'
, funcs = Utils._.isObject(self.options[opt]) ? self.options[opt] : {} , funcs = Utils._.clone(Utils._.isObject(self.options[opt]) ? self.options[opt] : {})
, _custom = type === 'get' ? self.DAO.prototype._customGetters : self.DAO.prototype._customSetters
Utils._.each(funcs, function (method, attribute) {
_custom[attribute] = method
Utils._.each(self.rawAttributes, function(options, attribute) {
if (options.hasOwnProperty(type)) {
funcs[attribute] = options[type]
} else if (typeof funcs[attribute] === "undefined") {
if (type === 'get') { if (type === 'get') {
funcs[attribute] = function() { return this.dataValues[attribute]; } funcs[attribute] = function() {
return this.get(attribute)
}
} }
if (type === 'set') { if (type === 'set') {
funcs[attribute] = function(value) { funcs[attribute] = function(value) {
if (Utils.hasChanged(this.dataValues[attribute], value)) { console.log(this)
//Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated return this.set(attribute, value)
var updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored) }
, createdAtAttr = Utils._.underscoredIf(this.__options.createdAt, this.__options.underscored) }
, touchedAtAttr = Utils._.underscoredIf(this.__options.touchedAt, this.__options.underscored) })
if (this.dataValues[attribute] || (attribute != 'id' && attribute != touchedAtAttr && attribute != createdAtAttr && attribute != updatedAtAttr)) { Utils._.each(self.rawAttributes, function(options, attribute) {
this.isDirty = true if (options.hasOwnProperty(type)) {
_custom[attribute] = options[type]
} }
if (type === 'get') {
funcs[attribute] = function() {
return this.get(attribute)
} }
this.dataValues[attribute] = value
} }
if (type === 'set') {
funcs[attribute] = function(value) {
return this.set(attribute, value)
} }
} }
}) })
...@@ -373,7 +410,7 @@ module.exports = (function() { ...@@ -373,7 +410,7 @@ module.exports = (function() {
options = optClone(options) options = optClone(options)
if (typeof options === 'object') { if (typeof options === 'object') {
if (options.hasOwnProperty('include')) { if (options.hasOwnProperty('include') && options.include) {
hasJoin = true hasJoin = true
validateIncludedElements.call(this, options) validateIncludedElements.call(this, options)
...@@ -456,7 +493,7 @@ module.exports = (function() { ...@@ -456,7 +493,7 @@ module.exports = (function() {
} else if (typeof options === 'object') { } else if (typeof options === 'object') {
options = Utils._.clone(options) options = Utils._.clone(options)
if (options.hasOwnProperty('include')) { if (options.hasOwnProperty('include') && options.include) {
hasJoin = true hasJoin = true
validateIncludedElements.call(this, options) validateIncludedElements.call(this, options)
...@@ -554,13 +591,8 @@ module.exports = (function() { ...@@ -554,13 +591,8 @@ module.exports = (function() {
DAOFactory.prototype.build = function(values, options) { DAOFactory.prototype.build = function(values, options) {
options = options || { isNewRecord: true, isDirty: true } options = options || { isNewRecord: true, isDirty: true }
if (options.hasOwnProperty('include') && options.include && (!options.includeValidated || !options.includeNames)) { if (options.hasOwnProperty('include') && options.include && !options.includeValidated) {
options.includeNames = [] validateIncludedElements.call(this, options)
options.include = options.include.map(function(include) {
include = validateIncludedElement.call(this, include)
options.includeNames.push(include.as)
return include
}.bind(this))
} }
if (options.includeNames) { if (options.includeNames) {
......
...@@ -16,7 +16,7 @@ module.exports = (function() { ...@@ -16,7 +16,7 @@ module.exports = (function() {
this.__eagerlyLoadedAssociations = [] this.__eagerlyLoadedAssociations = []
this.isNewRecord = options.isNewRecord this.isNewRecord = options.isNewRecord
initAttributes.call(this, values, options) initValues.call(this, values, options)
this.isDirty = options.isDirty this.isDirty = options.isDirty
} }
...@@ -80,15 +80,139 @@ module.exports = (function() { ...@@ -80,15 +80,139 @@ module.exports = (function() {
DAO.prototype.getDataValue = function(name) { DAO.prototype.getDataValue = function(name) {
return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name] return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
} }
DAO.prototype.get = DAO.prototype.getDataValue
DAO.prototype.setDataValue = function(name, value) { DAO.prototype.setDataValue = function(name, value) {
if (Utils.hasChanged(this.dataValues[name], value)) { if (Utils.hasChanged(this.dataValues[name], value)) {
this.isDirty = true this.isDirty = true
} }
this.dataValues[name] = value this.dataValues[name] = value
} }
DAO.prototype.set = DAO.prototype.setDataValue
DAO.prototype.get = function (key) {
if (this._customGetters[key]) {
return this._customGetters[key].call(this)
}
return this.dataValues[key]
}
DAO.prototype.set = function (key, value, options) {
var values
, originalValue
if (typeof key === "object") {
values = key
options = value
options || (options = {})
if (options.reset) {
this.dataValues = {}
}
// If raw, and we're not dealing with includes, just set it straight on the dataValues object
if (options.raw && !(this.options && this.options.include)) {
if (Object.keys(this.dataValues).length) {
this.dataValues = _.extend(this.dataValues, values)
} else {
this.dataValues = values
}
} else {
// Loop and call set
for (key in values) {
this.set(key, values[key], options)
}
}
} else {
options || (options = {})
originalValue = this.dataValues[key]
// If not raw, and there's a customer setter
if (!options.raw && this._customSetters[key]) {
this._customSetters[key].call(this, value)
} else {
// Check if we have included models, and if this key matches the include model names/aliases
if (this.options && this.options.include && this.options.includeNames.indexOf(key) !== -1) {
// Pass it on to the include handler
this._setInclude(key, value, options)
return
} else {
// If attempting to set primary key and primary key is already defined, return
if (this._hasPrimaryKeys && originalValue && this._isPrimaryKey(key)) {
return
}
// If attempting to set read only attributes, return
if (this._hasReadOnlyAttributes && this._isReadOnlyAttribute(key)) {
return
}
// Convert boolean-ish values to booleans
if (this._hasBooleanAttributes && this._isBooleanAttribute(key) && value != null) {
value = !!value
}
this.dataValues[key] = value
}
}
if (Utils.hasChanged(originalValue, value)) {
//Only dirty the object if the change is not due to id, touchedAt, createdAt or updatedAt being initiated
var updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored)
, createdAtAttr = Utils._.underscoredIf(this.__options.createdAt, this.__options.underscored)
, touchedAtAttr = Utils._.underscoredIf(this.__options.touchedAt, this.__options.underscored)
if (this.dataValues[key] && (key != 'id' && key != touchedAtAttr && key != createdAtAttr && key != updatedAtAttr)) {
this.isDirty = true
}
}
}
};
DAO.prototype._setInclude = function(key, value, options) {
if (!Array.isArray(value)) value = [value]
if (value[0] instanceof DAO) {
value = value.map(function (instance) {
return instance.dataValues
})
}
var include = _.find(this.options.include, function (include) {
return include.as === key || (include.as.slice(0,1).toLowerCase() + include.as.slice(1)) === key
})
var association = include.association
, self = this
var accessor = Utils._.camelize(key)
// downcase the first char
accessor = accessor.slice(0,1).toLowerCase() + accessor.slice(1)
value.forEach(function(data) {
var daoInstance = include.daoFactory.build(data, {
isNewRecord: false,
isDirty: false,
include: include.include,
includeNames: include.includeNames,
includeMap: include.includeMap,
includeValidated: true,
raw: options.raw
})
, isEmpty = !Utils.firstValueOfHash(daoInstance.identifiers)
if (association.isSingleAssociation) {
accessor = Utils.singularize(accessor, self.sequelize.language)
self.dataValues[accessor] = isEmpty ? null : daoInstance
self[accessor] = self.dataValues[accessor]
} else {
if (!self.dataValues[accessor]) {
self.dataValues[accessor] = []
self[accessor] = self.dataValues[accessor]
}
if (!isEmpty) {
self.dataValues[accessor].push(daoInstance)
}
}
}.bind(this))
};
// if an array with field names is passed to save() // if an array with field names is passed to save()
// only those fields will be updated // only those fields will be updated
...@@ -99,6 +223,10 @@ module.exports = (function() { ...@@ -99,6 +223,10 @@ module.exports = (function() {
options = Utils._.extend({}, options, fieldsOrOptions) options = Utils._.extend({}, options, fieldsOrOptions)
if (!options.fields) {
options.fields = this.attributes
}
var self = this var self = this
, values = options.fields ? {} : (this.options.includeNames ? _.omit(this.dataValues, this.options.includeNames) : this.dataValues) , values = options.fields ? {} : (this.options.includeNames ? _.omit(this.dataValues, this.options.includeNames) : this.dataValues)
, updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored) , updatedAtAttr = Utils._.underscoredIf(this.__options.updatedAt, this.__options.underscored)
...@@ -156,7 +284,7 @@ module.exports = (function() { ...@@ -156,7 +284,7 @@ module.exports = (function() {
} }
} }
if (self.__options.timestamps && self.dataValues.hasOwnProperty(updatedAtAttr)) { if (self.__options.timestamps) {
self.dataValues[updatedAtAttr] = values[updatedAtAttr] = ( self.dataValues[updatedAtAttr] = values[updatedAtAttr] = (
( (
self.isNewRecord self.isNewRecord
...@@ -165,6 +293,16 @@ module.exports = (function() { ...@@ -165,6 +293,16 @@ module.exports = (function() {
) )
? self.daoFactory.rawAttributes[updatedAtAttr].defaultValue ? self.daoFactory.rawAttributes[updatedAtAttr].defaultValue
: Utils.now(self.sequelize.options.dialect)) : Utils.now(self.sequelize.options.dialect))
if (self.isNewRecord) {
self.dataValues[createdAtAttr] = values[createdAtAttr] = (
(
!!self.daoFactory.rawAttributes[createdAtAttr]
&& !!self.daoFactory.rawAttributes[createdAtAttr].defaultValue
)
? self.daoFactory.rawAttributes[createdAtAttr].defaultValue
: Utils.now(self.sequelize.options.dialect))
}
} }
var query = null var query = null
...@@ -184,6 +322,7 @@ module.exports = (function() { ...@@ -184,6 +322,7 @@ module.exports = (function() {
} }
self.isDirty = false self.isDirty = false
query = 'update' query = 'update'
args = [self, self.QueryInterface.QueryGenerator.addSchema(self.__factory), values, identifier, options] args = [self, self.QueryInterface.QueryGenerator.addSchema(self.__factory), values, identifier, options]
hook = 'Update' hook = 'Update'
...@@ -236,16 +375,12 @@ module.exports = (function() { ...@@ -236,16 +375,12 @@ module.exports = (function() {
this.__factory.find({ this.__factory.find({
where: where, where: where,
limit: 1, limit: 1,
include: this.options.include || [] include: this.options.include || null
}, options) }, options)
.on('sql', function(sql) { emitter.emit('sql', sql) }) .on('sql', function(sql) { emitter.emit('sql', sql) })
.on('error', function(error) { emitter.emit('error', error) }) .on('error', function(error) { emitter.emit('error', error) })
.on('success', function(obj) { .on('success', function(obj) {
for (var valueName in obj.values) { this.set(obj.dataValues, {raw: true, reset: true})
if (obj.values.hasOwnProperty(valueName)) {
this[valueName] = obj.values[valueName]
}
}
this.isDirty = false this.isDirty = false
emitter.emit('success', this) emitter.emit('success', this)
}.bind(this)) }.bind(this))
...@@ -286,7 +421,8 @@ module.exports = (function() { ...@@ -286,7 +421,8 @@ module.exports = (function() {
} }
DAO.prototype.setAttributes = function(updates) { DAO.prototype.setAttributes = function(updates) {
var self = this this.set(updates)
/*var self = this
var readOnlyAttributes = Object.keys(this.__factory.primaryKeys) var readOnlyAttributes = Object.keys(this.__factory.primaryKeys)
readOnlyAttributes.push('id') readOnlyAttributes.push('id')
...@@ -321,7 +457,7 @@ module.exports = (function() { ...@@ -321,7 +457,7 @@ module.exports = (function() {
self[Utils._.underscoredIf(this.daoFactory.options.updatedAt, this.daoFactory.options.underscored)] = new Date() self[Utils._.underscoredIf(this.daoFactory.options.updatedAt, this.daoFactory.options.underscored)] = new Date()
} }
this.isDirty = isDirty this.isDirty = isDirty*/
} }
DAO.prototype.destroy = function(options) { DAO.prototype.destroy = function(options) {
...@@ -475,12 +611,12 @@ module.exports = (function() { ...@@ -475,12 +611,12 @@ module.exports = (function() {
// private // private
var initAttributes = function(values, options) { var initValues = function(values, options) {
// set id to null if not passed as value, a newly created dao has no id // set id to null if not passed as value, a newly created dao has no id
var defaults = this.hasPrimaryKeys ? {} : { id: null }, var defaults = this.hasPrimaryKeys ? {} : { id: null },
attrs = {},
key; key;
values = values && _.clone(values) || {}
// add all passed values to the dao and store the attribute names in this.attributes // add all passed values to the dao and store the attribute names in this.attributes
if (options.isNewRecord) { if (options.isNewRecord) {
...@@ -507,71 +643,15 @@ module.exports = (function() { ...@@ -507,71 +643,15 @@ module.exports = (function() {
} }
} }
if (Utils._.size(defaults)) { if (Object.keys(defaults).length) {
for (key in defaults) { for (key in defaults) {
attrs[key] = Utils.toDefaultValue(defaults[key]) if (!values.hasOwnProperty(key)) {
} values[key] = Utils.toDefaultValue(defaults[key])
}
Utils._.each(this.attributes, function(key) {
if (!attrs.hasOwnProperty(key)) {
attrs[key] = undefined
}
})
if (values) {
for (key in values) {
if (values.hasOwnProperty(key)) {
attrs[key] = values[key]
}
} }
} }
for (key in attrs) {
if (options.include && options.includeNames.indexOf(key) !== -1) {
if (!Array.isArray(attrs[key])) attrs[key] = [attrs[key]];
var include = _.find(options.include, function (include) {
return include.as === key || (include.as.slice(0,1).toLowerCase() + include.as.slice(1)) === key
})
var association = include.association
, self = this
var accessor = Utils._.camelize(key)
// downcase the first char
accessor = accessor.slice(0,1).toLowerCase() + accessor.slice(1)
attrs[key].forEach(function(data) {
var daoInstance = include.daoFactory.build(data, {
isNewRecord: false,
isDirty: false,
include: include.include,
includeNames: include.includeNames,
includeMap: include.includeMap,
includeValidated: true
})
, isEmpty = !Utils.firstValueOfHash(daoInstance.identifiers)
if (association.isSingleAssociation) {
accessor = Utils.singularize(accessor, self.sequelize.language)
self.dataValues[accessor] = isEmpty ? null : daoInstance
self[accessor] = self.dataValues[accessor]
} else {
if (!self.dataValues[accessor]) {
self.dataValues[accessor] = []
self[accessor] = self.dataValues[accessor]
} }
if (!isEmpty) { this.set(values, options)
self.dataValues[accessor].push(daoInstance)
}
}
}.bind(this))
} else {
this.addAttribute(key, attrs[key])
}
}
} }
return DAO return DAO
......
...@@ -227,7 +227,8 @@ module.exports = (function() { ...@@ -227,7 +227,8 @@ module.exports = (function() {
include:this.options.include, include:this.options.include,
includeNames: this.options.includeNames, includeNames: this.options.includeNames,
includeMap: this.options.includeMap, includeMap: this.options.includeMap,
includeValidated: true includeValidated: true,
raw: true
}) })
}.bind(this)) }.bind(this))
} else if (this.options.hasJoinTableModel === true) { } else if (this.options.hasJoinTableModel === true) {
...@@ -249,7 +250,7 @@ module.exports = (function() { ...@@ -249,7 +250,7 @@ module.exports = (function() {
// Regular queries // Regular queries
} else { } else {
result = results.map(function(result) { result = results.map(function(result) {
return this.callee.build(result, { isNewRecord: false, isDirty: false }) return this.callee.build(result, { isNewRecord: false, isDirty: false, raw: true })
}.bind(this)) }.bind(this))
} }
......
...@@ -632,7 +632,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -632,7 +632,7 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
self.Task.create({ title: 'task2' }).success(function(task2) { self.Task.create({ title: 'task2' }).success(function(task2) {
user.setTasks([task1, task2]).on('sql', spy).on('sql', _.after(2, function (sql) { user.setTasks([task1, task2]).on('sql', spy).on('sql', _.after(2, function (sql) {
expect(sql).to.have.string("INSERT INTO") expect(sql).to.have.string("INSERT INTO")
expect(sql).to.have.string("VALUES (1,1),(2,1)") expect(sql).to.have.string("VALUES (1,1),(1,2)")
})).success(function () { })).success(function () {
expect(spy.calledTwice).to.be.ok expect(spy.calledTwice).to.be.ok
done() done()
......
...@@ -28,6 +28,7 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() { ...@@ -28,6 +28,7 @@ describe(Support.getTestDialectTeaser("Multiple Level Filters"), function() {
UserId: 1, UserId: 1,
title: 'republic' title: 'republic'
},{ },{
UserId: 2,
title: 'empire' title: 'empire'
}]).success(function() { }]).success(function() {
Task.bulkCreate([{ Task.bulkCreate([{
......
...@@ -265,6 +265,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -265,6 +265,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
foobar: {type: Sequelize.TEXT, defaultValue: 'asd'}, foobar: {type: Sequelize.TEXT, defaultValue: 'asd'},
flag: {type: Sequelize.BOOLEAN, defaultValue: false} flag: {type: Sequelize.BOOLEAN, defaultValue: false}
}) })
expect(Task.build().title).to.equal('a task!') expect(Task.build().title).to.equal('a task!')
expect(Task.build().foo).to.equal(2) expect(Task.build().foo).to.equal(2)
expect(Task.build().bar).to.not.be.ok expect(Task.build().bar).to.not.be.ok
...@@ -548,12 +549,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -548,12 +549,12 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
Support.prepareTransactionTest(this.sequelize, function(sequelize) { Support.prepareTransactionTest(this.sequelize, function(sequelize) {
var User = sequelize.define('User', { username: Sequelize.STRING }) var User = sequelize.define('User', { username: Sequelize.STRING })
User.sync({ force: true }).success(function() { User.sync({ force: true }).done(function() {
User.create({ username: 'foo' }).success(function() { User.create({ username: 'foo' }).done(function() {
sequelize.transaction(function(t) { sequelize.transaction(function(t) {
User.update({ username: 'bar' }, {}, { transaction: t }).success(function() { User.update({ username: 'bar' }, {}, { transaction: t }).done(function(err) {
User.all().success(function(users1) { User.all().done(function(err, users1) {
User.all({ transaction: t }).success(function(users2) { User.all({ transaction: t }).done(function(err, users2) {
expect(users1[0].username).to.equal('foo') expect(users1[0].username).to.equal('foo')
expect(users2[0].username).to.equal('bar') expect(users2[0].username).to.equal('bar')
t.rollback().success(function(){ done() }) t.rollback().success(function(){ done() })
...@@ -669,7 +670,9 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -669,7 +670,9 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
{ username: 'Bob', secretValue: '43' }] { username: 'Bob', secretValue: '43' }]
this.User.bulkCreate(data).success(function() { this.User.bulkCreate(data).success(function() {
self.User.update({username: 'Bill'}, {secretValue: '42'}).success(function() { self.User.update({username: 'Bill'}, {secretValue: '42'}).done(function(err) {
console.log(err)
expect(err).not.to.be.ok
self.User.findAll({order: 'id'}).success(function(users) { self.User.findAll({order: 'id'}).success(function(users) {
expect(users.length).to.equal(3) expect(users.length).to.equal(3)
......
...@@ -124,7 +124,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -124,7 +124,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
where: { id: 1 }, where: { id: 1 },
attributes: ['id', ['username', 'name']] attributes: ['id', ['username', 'name']]
}).success(function(user) { }).success(function(user) {
expect(user.name).to.equal('barfooz') expect(user.dataValues.name).to.equal('barfooz')
done() done()
}) })
}) })
......
...@@ -618,10 +618,12 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -618,10 +618,12 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
include: [Page] include: [Page]
}).success(function(leBook) { }).success(function(leBook) {
page.updateAttributes({ content: 'something totally different' }).success(function(page) { page.updateAttributes({ content: 'something totally different' }).success(function(page) {
expect(leBook.pages.length).to.equal(1)
expect(leBook.pages[0].content).to.equal('om nom nom') expect(leBook.pages[0].content).to.equal('om nom nom')
expect(page.content).to.equal('something totally different') expect(page.content).to.equal('something totally different')
leBook.reload().success(function(leBook) { leBook.reload().success(function(leBook) {
expect(leBook.pages.length).to.equal(1)
expect(leBook.pages[0].content).to.equal('something totally different') expect(leBook.pages[0].content).to.equal('something totally different')
expect(page.content).to.equal('something totally different') expect(page.content).to.equal('something totally different')
done() done()
...@@ -792,15 +794,13 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -792,15 +794,13 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
// timeout is needed, in order to check the update of the timestamp // timeout is needed, in order to check the update of the timestamp
var build = function(callback) { var build = function(callback) {
user = User.build({ username: 'user' }) user = User.build({ username: 'user' })
updatedAt = user.updatedAt
expect(updatedAt.getTime()).to.be.above(now)
setTimeout(function() { var save = user.save()
user.save().success(function() {
expect(updatedAt.getTime()).to.be.below(user.updatedAt.getTime()) save.success(function() {
expect(now).to.be.below(user.updatedAt.getTime())
callback() callback()
}) })
}, 1000)
} }
// closures are fun :) // closures are fun :)
...@@ -1079,7 +1079,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -1079,7 +1079,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
it('returns a response that can be stringified', function(done) { it('returns a response that can be stringified', function(done) {
var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true }) var user = this.User.build({ username: 'test.user', age: 99, isAdmin: true })
expect(JSON.stringify(user)).to.deep.equal('{"id":null,"username":"test.user","age":99,"isAdmin":true}') expect(JSON.stringify(user)).to.deep.equal('{"username":"test.user","age":99,"isAdmin":true,"id":null}')
done() done()
}) })
...@@ -1235,7 +1235,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -1235,7 +1235,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
this.ParanoidUser.create({ username: 'fnord' }).success(function() { this.ParanoidUser.create({ username: 'fnord' }).success(function() {
self.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
users[0].updateAttributes({username: 'newFnord'}).success(function(user) { users[0].updateAttributes({username: 'newFnord'}).success(function(user) {
expect(user.deletedAt).to.be.null expect(user.deletedAt).not.to.exist
done() done()
}) })
}) })
...@@ -1248,7 +1248,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -1248,7 +1248,7 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
self.ParanoidUser.findAll().success(function(users) { self.ParanoidUser.findAll().success(function(users) {
self.ParanoidUser.create({ username: 'linkedFnord' }).success(function(linkedUser) { self.ParanoidUser.create({ username: 'linkedFnord' }).success(function(linkedUser) {
users[0].setParanoidUser( linkedUser ).success(function(user) { users[0].setParanoidUser( linkedUser ).success(function(user) {
expect(user.deletedAt).to.be.null expect(user.deletedAt).not.to.exist
done() done()
}) })
}) })
......
/* jshint camelcase: false */
var chai = require('chai')
, Sequelize = require('../../index')
, expect = chai.expect
, Support = require(__dirname + '/../support')
, DataTypes = require(__dirname + "/../../lib/data-types")
, dialect = Support.getTestDialect()
, config = require(__dirname + "/../config/config")
, sinon = require('sinon')
, datetime = require('chai-datetime')
, uuid = require('node-uuid')
, _ = require('lodash')
chai.use(datetime)
chai.Assertion.includeStack = true
describe(Support.getTestDialectTeaser("DAO"), function () {
describe('Values', function () {
describe('set', function () {
it('doesn\'t overwrite primary keys', function () {
var User = this.sequelize.define('User', {
identifier: {type: DataTypes.STRING, primaryKey: true}
})
var user = User.build({identifier: 'identifier'})
expect(user.get('identifier')).to.equal('identifier')
user.set('identifier', 'another identifier')
expect(user.get('identifier')).to.equal('identifier')
})
it('doesn\'t set timestamps', function () {
var User = this.sequelize.define('User', {
identifier: {type: DataTypes.STRING, primaryKey: true}
})
var user = User.build()
user.set({
createdAt: new Date(2000, 1, 1),
updatedAt: new Date(2000, 1, 1)
})
expect(user.get('createdAt')).not.to.be.ok
expect(user.get('updatedAt')).not.to.be.ok
})
describe('includes', function () {
it('should support basic includes', function () {
var Product = this.sequelize.define('Product', {
title: Sequelize.STRING
})
var Tag = this.sequelize.define('Tag', {
name: Sequelize.STRING
})
var User = this.sequelize.define('User', {
first_name: Sequelize.STRING,
last_name: Sequelize.STRING
})
Product.hasMany(Tag)
Product.belongsTo(User)
var product
product = Product.build({}, {
include: [
User,
Tag
]
})
product.set({
id: 1,
title: 'Chair',
tags: [
{id: 1, name: 'Alpha'},
{id: 2, name: 'Beta'}
],
user: {
id: 1,
first_name: 'Mick',
last_name: 'Hansen'
}
})
expect(product.tags).to.be.ok
expect(product.tags.length).to.equal(2)
expect(product.tags[0].Model).to.equal(Tag)
expect(product.user).to.be.ok
expect(product.user.Model).to.equal(User)
})
it('should support basic includes (with raw: true)', function () {
var Product = this.sequelize.define('Product', {
title: Sequelize.STRING
})
var Tag = this.sequelize.define('Tag', {
name: Sequelize.STRING
})
var User = this.sequelize.define('User', {
first_name: Sequelize.STRING,
last_name: Sequelize.STRING
})
Product.hasMany(Tag)
Product.belongsTo(User)
var product
product = Product.build({}, {
include: [
User,
Tag
]
})
product.set({
id: 1,
title: 'Chair',
tags: [
{id: 1, name: 'Alpha'},
{id: 2, name: 'Beta'}
],
user: {
id: 1,
first_name: 'Mick',
last_name: 'Hansen'
}
}, {raw: true})
expect(product.tags).to.be.ok
expect(product.tags.length).to.equal(2)
expect(product.tags[0].Model).to.equal(Tag)
expect(product.user).to.be.ok
expect(product.user.Model).to.equal(User)
})
})
})
})
})
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!