Skip to content

Commit

Permalink
Ensure List resize cleans up referenced nodes.
Browse files Browse the repository at this point in the history
Fixes immutable-js#540, and includes referenced tests
  • Loading branch information
leebyron committed Jul 14, 2015
1 parent 12ad749 commit c7c4ddc
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 19 deletions.
20 changes: 20 additions & 0 deletions __tests__/List.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,26 @@ describe('List', () => {
expect(v3.get(1800)).toBe(undefined);
});

it('discards truncated elements when using slice', () => {
var list = [1,2,3,4,5,6];
var v1 = Immutable.fromJS(list);
var v2 = v1.slice(0,3);
var v3 = v2.setSize(6);

expect(v2.toArray()).toEqual([1,2,3]);
expect(v3.toArray()).toEqual([1,2,3,undefined,undefined,undefined]);
});

it('discards truncated elements when using setSize', () => {
var list = [1,2,3,4,5,6];
var v1 = Immutable.fromJS(list);
var v2 = v1.setSize(3);
var v3 = v2.setSize(6);

expect(v2.toArray()).toEqual([1,2,3]);
expect(v3.toArray()).toEqual([1,2,3,undefined,undefined,undefined]);
});

it('can be efficiently sliced', () => {
var v1 = Immutable.Range(0,2000).toList();
var v2 = v1.slice(100,-100).toList();
Expand Down
14 changes: 5 additions & 9 deletions dist/immutable.js
Original file line number Diff line number Diff line change
Expand Up @@ -2828,29 +2828,25 @@
};

VNode.prototype.removeAfter = function(ownerID, level, index) {
if (index === level ? 1 << level : 0 || this.array.length === 0) {
if (index === (level ? 1 << level : 0) || this.array.length === 0) {
return this;
}
var sizeIndex = ((index - 1) >>> level) & MASK;
if (sizeIndex >= this.array.length) {
return this;
}
var removingLast = sizeIndex === this.array.length - 1;

var newChild;
if (level > 0) {
var oldChild = this.array[sizeIndex];
newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
if (newChild === oldChild && removingLast) {
if (newChild === oldChild && sizeIndex === this.array.length - 1) {
return this;
}
}
if (removingLast && !newChild) {
return this;
}

var editable = editableVNode(this, ownerID);
if (!removingLast) {
editable.array.pop();
}
editable.array.splice(sizeIndex + 1);
if (newChild) {
editable.array[sizeIndex] = newChild;
}
Expand Down
2 changes: 1 addition & 1 deletion dist/immutable.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 5 additions & 9 deletions src/List.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,29 +258,25 @@ class VNode {
}

removeAfter(ownerID, level, index) {
if (index === level ? 1 << level : 0 || this.array.length === 0) {
if (index === (level ? 1 << level : 0) || this.array.length === 0) {
return this;
}
var sizeIndex = ((index - 1) >>> level) & MASK;
if (sizeIndex >= this.array.length) {
return this;
}
var removingLast = sizeIndex === this.array.length - 1;

var newChild;
if (level > 0) {
var oldChild = this.array[sizeIndex];
newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
if (newChild === oldChild && removingLast) {
if (newChild === oldChild && sizeIndex === this.array.length - 1) {
return this;
}
}
if (removingLast && !newChild) {
return this;
}

var editable = editableVNode(this, ownerID);
if (!removingLast) {
editable.array.pop();
}
editable.array.splice(sizeIndex + 1);
if (newChild) {
editable.array[sizeIndex] = newChild;
}
Expand Down

0 comments on commit c7c4ddc

Please sign in to comment.