diff --git a/core/modules/utils/linked-list.js b/core/modules/utils/linked-list.js index b25f0b8fd..3fdc7f8b2 100644 --- a/core/modules/utils/linked-list.js +++ b/core/modules/utils/linked-list.js @@ -14,105 +14,181 @@ function LinkedList() { }; LinkedList.prototype.clear = function() { - this.index = Object.create(null); // LinkedList performs the duty of both the head and tail node - this.next = this; - this.prev = this; + this.next = Object.create(null); + this.prev = Object.create(null); + this.first = undefined; + this.last = undefined; this.length = 0; }; LinkedList.prototype.remove = function(value) { if($tw.utils.isArray(value)) { + for(var t=0; t list.push(undefined)).toThrow(message + "undefined"); + expect(() => list.pushTop(undefined)).toThrow(message + "undefined"); + expect(() => list.pushTop(["c", undefined])).toThrow(message + "undefined"); + expect(() => list.pushTop(5)).toThrow(message + "5"); + expect(() => list.pushTop(null)).toThrow(message + "null"); + + // now lets do a quick test to make sure this exception + // doesn't leave any side-effects + // A.K.A Strong guarantee + var pair = newPair(["A", "5", "B", "C"]); + expect(() => pushTop(pair, 5)).toThrow(message + "5"); + compare(pair); + expect(() => push(pair, ["D", 7])).toThrow(message + "7"); + compare(pair); + expect(() => remove(pair, 5)).toThrow(message + "5"); + compare(pair); + // This is the tricky one. 'A' and 'B' should not be removed or pushed. + expect(() => pushTop(pair, ["A", "B", null])).toThrow(message + "null"); + compare(pair); + expect(() => remove(pair, ["A", "B", null])).toThrow(message + "null"); + compare(pair); }); it("can clear", function() { var list = new $tw.utils.LinkedList(); - list.push('A', 'B', 'C'); + list.push("A", "B", "C"); list.clear(); expect(list.toArray()).toEqual([]); expect(list.length).toBe(0); }); it("can remove", function() { - var array = []; var list = new $tw.utils.LinkedList(); - push(array, list, 'A', 'x', 'C', 'x', 'D', 'x', 'E', 'x'); + list.push(["A", "x", "C", "x", "D", "x", "E", "x"]); // single - remove(array, list, 'x'); - compare(array, list); // A C x D x E x - + list.remove("x"); // arrays - remove(array, list, ['x', 'A', 'x']); - compare(array, list); // C D E x + list.remove(["x", "A", "XXX", "x"]); + expect(list.toArray()).toEqual(["C", "D", "E", "x"]); }); - it('can ignore removal of nonexistent items', function() { - var array = []; - var list = new $tw.utils.LinkedList(); - push(array, list, 'A', 'B', 'C', 'D'); + it("can ignore removal of nonexistent items", function() { + var pair = newPair(["A", "B", "C", "D"]); // single - remove(array, list, 'Z'); - compare(array, list); // A B C D + compare(remove(pair, "Z")); // ABCD // array - remove(array, list, ['Z', 'B', 'X']); - compare(array, list); // A C D + compare(remove(pair, ["Z", "B", "X"])); // ACD }); - it('can iterate with each', function() { + it("can iterate with each", function() { var list = new $tw.utils.LinkedList(); - list.push('0', '1', '2', '3'); + list.push("0", "1", "2", "3"); var counter = 0; list.each(function(value) { expect(value).toBe(counter.toString()); @@ -149,6 +260,11 @@ describe("LinkedList class tests", function() { }); expect(counter).toBe(4); }); + + it("can iterate a list of the same item", function() { + // Seems simple. Caused an infinite loop during development. + compare(newPair(["A", "A"])); + }); }); })();