Skip to content

Commit

Permalink
fixed bug with extend
Browse files Browse the repository at this point in the history
added Graviton.isModel
fixed race conditions in tests
  • Loading branch information
fractallian committed Jun 27, 2014
1 parent b796f5b commit b1457f2
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 36 deletions.
2 changes: 2 additions & 0 deletions graviton.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ Graviton.setProperty = function(obj, key, val) {
}
};

Graviton.isModel = isModel;

// use this to declare new models
// options contain the relations etc.
Graviton.define = function(collectionName, options) {
Expand Down
16 changes: 14 additions & 2 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,19 @@ Model = function(collectionName, obj, options) {
_.extend(this, options.properties);
};

isModel = function(obj) {
return (obj instanceof Graviton.Model || Graviton.Model.prototype.isPrototypeOf(obj));
};


// for creating a custom class to user for model transforms
Model.extend = function(proto) {
var self = this;
var Model = function(collectionName, obj, options) {
self.call(this, collectionName, obj, options);
};
Model.prototype = _.extend({}, this.prototype, proto);
Model.prototype = Object.create(this.prototype);
_.extend(Model.prototype, proto);
Model.extend = this.extend;
return Model;
};
Expand Down Expand Up @@ -92,13 +98,19 @@ Model.prototype.savedState = function() {
return this._savedState;
};

Model.prototype.update = function(modifier, options, callback) {
var args = _.toArray(arguments);
args.unshift({_id: this._id});
return this._collection.update.apply(this, args);
};

// insert or update
// TODO: track the attributes that have changed and only update those
Model.prototype.save = function() {
if (!this.persist()) {
var diff = Graviton.mongoDiff(this.savedState(), this.attributes);
if (!_.isEmpty(diff.operators)) {
this._collection.update(this._id, diff.operators);
this.update(diff.operators);
this.syncSavedState();
return {updated: true, warnings: diff.warnings};
}
Expand Down
8 changes: 4 additions & 4 deletions lib/relations.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Relation = function(model, config) {
Relation.prototype.constructor = Relation;

Relation.prototype.build = function(obj) {
if (obj instanceof Graviton.Model) return obj;
if (isModel(obj)) return obj;
if (_.isObject(obj)) return this._collection.build(obj);
};
// inserts model if it doesn't have an id - typically called by add
Expand Down Expand Up @@ -148,7 +148,7 @@ HasMany.prototype.add = function(model) {
model = this.build(model);
model.set(this._foreignKey, this._model._id);

Relation.prototype.persist.call(this, model);
model.persist();

var set = {$set: {}};
set['$set'][this._foreignKey] = this._model._id;
Expand All @@ -164,10 +164,10 @@ hasOne = function(model, config) {
var rel = new Relation(model, config);
return function(model) {
if (model) {
model = Relation.prototype.build.call(rel, model);
model = rel.build(model);
if (model.get(rel._foreignKey) !== rel._model._id) {
model.set(rel._foreignKey, rel._model._id);
}
}
model.save();
return model;
} else {
Expand Down
115 changes: 85 additions & 30 deletions test/graviton-test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@

var _klasses = [];

var init = function(klass) {
allowAll(klass);
if (Meteor.isServer) {
klass.remove({});
allowAll(klass);
}
_klasses.push(klass);

};

var allowAll = function(klass) {
Expand All @@ -19,7 +23,7 @@ var allowAll = function(klass) {
});
};

Car = Graviton.Car = Graviton.define("cars", {
Car = Graviton.define("cars", {
initialize: function() {
this.set('price', this.get('price') - 2);
},
Expand Down Expand Up @@ -97,78 +101,94 @@ Window = Graviton.define("windows", {
persist: false
});

////////////// setup
var doc, c, w;
var setup = function() {
if (Meteor.isServer) {
_.each(_klasses, function(klass) {
klass.remove({});
});
}


var doc = {color: 'red', speed: 'fast', price: 100, engine: {type: 'combustion', cylinders: 8}};
doc._id = Car.insert(doc);

var c = Car.findOne(doc._id);
if (Meteor.isClient) window.c = c;

c.manufacturer({name: "Audi", location: "Germany"});

c.wheels.add({});
c.wheels.add([{}, {tread: 'worn'}, {}]);

var w = Wheel.build({});
w.save();

w.set("isFlat", true);
w.save();
doc = {color: 'red', speed: 'fast', price: 100, engine: {type: 'combustion', cylinders: 8}};
doc._id = Car.insert(doc);

c.drivers.add({name: "Mario"});
c.drivers.add({name: "Dale"});
c = Car.findOne(doc._id);

c.set("plate", {code: "BASFACE"});
c.manufacturer({name: "Audi", location: "Germany"});

c.windows.add([
{type: "windshield"},
{type: "frontDriver"},
{type: "frontPassenger"},
{type: "rear"}
]);
c.wheels.add({});
c.wheels.add([{}, {tread: 'worn'}, {}]);

w = Wheel.build({});
w.save();

w.set("isFlat", true);
w.save();

c.drivers.add({name: "Mario"});
c.drivers.add({name: "Dale"});

c.set("plate", {code: "BASFACE"});

c.windows.add([
{type: "windshield"},
{type: "frontDriver"},
{type: "frontPassenger"},
{type: "rear"}
]);
};
////////////////////

setup();

Tinytest.add('Model - initialize', function(test) {
setup();
test.equal(c.get('price'), 98);
test.equal(c._collection._name, 'cars');
test.equal(doc.color, c.attributes.color);
test.equal(doc.engine.type.cylinders, c.get('engine.type.cylinders'));
});

Tinytest.add('Model - defaults', function(test) {
setup();
test.equal(w.get("tread"), "new");
});

Tinytest.add('Model - save', function(test) {
setup();
test.equal(_.isString(w._id), true);
var flat = Wheel.findOne({isFlat: true});
test.equal((flat instanceof Graviton.Model), true);
});

Tinytest.add('Relations - hasMany', function(test) {
setup();
test.equal(c.wheels._collection._name, 'wheels');
test.equal(c.wheels.find().count(), 4);
test.equal(c.wheels.all().length, c.wheels.find().count());
test.equal(c.wheels.find({tread: 'new'}).count(), 3);
test.equal(Driver.findOne().cars.findOne()._id, c._id);
test.equal(c.drivers.findOne().cars.find().count(), 1);
});

Tinytest.add('Relations - hasOne', function(test) {
setup();
test.isTrue(c.manufacturer() instanceof Graviton.Model);
var mfr = Mfr.findOne();
var mfr = Mfr.findOne({carId: c._id});
test.equal(mfr._id, c.manufacturer()._id);
});

Tinytest.add('Relations - belongsTo', function(test) {
setup();
test.equal(c.wheels.findOne().car()._id, c._id);
});

Tinytest.add('Relations - belongsToMany', function(test) {
setup();
if (c.drivers.find().count() != 2) {
console.log(c.drivers.find().fetch());
}
test.equal(c.drivers.find().count(), 2);
test.equal(_.isArray(c.get("driverIds")), true);

Expand All @@ -187,16 +207,51 @@ Tinytest.add('Relations - belongsToMany', function(test) {
var d = c.drivers.findOne();
var cur = c.drivers.find({_id: {$ne: d._id}});
test.equal(cur.count(), 2);

});

Tinytest.add('Relations - embeds', function(test) {
setup();
test.isTrue(c.plate() instanceof Graviton.Model);
test.equal(c.plate().get("code"), "BASFACE");
});

Tinytest.add('Relations - embedsMany', function(test) {
setup();
test.isTrue(c.windows.at(0) instanceof Graviton.Model);
test.equal(c.windows.all().length, 4);
test.equal(c.windows.at(2).get("type"), "frontPassenger");
test.equal(c.get("windows").length, 4);
});


////////

var Mdl = Graviton.Model.extend({});
var SubMdl = Mdl.extend({});

var Raw = Graviton.define('raw', {persist: false});
var Col = Graviton.define('col', {modelCls: Mdl, persist: false});
var SubCol = Graviton.define('sub', {modelCls: SubMdl, persist: false});

var r = Raw.build({});
var m = Col.build({});
var s = SubCol.build({});


Tinytest.add('Model - isModel', function(test) {
test.isTrue(Graviton.isModel(r));
test.isTrue(Graviton.isModel(m));
test.isTrue(Graviton.isModel(s));
test.isFalse(Graviton.isModel({}));
test.isFalse(Graviton.isModel([]));
test.isFalse(Graviton.isModel("xxx"));
test.isFalse(Graviton.isModel(234));
test.isFalse(Graviton.isModel(_));
test.isFalse(Graviton.isModel(Graviton));
});





0 comments on commit b1457f2

Please sign in to comment.