Skip to content

Commit

Permalink
Merge pull request #129 from gnarf/fix-remove-has-one
Browse files Browse the repository at this point in the history
Fix call stack overflow when removing circular hasOne inverse
  • Loading branch information
dgeb committed Apr 8, 2015
2 parents 616b3c7 + a9e4675 commit cb85917
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
14 changes: 10 additions & 4 deletions lib/orbit-common/cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,16 +275,22 @@ var Cache = Class.extend({
},

_markForRemoval: function(path) {
this._pathsToRemove.push(path.join('/'));
path = path.join('/');
// console.log('_markForRemoval', path);
this._pathsToRemove.push(path);
},

_unmarkForRemoval: function(path) {
var i = this._pathsToRemove.indexOf(path.join('/'));
path = path.join('/');
var i = this._pathsToRemove.indexOf(path);
// console.log('_unmarkForRemoval', path, i);
if (i > -1) this._pathsToRemove.splice(i, 1);
},

_isMarkedForRemoval: function(path) {
return (this._pathsToRemove.indexOf(path.join('/')) > -1);
path = path.join('/');
// console.log('_isMarkedForRemoval', path);
return (this._pathsToRemove.indexOf(path) > -1);
},

_isOperationRequired: function(operation) {
Expand Down Expand Up @@ -683,7 +689,7 @@ var Cache = Class.extend({
var op = this._removeLinkOp(type, id, key, value);

// Apply operation only if necessary
if (this.retrieve(op.path)) {
if (this.retrieve(op.path) && !this._isMarkedForRemoval(op.path)) {
this.transform(parentOperation.spawn(op));
}
},
Expand Down
37 changes: 37 additions & 0 deletions test/tests/orbit-common/unit/cache-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,43 @@ test("does not remove hasOne if link doesn't exist", function(){
ok(!appliedTransform, "didn't apply transform");
});

test("#transform removing model with a bi-directional hasOne", function() {
expect(5);

var hasOneSchema = new Schema({
models: {
one: {
links: {
two: { type: 'hasOne', model: 'two', inverse: 'one' }
}
},
two: {
links: {
one: { type: 'hasOne', model: 'one', inverse: 'two' }
}
},
}
});
cache = new Cache(hasOneSchema);
cache.transform({ op: 'add', path: 'one/one', value: {
id: 'one',
__rel: { two: null },
}});
cache.transform({ op: 'add', path: 'two/two', value: {
id: 'two',
__rel: { one: 'one' },
}});
var one = cache.retrieve(['one', 'one']);
var two = cache.retrieve(['two', 'two']);
ok(one, 'one exists');
ok(two, 'two exists');
equal(one.__rel.two, 'two', 'one links to two');
equal(two.__rel.one, 'one', 'two links to one');

cache.transform({ op: 'remove', path: 'two/two' });
strictEqual(one.__rel.two, null, 'ones link to two got removed');
});

test("#transform maintainDependencies:true removes dependent records", function() {
// By making this schema recursively dependent remove we check that recursive
// works as well.
Expand Down

0 comments on commit cb85917

Please sign in to comment.