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

Commit 2d298a3c by Jochem Maas

add tests for getters/setters, bugfix, refactor - its WIP

1 parent 770c10c9
...@@ -78,11 +78,29 @@ module.exports = (function() { ...@@ -78,11 +78,29 @@ module.exports = (function() {
Util.inherits(this.DAO, DAO); Util.inherits(this.DAO, DAO);
this.DAO.prototype.rawAttributes = this.rawAttributes; this.DAO.prototype.rawAttributes = this.rawAttributes;
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
}) })
} }
Utils._.each(['Get', 'Set'], function(type) {
var opt = type.toLowerCase() + 'terMethods',
meth = '__define' + type + 'ter__';
if (self.options[opt]) {
Utils._.each(self.options[opt], function(fct, name) {
//var def = {};
if (!Utils._.isFunction(fct))
throw new Error(type + 'ter for "' + name + '" is not a function.')
self.DAO.prototype[meth](name, fct);
})
}
})
this.DAO.prototype.attributes = Object.keys(this.DAO.prototype.rawAttributes); this.DAO.prototype.attributes = Object.keys(this.DAO.prototype.rawAttributes);
this.DAO.prototype.booleanValues = []; this.DAO.prototype.booleanValues = [];
......
...@@ -14,13 +14,8 @@ module.exports = (function() { ...@@ -14,13 +14,8 @@ module.exports = (function() {
this.__eagerlyLoadedAssociations = [] this.__eagerlyLoadedAssociations = []
initAttributes.call(this, values, isNewRecord) initAttributes.call(this, values, isNewRecord)
if (this.hasDefaultValues) {
Utils._.each(this.defaultValues, function (value, name) {
self.addAttribute(name, value());
})
}
} }
Utils._.extend(DAO.prototype, Mixin.prototype) Utils._.extend(DAO.prototype, Mixin.prototype)
Object.defineProperty(DAO.prototype, 'sequelize', { Object.defineProperty(DAO.prototype, 'sequelize', {
...@@ -87,6 +82,17 @@ module.exports = (function() { ...@@ -87,6 +82,17 @@ module.exports = (function() {
} }
}) })
DAO.prototype.getDataValue = function(name) {
return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
}
DAO.prototype.setDataValue = function(name, value) {
if (this.dataValues && this.dataValues.hasOwnProperty(name))
this.dataValues[name] = value
else
this[name] = value
}
// 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
DAO.prototype.save = function(fields) { DAO.prototype.save = function(fields) {
...@@ -128,7 +134,7 @@ module.exports = (function() { ...@@ -128,7 +134,7 @@ module.exports = (function() {
} }
} }
if (this.__options.timestamps && this.hasOwnProperty(updatedAtAttr)) { if (this.__options.timestamps && this.dataValues.hasOwnProperty(updatedAtAttr)) {
this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now() this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now()
} }
...@@ -338,24 +344,34 @@ module.exports = (function() { ...@@ -338,24 +344,34 @@ module.exports = (function() {
if (typeof this.dataValues[attribute] !== 'undefined') if (typeof this.dataValues[attribute] !== 'undefined')
return; return;
var def = {}, if (this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1) // transform integer 0,1 into boolean
predef = Object.getOwnPropertyDescriptor(this, attribute),
isBool = this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1;
if (isBool) // transform integer 0,1 into boolean
value = !!value; value = !!value;
var hasnot = function(which) { var has = (function(o) {
return !predef || (!predef.hasOwnProperty('value') && !predef.hasOwnProperty(which)); var predef = Object.getOwnPropertyDescriptor(o, attribute);
};
if (predef && predef.hasOwnProperty('value'))
return true; // true here means 'this property exist as a simple value property, do not place setters or getters at all'
if (hasnot('get')) def.get = function() { return this.dataValues[attribute]; }; return {
if (hasnot('set')) def.set = function(v) { this.dataValues[attribute] = v; }; get: (predef && predef.hasOwnProperty('get') ? predef.get : null) || o.__lookupGetter__(attribute),
set: (predef && predef.hasOwnProperty('set') ? predef.set : null) || o.__lookupSetter__(attribute)
};
})(this);
if (Utils._.size(def)) // node-v0.8.19:
Object.defineProperty(this, attribute, def); // calling either __defineGetter__ any previously defined setters for the attribute in
// question *if* that property setter was defined on the object's prototype (which is what
// we do in dao-factory) ... therefore we need to [re]define both the setter and getter
// here with either the function that already existed OR the default/automatic definition
//
// (the same is true for __defineSetter and 'prototype' getters)
if (has !== true) {
this.__defineGetter__(attribute, has.get || function() { return this.dataValues[attribute]; });
this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v; });
}
this.dataValues[attribute] = value; this[attribute] = value;
} }
DAO.prototype.setValidators = function(attribute, validators) { DAO.prototype.setValidators = function(attribute, validators) {
...@@ -369,16 +385,10 @@ module.exports = (function() { ...@@ -369,16 +385,10 @@ module.exports = (function() {
// private // private
var initAttributes = function(values, isNewRecord) { var initAttributes = function(values, isNewRecord) {
// add all passed values to the dao and store the attribute names in this.attributes // set id to null if not passed as value, a newly created dao has no id
for (var key in values) { var defaults = this.hasPrimaryKeys ? {} : { id: null },
if (values.hasOwnProperty(key)) { attrs = {},
this.addAttribute(key, values[key]) key;
}
}
// set id to null if not passed as value
// a newly created dao has no id
var defaults = this.hasPrimaryKeys ? {} : { id: null }
if (this.__options.timestamps && isNewRecord) { if (this.__options.timestamps && isNewRecord) {
defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now() defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now()
...@@ -387,13 +397,38 @@ module.exports = (function() { ...@@ -387,13 +397,38 @@ module.exports = (function() {
if (this.__options.paranoid) { if (this.__options.paranoid) {
defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null
} }
if (this.hasDefaultValues) {
Utils._.each(this.defaultValues, function(valueFn, key) {
if (!defaults.hasOwnProperty(key))
defaults[key] = valueFn()
})
}
} }
if (Utils._.size(defaults)) { if (Utils._.size(defaults)) {
for (var attr in defaults) { for (key in defaults) {
this.addAttribute(attr, Utils.toDefaultValue(defaults[attr])) attrs[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) {
this.addAttribute(key, attrs[key])
}
} }
return DAO return DAO
......
...@@ -99,6 +99,37 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() { ...@@ -99,6 +99,37 @@ describe(Helpers.getTestDialectTeaser("DAOFactory"), function() {
var user = this.User.build({ username: 'John Wayne' }) var user = this.User.build({ username: 'John Wayne' })
expect(user.selectedValues).toEqual({ username: 'John Wayne' }) expect(user.selectedValues).toEqual({ username: 'John Wayne' })
}) })
it("attaches getter and setter methods", function() {
var Product = this.sequelize.define('ProductWithSettersAndGetters', {
priceInCents: {
type: Sequelize.INTEGER
}
},{
instanceMethods: {
foo: function() {
console.log('woot')
}
},
setterMethods: {
price: function(value) {
this.dataValues.priceInCents = value * 100;
}
},
getterMethods: {
price: function() {
return '$' + (this.getDataValue('priceInCents') / 100);
},
priceInCents: function() {
return this.dataValues.priceInCents;
}
}
});
expect(Product.build({price: 20}).priceInCents).toEqual(20 * 100);
expect(Product.build({priceInCents: 30 * 100}).price).toEqual('$' + 30);
})
}) })
describe('findOrCreate', function () { describe('findOrCreate', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!