UNPKG

extjs-gpl

Version:

GPL licensed version of Sencha Ext JS

1,273 lines (1,037 loc) 190 kB
/* global expect, Ext, jasmine */ describe("Ext.util.Collection", function() { var collection, fakeScope = {}; function logEvents (col, log, property) { property = property || 'id'; col.on({ beginupdate: function (sender) { expect(sender === col).toBe(true); log.push('beginupdate'); }, add: function (sender, details) { expect(sender === col).toBe(true); log.push('add ' + Ext.encode(Ext.Array.pluck(details.items, property)) + ' at ' + details.at); if (details.keys) { log[log.length - 1] += ' w/keys ' + Ext.encode(details.keys); } }, remove: function (sender, details) { expect(sender === col).toBe(true); log.push('remove ' + Ext.encode(Ext.Array.pluck(details.items, property)) + ' at ' + details.at); if (details.keys) { log[log.length - 1] += ' w/keys ' + Ext.encode(details.keys); } }, endupdate: function (sender) { expect(sender === col).toBe(true); log.push('endupdate'); } }); } describe('Moving items in a filtered Collection with sorters, but autoSort: false', function() { var item1, item2, item3, item4, item5, collection; beforeEach(function() { collection = new Ext.util.Collection(); item1 = {id: 1}; item2 = {id: 2}; item3 = {id: 3}; item4 = {id: 4}; item5 = {id: 5}; collection.add([item4, item3, item2, item1]); }); afterEach(function() { collection.destroy(); }); it('should honour the new insertion point', function() { collection.sort({property: 'id'}); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.getAt(3)).toBe(item4); // A filter which filters in all items collection.filterBy(function() { return true; }); // Because of autoSort, this should sort back to sorted order collection.insert(0, item4); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.getAt(3)).toBe(item4); // From now on, we should NOT always be in sorted order collection.setAutoSort(false); // Should not sort, item 4 should be first collection.insert(0, item4); expect(collection.getAt(0)).toBe(item4); expect(collection.getAt(1)).toBe(item1); expect(collection.getAt(2)).toBe(item2); expect(collection.getAt(3)).toBe(item3); }); it('should honour the new insertion point if we have a source collection', function() { var downstreamCollection = new Ext.util.Collection({ source: collection }); downstreamCollection.sort({property: 'id'}); expect(downstreamCollection.getAt(0)).toBe(item1); expect(downstreamCollection.getAt(1)).toBe(item2); expect(downstreamCollection.getAt(2)).toBe(item3); expect(downstreamCollection.getAt(3)).toBe(item4); // A filter which filters in all items downstreamCollection.filterBy(function() { return true; }); // Because of autoSort, this should sort back to sorted order collection.insert(0, item4); expect(downstreamCollection.getAt(0)).toBe(item1); expect(downstreamCollection.getAt(1)).toBe(item2); expect(downstreamCollection.getAt(2)).toBe(item3); expect(downstreamCollection.getAt(3)).toBe(item4); // From now on, we should NOT always be in sorted order downstreamCollection.setAutoSort(false); // Will still be sorted in the downstream Collection. // autoSort only applies to immediate mutations collection.add(item1); expect(downstreamCollection.getAt(0)).toBe(item1); expect(downstreamCollection.getAt(1)).toBe(item2); expect(downstreamCollection.getAt(2)).toBe(item3); expect(downstreamCollection.getAt(3)).toBe(item4); // The refresh of upstream should still cause a sort. collection.filterBy(function() { return true; }); expect(downstreamCollection.getAt(0)).toBe(item1); expect(downstreamCollection.getAt(1)).toBe(item2); expect(downstreamCollection.getAt(2)).toBe(item3); expect(downstreamCollection.getAt(3)).toBe(item4); // Inserted into a specific position in upstream Collection. // Should just get appended into our collection collection.insert(0, item5); expect(downstreamCollection.getAt(0)).toBe(item5); expect(downstreamCollection.getAt(1)).toBe(item1); expect(downstreamCollection.getAt(2)).toBe(item2); expect(downstreamCollection.getAt(3)).toBe(item3); expect(downstreamCollection.getAt(4)).toBe(item4); }); }); describe("constructor", function() { it("should provide a default getKey implementation", function() { collection = new Ext.util.Collection(); var item1 = {id: 1, data: 'first item'}, item2 = {id: 2, data: 'second item'}; collection.add(item1); collection.add(item2); expect(collection.get(1)).toBe(item1); expect(collection.get(2)).toBe(item2); }); it("should allow a custom getKey implementation", function() { collection = new Ext.util.Collection({ keyFn: function(item) { return item.myKey; } }); var item1 = {myKey: 'a', data: 'first item'}, item2 = {myKey: 'b', data: 'second item'}; collection.add(item1, item2); expect(collection.get('a')).toBe(item1); expect(collection.get('b')).toBe(item2); }); it("should contain the source items when configured with a source", function() { var source = new Ext.util.Collection(); source.add({id: 1}, {id: 2}, {id: 3}); collection = new Ext.util.Collection({ source: source }); expect(collection.getCount()).toBe(3); }); }); describe("iterators", function() { var fn, callScope, item1, item2, item3; beforeEach(function() { collection = new Ext.util.Collection(); fn = jasmine.createSpy('fn'); item1 = {id: 1, name: 'first'}; item2 = {id: 2, name: 'second'}; item3 = {id: 3, name: 'third'}; collection.add([item1, item2, item3]); }); describe("each", function() { it("should call with the correct scope", function() { collection.each(function() { callScope = this; }, fakeScope); expect(callScope).toBe(fakeScope); }); it("should call the correct number of times", function() { collection.each(fn); expect(fn.callCount).toBe(3); }); it("should be called with each item", function() { collection.each(fn); expect(fn).toHaveBeenCalledWith(item1, 0, 3); expect(fn).toHaveBeenCalledWith(item2, 1, 3); expect(fn).toHaveBeenCalledWith(item3, 2, 3); }); }); describe("eachKey", function() { it("should be called with the correct scope", function() { collection.eachKey(function() { callScope = this; }, fakeScope); expect(callScope).toBe(fakeScope); }); it("should call the correct number of times", function() { collection.eachKey(fn); expect(fn.callCount).toBe(3); }); it("should be called with each key", function() { collection.eachKey(fn); expect(fn).toHaveBeenCalledWith(1, item1, 0, 3); expect(fn).toHaveBeenCalledWith(2, item2, 1, 3); expect(fn).toHaveBeenCalledWith(3, item3, 2, 3); }); }); }); describe("adding items", function() { var item1, item2, item3, item4; beforeEach(function() { collection = new Ext.util.Collection(); item1 = {id: 1}; item2 = {id: 2}; item3 = {id: 3}; item4 = {id: 4}; }); afterEach(function() { item1 = item2 = item3 = item4 = null; }); it('should move an item down by one index successfully', function() { collection.add([item1, item2, item3, item4]); collection.insert(1, item1); expect(collection.getAt(0)).toBe(item2); expect(collection.getAt(1)).toBe(item1); expect(collection.getAt(2)).toBe(item3); expect(collection.getAt(3)).toBe(item4); }); it("should get the correct count when adding an array", function() { collection.add([item1, item2]); expect(collection.getCount()).toBe(2); expect(collection.length).toBe(2); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); }); it("should get the correct count when adding varargs", function() { collection.add(item1, item2); expect(collection.getCount()).toBe(2); expect(collection.length).toBe(2); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); }); it("should get the correct count when adding sequentially", function() { collection.add(item1); collection.add(item2); expect(collection.getCount()).toBe(2); expect(collection.length).toBe(2); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); }); it("should fire the add event", function() { var executed = false; collection.on('add', function() { executed = true; }); collection.add(item1); expect(executed).toBe(true); }); describe("with replaceAll", function() { it("should add when the collection is empty", function() { collection.replaceAll(item1); expect(collection.getCount()).toBe(1); }); it("should remove all existing items", function() { collection.add(item1, item2, item3); collection.replaceAll(item4); expect(collection.getCount()).toBe(1); expect(collection.first()).toBe(item4); }); it("should remove even when no items are added", function() { collection.add(item1, item2, item3); collection.setDecoder(function() { return false; }); collection.replaceAll(item4); expect(collection.getCount()).toBe(0); }); }); describe("when sorted", function() { var spy, expectPos; beforeEach(function() { spy = jasmine.createSpy(); }); afterEach(function() { expect(spy).not.toHaveBeenCalled(); expectPos = spy = null; }); describe("a single item", function() { describe("with no items", function() { beforeEach(function() { collection.getSorters().add('id'); collection.on('sort', spy); }); it("should add the item", function() { expectPos = function() { expect(collection.length).toBe(1); expect(collection.getAt(0)).toBe(item1); expect(collection.indexOfKey(1)).toBe(0); }; collection.on('add', expectPos); collection.add(item1); expectPos(); }); it("should be able to insert at index 0", function() { collection.insert(0, item1); expect(collection.getAt(0)).toBe(item1); }); it("should truncate the position if it goes past range", function() { collection.insert(10, item1); expect(collection.getAt(0)).toBe(item1); expect(collection.length).toBe(1); }); }); describe("with items", function() { var items = (function() { var records = []; for (var i = 0; i < 30; i++) { records.push({ id: i, order: i < 10 ? 'mac' : i < 20 ? 'and' : 'cheese' }); } return records; })(), item1 = {id: 30, order: 'mac'}, item2 = {id: 31, order: 'and'}, item3 = {id: 32, order: 'cheese'}; beforeEach(function() { collection.getSorters().add('order'); collection.add(items); collection.on('sort', spy); }); it("should put the item in the correct position", function() { collection.add(item1, item2); expectPos = function() { expect(collection.length).toBe(33); expect(collection.getAt(32)).toBe(item1); expect(collection.getAt(10)).toBe(item2); expect(collection.indexOfKey(30)).toBe(32); expect(collection.indexOfKey(31)).toBe(10); expect(collection.indexOfKey(32)).toBe(21); }; collection.on('add', expectPos); collection.add(item3); expectPos(); }); describe("inserting at index", function() { it("should be able to insert as the first item", function() { collection.insert(0, item2); expect(collection.getAt(0)).toBe(item2); }); it("should be able to insert as the last item", function() { collection.insert(30, item1); expect(collection.getAt(30)).toBe(item1); }); it("should be able to insert directly after the first item", function() { collection.insert(1, item2); expect(collection.getAt(1)).toBe(item2); }); it("should be able to insert directly before the last item", function() { collection.insert(29, item1); expect(collection.getAt(29)).toBe(item1); expect(collection.length).toBe(31); }); it("should be able to insert in the middle of the collection", function() { collection.insert(14, item3); expect(collection.getAt(14)).toBe(item3); }); it("should insert at last index of the appropriate sorting if index is out of range", function() { collection.insert(0, item1); collection.insert(14, item2); collection.insert(25, item3); expect(collection.getAt(10)).toBe(item2); expect(collection.getAt(21)).toBe(item3); expect(collection.getAt(32)).toBe(item1); }); }); }); }); describe("multiple items", function() { beforeEach(function() { collection.getSorters().add('id'); collection.on('sort', spy); }); describe("with no items", function() { it("should insert the items", function() { expectPos = function() { expect(collection.length).toBe(3); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.indexOfKey(1)).toBe(0); expect(collection.indexOfKey(2)).toBe(1); expect(collection.indexOfKey(3)).toBe(2); }; collection.on('add', expectPos); collection.add([item1, item2, item3]); expectPos(); }); it("should sort the added items", function() { expectPos = function() { expect(collection.length).toBe(3); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); }; collection.on('add', expectPos); collection.add([item3, item1, item2]); expectPos(); }); }); describe("with items", function() { it("should insert the items into the correct position", function() { collection.add(item3); expectPos = function() { expect(collection.length).toBe(3); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.indexOfKey(1)).toBe(0); expect(collection.indexOfKey(2)).toBe(1); expect(collection.indexOfKey(3)).toBe(2); }; collection.on('add', expectPos); collection.add(item1, item2); expectPos(); }); it("should sort the added items", function() { collection.add(item3); expectPos = function() { expect(collection.length).toBe(3); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.indexOfKey(1)).toBe(0); expect(collection.indexOfKey(2)).toBe(1); expect(collection.indexOfKey(3)).toBe(2); }; collection.on('add', expectPos); collection.add(item2, item1); expectPos(); }); it("should insert items in a discontiguous range", function() { collection.add(item1, item3); var count = 0; expectPos = function() { expect(collection.length).toBe(4); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.getAt(3)).toBe(item4); expect(collection.indexOfKey(1)).toBe(0); expect(collection.indexOfKey(2)).toBe(1); expect(collection.indexOfKey(3)).toBe(2); expect(collection.indexOfKey(4)).toBe(3); }; collection.on('add', function() { if (count === 0) { expect(collection.length).toBe(4); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item2); expect(collection.getAt(2)).toBe(item3); expect(collection.indexOfKey(1)).toBe(0); expect(collection.indexOfKey(2)).toBe(1); expect(collection.indexOfKey(3)).toBe(2); } else { expectPos(); } ++count; }); collection.add(item4, item2); expectPos(); }); }); }); }); }); describe("removing items", function() { var item1 = {id: 1, name: 'one'}, item2 = {id: 2, name: 'two'}, item3 = {id: 3, name: 'three'}, item4 = {id: 4, name: 'four'}, item5 = {id: 5, name: 'five'}, item6 = {id: 6, name: 'six'}, item7 = {id: 7, name: 'seven'}, item8 = {id: 8, name: 'eight'}, item9 = {id: 9, name: 'nine'}; beforeEach(function() { collection = new Ext.util.Collection(); collection.add([ item1, item2, item3, item4, item5, item6, item7, item8, item9 ]); }); describe("remove", function() { it("should remove a single item", function() { collection.remove(item1); expect(collection.getCount()).toBe(8); }); it("should return the removed item count", function(){ expect(collection.remove(item1)).toBe(1); }); it("should the passed items array", function(){ collection.remove([item2, item3]); expect(collection.getCount()).toBe(7); }); it("should fire the remove event when passing items array", function () { var source = [], details = []; collection.on('remove', function (sender, remove) { source.push(sender); details.push(remove); }); collection.remove([item2, item3, item6]); expect(source.length).toBe(2); expect(source[0] === collection).toBe(true); expect(source[1] === collection).toBe(true); expect(details[0].at).toBe(5); expect(details[0].items.length).toBe(1); expect(details[0].items[0]).toBe(item6); expect(details[0].keys.length).toBe(1); expect(details[0].keys[0]).toBe(6); expect(details[1].at).toBe(1); expect(details[1].items.length).toBe(2); expect(details[1].items[0]).toBe(item2); expect(details[1].items[1]).toBe(item3); expect(details[1].keys.length).toBe(2); expect(details[1].keys[0]).toBe(2); expect(details[1].keys[1]).toBe(3); }); it("should return 0 if no item was found", function(){ expect(collection.remove({ id: 0 })).toBe(0); }); it("should fire the remove event", function() { var source, details; collection.on('remove', function (sender, remove) { source = sender; details = remove; }); collection.remove(item1); expect(source).toBe(collection); expect(details.at).toBe(0); expect(details.items.length).toBe(1); expect(details.items[0]).toBe(item1); }); it("should only fire a single event if the items are in a large contiguous range", function() { var spy = jasmine.createSpy(), items = [], i; for (i = 0; i < 1000; ++i) { items.push({ id: i + 1 }); } collection.add(items); collection.on('remove', spy); collection.remove(collection.getRange()); expect(spy.callCount).toBe(1); }); }); describe("removeAt", function() { it("should remove a single item", function() { collection.removeAt(1); expect(collection.getCount()).toBe(8); }); it("should return the removed item", function(){ expect(collection.removeAt(1)).toBe(item2); }); it("should return false if no item was found", function(){ expect(collection.removeAt(9)).toBeFalsy(); }); describe("event", function() { it("should fire the remove event", function() { var source, details; collection.on('remove', function (sender, remove) { source = sender; details = remove; }); collection.removeAt(1); expect(source).toBe(collection); expect(details.at).toBe(1); expect(details.items.length).toBe(1); expect(details.items[0]).toBe(item2); expect(details.keys.length).toBe(1); expect(details.keys[0]).toBe(2); }); it("should update the collection during a remove", function(){ var count, item; collection.on('remove', function(){ count = collection.getCount(); item = collection.getByKey(1); }); collection.removeAt(0); expect(count).toBe(8); expect(item).toBeUndefined(); }); }); describe("when filtered", function() { it("should remove the correct item with an all inclusive filter", function() { collection.getFilters().add(function() { return true; }); collection.removeAt(1); expect(collection.getAt(0)).toBe(item1); expect(collection.getAt(1)).toBe(item3); expect(collection.getCount()).toBe(8); }); }); }); describe("bulkRemove", function(){ it("should limit the length to that of the collection", function () { collection.removeAt(4, 100); expect(collection.getCount()).toBe(4); }); it("should remove the correct items", function(){ collection.removeAt(3, 2); expect(collection.getCount()).toBe(7); expect(collection.getAt(2)).toBe(item3); expect(collection.getAt(3)).toBe(item6); }); }); describe("removeByKey", function() { it("should remove a single item", function() { collection.removeByKey(1); expect(collection.getCount()).toBe(8); }); it("should return the removed item", function(){ expect(collection.removeByKey(1)).toBe(item1); }); it("should return false if no item was found", function(){ expect(collection.removeByKey(10)).toBeFalsy(); }); it("should fire the remove event", function() { var source, details; collection.on('remove', function (sender, remove) { source = sender; details = remove; }); collection.removeByKey(2); expect(source).toBe(collection); expect(details.at).toBe(1); expect(details.items.length).toBe(1); expect(details.items[0]).toBe(item2); expect(details.keys.length).toBe(1); expect(details.keys[0]).toBe(2); }); }); describe("removeAll", function(){ it("should remove all items", function(){ collection.removeAll(); expect(collection.getCount()).toBe(0); }); it("should fire the remove event with no passed items", function(){ var called = 0, source, details; collection.on('remove', function (sender, remove) { source = sender; details = remove; ++called; }); collection.removeAll(); expect(called).toBe(1); expect(source).toBe(collection); expect(details.at).toBe(0); expect(details.items.length).toBe(9); expect(details.items).toEqual([item1, item2, item3, item4, item5, item6, item7, item8, item9]); expect(details.keys.length).toBe(9); expect(details.keys).toEqual([1,2,3,4,5,6,7,8,9]); }); }); }); describe("clearing items", function() { beforeEach(function() { collection = new Ext.util.Collection(); collection.add([{id: 1}, {id: 2}]); }); it("should remove all items", function() { expect(collection.length).toBe(2); collection.clear(); expect(collection.length).toBe(0); }); it("should not fire the remove event", function() { var called = 0; collection.on('remove', function() { ++called; }); collection.clear(); expect(called).toBe(0); }); }); describe("determining insertion index in a sorted Collection", function() { // Items to sort into name order var item1 = {id: 2, name: 'Michael'}, item2 = {id: 3, name: 'Yanto'}, item3 = {id: 1, name: 'Bill'}, // Items to find insertion indices for item4 = {id: 4, name: 'Albert'}, // Insert index 0 when ASC, 3 when DESC item5 = {id: 5, name: 'Fred'}, // Insert index 1 when ASC, 2 when DESC item6 = {id: 6, name: 'Robert'}, // Insert index 2 when ASC, 1 when DESC item7 = {id: 7, name: 'Zebedee'};// Insert index 3 when ASC, 0 when DESC beforeEach(function() { collection = new Ext.util.Collection(); collection.add([item1, item2, item3]); }); function getInsertIndex (item) { collection.add(item); var ret = collection.indexOf(item); collection.remove(item); return ret; } describe("Sorted ascending", function() { it("should find correct insertion indices", function() { collection.sort('name'); expect(getInsertIndex(item4)).toBe(0); expect(getInsertIndex(item5)).toBe(1); expect(getInsertIndex(item6)).toBe(2); expect(getInsertIndex(item7)).toBe(3); }); }); describe("Sorted descending", function() { it("should find correct insertion indices", function() { collection.sort('name', 'DESC'); expect(getInsertIndex(item4)).toBe(3); expect(getInsertIndex(item5)).toBe(2); expect(getInsertIndex(item6)).toBe(1); expect(getInsertIndex(item7)).toBe(0); }); }); }); describe("an existing Collection", function() { var item1 = {id: 1, name: 'first'}, item2 = {id: 2, name: 'second'}, item3 = {id: 3, name: 'third'}, item4 = {id: 4, name: 'fourth'}, item5 = {id: 5, name: 'fifth'}, item6 = {id: 6, name: 'sixth'}, item7 = {id: 7, name: 'seventh'}, item8 = {id: 8, name: 'eighth'}, item9 = {id: 9, name: 'ninth'}; function fill () { collection.clear(); collection.add([ item1, // 0 -9 item2, // 1 -8 item3, // 2 -7 item4, // 3 -6 item5, // 4 -5 item6, // 5 -4 item7, // 6 -3 item8, // 7 -2 item9 // 8 -1 ]); } var generation; beforeEach(function() { collection = new Ext.util.Collection(); collection.add([item1, item2, item3]); generation = collection.generation; }); describe("updateKey", function(){ it("should do nothing if the old key doesn't exist for member item", function() { collection.updateKey(item1, 'bar'); expect(collection.getByKey('bar')).toBeUndefined(); expect(collection.getByKey(item1.id)).toBe(item1); expect(collection.generation).toBe(generation); // no changes made }); it("should do nothing if the old key doesn't exist for non-member item", function() { collection.updateKey(item4, 'bar'); expect(collection.getByKey('bar')).toBeUndefined(); expect(collection.getByKey(item4.id)).toBe(undefined); expect(collection.generation).toBe(generation); // no changes made }); it("should throw if old key is a different item", function() { expect(function () { collection.updateKey(item4, item1.id); }).toThrow(); expect(collection.getByKey(item4.id)).toBe(undefined); expect(collection.generation).toBe(generation); // no changes made }); it("should throw if new key collides with a different item", function() { // Replace item1 so we can change its key and not have any issues with // an error for claiming newItem1 was the item by id=1. We just want to // check for the collision on the new id. var newItem1 = Ext.apply({}, item1); collection.add(newItem1); generation = collection.generation; newItem1.id = item3.id; expect(function () { collection.updateKey(newItem1, item1.id); }).toThrow(); expect(collection.getByKey(item3.id)).toBe(item3); expect(collection.generation).toBe(generation); // no changes made }); it("should update the key for the item", function () { var newItem1 = Ext.apply({}, item1); collection.clear(); collection.add(newItem1, item2, item3); newItem1.id = 20; collection.updateKey(newItem1, 1); expect(collection.getByKey(1)).toBeUndefined(); expect(collection.getByKey(20)).toBe(newItem1); // The index must no longer contain the old key expect(collection.indexOfKey(1)).toBe(-1); expect(collection.indexOfKey(20)).toBe(0); }); }); describe("inserting items", function() { it("should insert a new item", function() { var count = collection.getCount(); collection.insert(0, item4); expect(collection.getCount()).toBe(count + 1); }); it("should fire the add event", function() { var called = 0, source, details; collection.on('add', function (sender, add) { ++called; source = sender; details = add; }); collection.insert(0, item4); expect(called).toBe(1); expect(source).toBe(collection); expect(details.at).toBe(0); expect(details.items.length).toBe(1); expect(details.items[0]).toBe(item4); expect(details.keys.length).toBe(1); expect(details.keys[0]).toBe(4); }); it("should insert the item at the correct location", function() { expect(collection.items[0]).toBe(item1); collection.insert(0, item4); expect(collection.items[0]).toBe(item4); }); describe("with a source", function() { var child, newItem; beforeEach(function() { fill(); child = new Ext.util.Collection(); child.setSource(collection); newItem = { id: 100, name: 'Foo' }; }); afterEach(function() { child.destroy(); newItem = child = null; }); describe("inserting into the source", function() { it("should have the correct position when inserting at the start", function() { collection.insert(0, newItem); expect(child.getAt(0)).toBe(newItem); }); it("should have the correct position when inserting into the middle", function() { collection.insert(4, newItem); expect(child.getAt(4)).toBe(newItem); }); it("should have the correct position when inserting at the end", function() { collection.insert(100, newItem); expect(collection.getAt(9)).toBe(newItem); }); describe("with source sorted", function() { it("should take the sorted position from the source", function() { collection.getSorters().add(function(item1, item2) { var n1 = item1.name, n2 = item2.name; if (n1 === n2) { return 0; } return n1 < n2 ? -1 : 1; }); newItem.name = 'a'; collection.insert(100, newItem); expect(child.getAt(0)).toBe(newItem); }); }); describe("with the child filtered", function() { it("should have the correct position when inserting at the start", function() { child.getFilters().add(function(item) { return item.name === 'third' || item.name === 'seventh' || item.name === 'Foo'; }); collection.insert(0, newItem); expect(child.getAt(0)).toBe(newItem); }); it("should have the correct position when inserting into the middle", function() { child.getFilters().add(function(item) { return item.name === 'third' || item.name === 'seventh' || item.name === 'Foo'; }); collection.insert(5, newItem); expect(child.getAt(1)).toBe(newItem); }); it("should have the correct position when inserting at the end", function() { child.getFilters().add(function(item) { return item.name === 'third' || item.name === 'seventh' || item.name === 'Foo'; }); collection.insert(100, newItem); expect(child.getAt(2)).toBe(newItem); }); it("should have the correct position when the nearest item in the child is the first item in the source", function() { child.getFilters().add(function(item) { return item.name === 'first' || item.name === 'seventh' || item.name === 'Foo'; }); collection.insert(3, newItem); expect(child.getAt(1)).toBe(newItem); }); it("should have the correct position when there is no nearest item in the source", function() { child.getFilters().add(function(item) { return item.name === 'seventh' || item.name === 'Foo'; }); collection.insert(3, newItem); expect(child.getAt(0)).toBe(newItem); }); }); }); describe("inserting into the child", function() { it("should have the correct position when inserting at the start", function() { child.insert(0, newItem); expect(collection.getAt(0)).toBe(newItem); }); it("should have the correct position when inserting into the middle", function() { child.insert(4, newItem); expect(collection.getAt(4)).toBe(newItem); }); it("should have the correct position when inserting at the end", function() { child.insert(100, newItem); expect(collection.getAt(9)).toBe(newItem); }); describe("with the source sorted", function() { it("should use the specified position", function() { collection.sort('name'); var item = {id: 100, name: 'zzzz'}; child.insert(0, item); expect(child.getAt(0)).toBe(item); expect(collection.getAt(9)).toBe(item); }); }); describe("when filtered", function() { it("should adjust the position for the source collection", function() { child.getFilters().add(function(item) { return item.name !== 'first' && item.name !== 'second'; }); child.insert(0, newItem); expect(collection.indexOf(newItem)).toBe(2); }); }); }); it("should not cause an exception when modifying the item in the source onCollectionAdd & the child is sorted", function() { var o = { observerPriority: -1000, onCollectionAdd: function(source, details) { var item = details.items[0]; item.name = 'asdf'; expect(function() { collection.itemChanged(item, ['name']); }).not.toThrow(); } }; child.getSorters().add('name'); collection.addObserver(o); collection.add({ id: 1000, name: 'q' }); }); }); }); describe("replacing items", function() { it("should replace the correct item", function() { collection.splice(1, 1, [item4]); expect(collection.getAt(1)).toBe(item4); }); it("should not change the count", function() { var count = collection.getCount(); collection.splice(1, 1, [item4]); expect(collection.getCount()).toBe(count); }); it("should fire the proper events", function() { var log = []; logEvents(collection, log, 'name'); collection.splice(1, 1, [item4]); expect(log).toEqual([ 'beginupdate', 'remove ["second"] at 1 w/keys [2]', 'add ["fourth"] at 1 w/keys [4]', 'endupdate' ]); }); }); describe("cloning", function() { it("should copy all items into the new Collection", function() { var mc2 = collection.clone(); expect(mc2.getCount()).toBe(3); expect(mc2.items[0]).toBe(item1); expect(mc2.items[1]).toBe(item2); expect(mc2.items[2]).toBe(item3); }); it("should keep the getKey fn", function(){ var fn = function(o){ return o.id; }, mc1 = new Ext.util.Collection({ keyFn: fn }); var mc2 = mc1.clone(); expect(mc2.getKey).toBe(fn); mc1 = mc2 = null; }); }); describe("getting items", function() { it("should get an item's key", function() { expect(collection.getKey(item1)).toBe(1); }); describe("first", function() { it("should get the first item", function() { expect(collection.first()).toBe(item1); }); it("should return undefined if the collection is empty", function() { collection = new Ext.util.Collection(); expect(collection.first()).toBeUndefined(); }); }); describe("last", function() { it("should get the last item", function() { expect(collection.last()).toBe(item3); }); it("should return undefined if the collection is empty", function() { collection = new Ext.util.Collection(); expect(collection.last()).toBeUndefined(); }); }); describe("get", function() { it("should get by key", function() { expect(collection.get(2)).toBe(item2); }); it("should return undefined if the key doesn't exist", function() { expect(collection.get(100)).toBeUndefined(); }); it("should get an newly added item", function() { var item5 = {id: 'a', name: 'fifth item'}; collection.add(item5); expect(collection.get('a')).toBe(item5); }); }); describe("indexOf", function() { it("should return the correct indexOf an item", function() {