extjs-gpl
Version:
GPL licensed version of Sencha Ext JS
1,273 lines (1,095 loc) • 68.2 kB
JavaScript
/* global expect, Ext, MockAjaxManager, jasmine, spyOn */
describe("Ext.data.ChainedStore", function() {
var fakeScope = {},
abeRec, aaronRec, edRec, tommyRec,
abeRaw, aaronRaw, edRaw, tommyRaw,
source, store, User;
function addSourceData() {
source.add(edRaw, abeRaw, aaronRaw, tommyRaw);
edRec = source.getAt(0);
abeRec = source.getAt(1);
aaronRec = source.getAt(2);
tommyRec = source.getAt(3);
}
function makeUser(email, data) {
if (Ext.isObject(email)) {
data = email;
} else {
data = data || {};
if (!data.email) {
data.email = email;
}
}
return new User(data);
}
function createSource(cfg) {
cfg = cfg || {};
source = new Ext.data.Store(Ext.applyIf(cfg, {
asynchronousLoad: false,
model: 'spec.User'
}));
}
function createStore(cfg) {
store = new Ext.data.ChainedStore(Ext.apply({
source: source
}, cfg));
}
function completeWithData(data) {
Ext.Ajax.mockComplete({
status: 200,
responseText: Ext.JSON.encode(data)
});
}
function expectOrder(recs, s) {
var len = recs.length,
i;
for (i = 0; i < len; ++i) {
expect(s.getAt(i)).toBe(recs[i]);
}
}
function spyOnEvent(object, eventName, fn) {
var obj = {
fn: fn || Ext.emptyFn
},
spy = spyOn(obj, "fn");
object.addListener(eventName, obj.fn);
return spy;
}
beforeEach(function() {
Ext.data.Model.schema.setNamespace('spec');
MockAjaxManager.addMethods();
edRaw = {name: 'Ed Spencer', email: 'ed@sencha.com', evilness: 100, group: 'code', old: false, age: 25, valid: 'yes'};
abeRaw = {name: 'Abe Elias', email: 'abe@sencha.com', evilness: 70, group: 'admin', old: false, age: 20, valid: 'yes'};
aaronRaw = {name: 'Aaron Conran', email: 'aaron@sencha.com', evilness: 5, group: 'admin', old: true, age: 26, valid: 'yes'};
tommyRaw = {name: 'Tommy Maintz', email: 'tommy@sencha.com', evilness: -15, group: 'code', old: true, age: 70, valid: 'yes'};
User = Ext.define('spec.User', {
extend: 'Ext.data.Model',
idProperty: 'email',
fields: [
{name: 'name', type: 'string'},
{name: 'email', type: 'string'},
{name: 'evilness', type: 'int'},
{name: 'group', type: 'string'},
{name: 'old', type: 'boolean'},
{name: 'valid', type: 'string'},
{name: 'age', type: 'int'}
]
});
createSource();
addSourceData();
});
afterEach(function() {
MockAjaxManager.removeMethods();
Ext.data.Model.schema.clear();
Ext.undefine('spec.User');
User = source = store = Ext.destroy(source, store);
Ext.data.Model.schema.clear(true);
});
describe("constructing", function() {
it("should inherit the model from the backing store", function() {
createStore();
expect(store.getModel()).toBe(User);
});
it("should have the data from the backing store", function() {
createStore();
var sourceData = source.getRange(),
storeData = store.getRange(),
len = sourceData.length,
i;
expect(storeData.length).toBe(sourceData.length);
for (i = 0; i < len; ++i) {
expect(storeData[i]).toBe(sourceData[i]);
}
});
it("should not fire a refresh or datachanged event", function() {
var spy = jasmine.createSpy();
createStore({
listeners: {
refresh: spy,
datachanged: spy
}
});
expect(spy).not.toHaveBeenCalled();
});
it("should accept an id of a store as the source", function() {
var idSource = new Ext.data.Store({
model: 'spec.User',
storeId: 'sourceId'
});
source = 'sourceId';
createStore();
source = null;
expect(store.getSource()).toBe(idSource);
idSource.destroy();
});
it("should accept a chained store as the source", function() {
createStore();
var child = new Ext.data.ChainedStore({
source: store
});
expect(child.getCount()).toBe(4);
expect(child.getModel()).toBe(User);
child.destroy();
});
});
it("should not join the records to the store", function() {
createStore();
var joined = edRec.joined;
expect(joined.length).toBe(1);
expect(joined[0]).toBe(source);
});
describe("beginUpdate/endUpdate", function() {
var beginSpy, endSpy;
beforeEach(function() {
beginSpy = jasmine.createSpy();
endSpy = jasmine.createSpy();
createStore();
});
afterEach(function() {
beginSpy = endSpy = null;
});
function setup() {
createStore();
store.on('beginupdate', beginSpy);
store.on('endupdate', endSpy);
}
describe("calls to methods directly", function() {
it("should fire beginupdate on the first call to beginUpdate", function() {
setup();
store.beginUpdate();
expect(beginSpy.callCount).toBe(1);
store.beginUpdate();
store.beginUpdate();
expect(beginSpy.callCount).toBe(1);
});
it("should fire the endupdate on the last matching call to endUpdate", function() {
setup();
store.beginUpdate();
store.beginUpdate();
store.beginUpdate();
store.endUpdate();
store.endUpdate();
expect(endSpy).not.toHaveBeenCalled();
store.endUpdate();
expect(endSpy.callCount).toBe(1);
});
});
describe("in reaction to store changes", function() {
beforeEach(function() {
setup();
});
// TODO: this could be fleshed out further to include more functionality
describe("add", function() {
it("should fire begin/end for adding a single record", function() {
source.add({});
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
it("should fire begin/end for adding multiple records in contiguous range", function() {
source.add([{}, {}, {}, {}]);
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
it("should fire begin/end for adding multiple records over a discontiguous range", function() {
store.sort('age');
source.add([{
age: 1
}, {
age: 1000
}]);
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
});
describe("remove", function() {
it("should fire begin/end for removing a single record", function() {
source.removeAt(0);
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
it("should fire begin/end for removing multiple records in contiguous range", function() {
source.remove([edRec, abeRec]);
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
it("should fire begin/end for removing multiple records over a discontiguous range", function() {
source.remove([edRec, tommyRec]);
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
});
describe("update", function() {
it("should fire begin/end for a record update", function() {
edRec.set('name', 'foo');
expect(beginSpy.callCount).toBe(1);
expect(endSpy.callCount).toBe(1);
});
});
});
});
describe("getting records", function() {
beforeEach(function() {
createStore();
addSourceData();
});
describe("first", function() {
it("should return the first record", function() {
expect(store.first()).toBe(edRec);
});
it("should return the record if there is only 1", function() {
store.remove([edRec, abeRec, tommyRec]);
expect(store.first()).toBe(aaronRec);
});
it("should return null with an empty store", function() {
store.removeAll();
expect(store.first()).toBeNull();
});
it("should be affected by filters", function() {
store.getFilters().add({
property: 'group',
value: 'admin'
});
expect(store.first()).toBe(abeRec);
});
});
describe("last", function() {
it("should return the last record", function() {
expect(store.last()).toBe(tommyRec);
});
it("should return the record if there is only 1", function() {
store.remove([edRec, abeRec, tommyRec]);
expect(store.last()).toBe(aaronRec);
});
it("should return null with an empty store", function() {
store.removeAll();
expect(store.last()).toBeNull();
});
it("should be affected by filters", function() {
store.getFilters().add({
property: 'group',
value: 'admin'
});
expect(store.last()).toBe(aaronRec);
});
});
describe("getAt", function() {
it("should return the record at the specified index", function() {
expect(store.getAt(1)).toBe(abeRec);
});
it("should return null when the index is outside the store bounds", function() {
expect(store.getAt(100)).toBe(null);
});
it("should return null when the store is empty", function() {
store.removeAll();
expect(store.getAt(0)).toBe(null);
});
});
describe("getById", function() {
it("should return the record with the matching id", function() {
expect(store.getById('tommy@sencha.com')).toBe(tommyRec);
});
it("should return null if a matching id is not found", function() {
expect(store.getById('foo@sencha.com')).toBe(null);
});
it("should return null when the store is empty", function() {
store.removeAll();
expect(store.getById('ed@sencha.com')).toBe(null);
});
it("should ignore filters", function() {
store.filter('email', 'ed@sencha.com');
expect(store.getById('aaron@sencha.com')).toBe(aaronRec);
});
});
describe("getByInternalId", function() {
it("should return the record with the matching id", function() {
expect(store.getByInternalId(tommyRec.internalId)).toBe(tommyRec);
});
it("should return null if a matching id is not found", function() {
expect(store.getByInternalId('foo@sencha.com')).toBe(null);
});
it("should return null when the store is empty", function() {
store.removeAll();
expect(store.getByInternalId('ed@sencha.com')).toBe(null);
});
it("should ignore filters", function() {
store.filter('email', 'ed@sencha.com');
expect(store.getByInternalId(aaronRec.internalId)).toBe(aaronRec);
});
it("should work correctly if not called before filtering", function() {
store.filter('email', 'ed@sencha.com');
expect(store.getByInternalId(aaronRec.internalId)).toBe(aaronRec);
});
it("should work correctly if called before & after filtering", function() {
expect(store.getByInternalId(aaronRec.internalId)).toBe(aaronRec);
store.filter('email', 'ed@sencha.com');
expect(store.getByInternalId(aaronRec.internalId)).toBe(aaronRec);
});
});
describe("getRange", function() {
it("should default to the full store range", function() {
expect(store.getRange()).toEqual([edRec, abeRec, aaronRec, tommyRec]);
});
it("should return from the start index", function() {
expect(store.getRange(2)).toEqual([aaronRec, tommyRec]);
});
it("should use the end index, and include it", function() {
expect(store.getRange(0, 2)).toEqual([edRec, abeRec, aaronRec]);
});
it("should ignore an end index greater than the store range", function() {
expect(store.getRange(1, 100)).toEqual([abeRec, aaronRec, tommyRec]);
});
});
describe("query", function() {
var coders,
slackers;
it("should return records with group: 'coder'", function() {
coders = store.query('group', 'code');
expect(coders.length).toBe(2);
expect(coders.contains(edRec)).toBe(true);
expect(coders.contains(tommyRec)).toBe(true);
expect(coders.contains(aaronRec)).toBe(false);
expect(coders.contains(abeRec)).toBe(false);
});
it("should return null if a matching id is not found", function() {
slackers = store.query('group', 'slackers');
expect(slackers.length).toBe(0);
});
it("should return null when the store is empty", function() {
store.removeAll();
coders = store.query('group', 'code');
expect(coders.length).toBe(0);
});
it("should ignore filters", function() {
store.filter('email', 'ed@sencha.com');
expect(store.getCount()).toBe(1);
coders = store.query('group', 'code');
expect(coders.length).toBe(2);
expect(coders.contains(edRec)).toBe(true);
expect(coders.contains(tommyRec)).toBe(true);
expect(coders.contains(aaronRec)).toBe(false);
expect(coders.contains(abeRec)).toBe(false);
});
});
});
describe("sorting", function() {
describe("initial values", function() {
it("should default to having no sorters", function() {
createStore();
expect(store.getSorters().getCount()).toBe(0);
});
it("should not inherit sorters from the source store", function() {
source.sort('age', 'DESC');
createStore();
expect(store.getSorters().getCount()).toBe(0);
});
it("should have the data in order of the source store by default", function() {
source.sort('age', 'DESC');
createStore();
expect(store.getAt(0)).toBe(source.getAt(0));
expect(store.getAt(1)).toBe(source.getAt(1));
expect(store.getAt(2)).toBe(source.getAt(2));
expect(store.getAt(3)).toBe(source.getAt(3));
});
});
describe("sorting the source", function() {
it("should not change the sort order in the store", function() {
createStore();
source.sort('name', 'DESC');
expectOrder([tommyRec, edRec, abeRec, aaronRec], source);
expectOrder([edRec, abeRec, aaronRec, tommyRec], store);
});
});
describe("sorting the store", function() {
it("should not change the sort order in the source store", function() {
createStore();
store.sort('name', 'DESC');
expectOrder([tommyRec, edRec, abeRec, aaronRec], store);
expectOrder([edRec, abeRec, aaronRec, tommyRec], source);
});
});
});
describe("filtering", function() {
describe("filtering the source", function() {
it("should also filter the store", function() {
createStore();
source.filter('group', 'code');
expect(store.getCount()).toBe(2);
expectOrder(source.getRange(), store);
});
it("should not affect the store filter collection", function() {
createStore();
source.filter('group', 'code');
expect(store.getFilters().getCount()).toBe(0);
});
it("should also unfilter the store", function() {
createStore();
source.filter('group', 'code');
source.getFilters().removeAll();
expect(store.getCount()).toBe(4);
expectOrder(source.getRange(), store);
});
it("should have a record present in the store when added to the source but filtered out", function() {
createStore();
source.filter('group', 'code');
var rec = makeUser('foo@sencha.com', {
group: 'admin'
});
source.add(rec);
source.getFilters().removeAll();
expect(store.indexOf(rec)).toBe(4);
});
describe("events", function() {
var spy;
beforeEach(function() {
spy = jasmine.createSpy();
createStore();
});
afterEach(function() {
spy = null;
});
it("should fire the refresh event on the store", function() {
store.on('refresh', spy);
source.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should fire the datachanged event on the store", function() {
store.on('datachanged', spy);
source.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should not fire the filterchange event", function() {
store.on('filterchange', spy);
source.filter('group', 'code');
expect(spy).not.toHaveBeenCalled();
});
describe("when the source is a chained store", function() {
var child;
beforeEach(function() {
child = new Ext.data.ChainedStore({
source: store
});
});
afterEach(function() {
child.destroy();
child = null;
});
it("should fire the refresh event on the store", function() {
child.on('refresh', spy);
store.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should fire the datachanged event on the store", function() {
child.on('datachanged', spy);
store.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should not fire the filterchange event", function() {
child.on('filterchange', spy);
store.filter('group', 'code');
expect(spy).not.toHaveBeenCalled();
});
});
});
});
describe("filtering the store", function() {
it("should not filter the source", function() {
createStore();
store.filter('group', 'code');
expect(store.getCount()).toBe(2);
expect(source.getCount()).toBe(4);
});
it("should not affect the source filter collection", function() {
createStore();
store.filter('group', 'code');
expect(source.getFilters().getCount()).toBe(0);
});
it("should filter based off source filters when the source is filtered", function() {
createStore();
source.filter('group', 'code');
store.filter('name', 'Tommy');
expect(store.getCount()).toBe(1);
expect(store.getAt(0)).toBe(tommyRec);
});
it("should apply source filters over current filters", function() {
createStore();
store.getFilters().add({
property: 'age',
value: 70,
operator: '<'
});
expect(store.getCount()).toBe(3);
source.filter('group', 'admin');
expect(store.getCount()).toBe(2);
expectOrder([abeRec, aaronRec], store);
});
describe("events", function() {
it("should fire the refresh event", function() {
var spy = jasmine.createSpy();
createStore();
store.on('refresh', spy);
store.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should fire the datachanged event", function() {
var spy = jasmine.createSpy();
createStore();
store.on('datachanged', spy);
store.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it("should fire the filterchange event", function() {
var spy = jasmine.createSpy();
createStore();
store.on('filterchange', spy);
store.filter('group', 'code');
expect(spy).toHaveBeenCalled();
expect(spy.callCount).toBe(1);
});
it('should fire the update event on both source and chained Stores', function() {
store = new Ext.data.ArrayStore({
fields: ['f1'],
data: [['f1value']]
});
var chained = new Ext.data.ChainedStore({
source: store
}),
sourceFiredUpdate,
chainedFiredUpdate,
rec = store.getAt(0);
store.on('update', function() {
sourceFiredUpdate = true;
});
chained.on('update', function(){
chainedFiredUpdate = true;
});
// There's one record in each store
expect(store.getCount()).toBe(1);
expect(chained.getCount()).toBe(1);
rec.set('f1', 'f1 updated');
// Should be no change
expect(store.getCount()).toBe(1);
expect(chained.getCount()).toBe(1);
// Both stores fire the update event
expect(sourceFiredUpdate).toBe(true);
expect(chainedFiredUpdate).toBe(true);
chained.destroy();
});
it('should NOT fire the update event on the chained Store if the record is filtered out of the source', function() {
store = new Ext.data.ArrayStore({
fields: ['f1'],
data: [['f1value']],
filters: {
property: 'f1',
value: 'f1Value'
}
});
var chained = new Ext.data.ChainedStore({
source: store
}),
sourceFiredUpdate,
chainedFiredUpdate,
rec = store.getAt(0);
store.on('update', function() {
sourceFiredUpdate = true;
});
chained.on('update', function() {
chainedFiredUpdate = true;
});
// There's one record in each store
expect(store.getCount()).toBe(1);
expect(chained.getCount()).toBe(1);
// Will filter the record out of source because "f1 updated" won't match "f1value"
rec.set('f1', 'f1 updated');
// The only record is filtered out
expect(store.getCount()).toBe(0);
expect(chained.getCount()).toBe(0);
// Source should have fired the update event
expect(sourceFiredUpdate).toBe(true);
// Chained store no longer contains the filtered record,
// so should not have fired the update event
expect(chainedFiredUpdate).toBeFalsy();
chained.destroy();
});
});
});
});
describe("loading", function() {
describe("via load", function() {
it("should populate the store", function() {
source.removeAll();
createStore();
source.load();
completeWithData([abeRaw, tommyRaw, edRaw, aaronRaw]);
expectOrder(source.getRange(), store);
});
it("should clear any existing data", function() {
createStore();
source.load();
completeWithData([{
id: 'foo@sencha.com'
}]);
expect(store.getCount()).toBe(1);
expect(store.getAt(0)).toBe(source.getAt(0));
});
describe("events", function() {
it("should not fire the add, remove or clear events", function() {
source.removeAll();
createStore();
var spy = jasmine.createSpy();
store.on('add', spy);
store.on('remove', spy);
store.on('clear', spy);
source.load();
completeWithData([abeRaw, tommyRaw, edRaw, aaronRaw]);
expect(spy).not.toHaveBeenCalled();
});
it("should relay the beforeload event", function() {
var readSpy = spyOn(User.getProxy(), 'read').andCallThrough();
source.removeAll();
createStore();
var spy = jasmine.createSpy();
store.on('beforeload', spy);
source.load();
completeWithData([abeRaw, tommyRaw, edRaw, aaronRaw]);
expect(spy).toHaveBeenCalled();
expect(spy.mostRecentCall.args[0]).toBe(store);
expect(spy.mostRecentCall.args[1]).toBe(readSpy.mostRecentCall.args[0]);
});
it("should relay the load event", function() {
var readSpy = spyOn(User.getProxy(), 'read').andCallThrough();
source.removeAll();
createStore();
var spy = jasmine.createSpy();
store.on('load', spy);
source.load();
completeWithData([abeRaw, tommyRaw, edRaw, aaronRaw]);
expect(spy).toHaveBeenCalled();
expect(spy.mostRecentCall.args[0]).toBe(store);
expect(spy.mostRecentCall.args[1]).toEqual([source.getAt(0), source.getAt(1), source.getAt(2), source.getAt(3)]);
expect(spy.mostRecentCall.args[2]).toBe(true);
expect(spy.mostRecentCall.args[3]).toBe(readSpy.mostRecentCall.args[0]);
});
it("should fire the refresh and datachanged event", function() {
createStore();
var dataChangedSpy = jasmine.createSpy(),
refreshSpy = jasmine.createSpy();
store.on('refresh', refreshSpy);
store.on('datachanged', dataChangedSpy);
source.load();
completeWithData([abeRaw, tommyRaw, edRaw, aaronRaw]);
expect(refreshSpy).toHaveBeenCalled();
expect(refreshSpy.mostRecentCall.args[0]).toBe(store);
expect(dataChangedSpy).toHaveBeenCalled();
expect(dataChangedSpy.mostRecentCall.args[0]).toBe(store);
});
});
});
describe("via loadData", function() {
it("should populate the store", function() {
source.removeAll();
createStore();
source.loadData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expectOrder(source.getRange(), store);
});
it("should clear any existing data", function() {
createStore();
source.loadData([{
id: 'foo@sencha.com'
}]);
expect(store.getCount()).toBe(1);
expect(store.getAt(0)).toBe(source.getAt(0));
});
it("should not fire the add event", function() {
source.removeAll();
createStore();
var spy = jasmine.createSpy();
store.on('add', spy);
source.loadData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(spy).not.toHaveBeenCalled();
});
it("should not fire the remove event", function() {
createStore();
var spy = jasmine.createSpy();
store.on('remove', spy);
source.loadData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(spy).not.toHaveBeenCalled();
});
it("should fire the refresh and datachanged event", function() {
createStore();
var dataChangedSpy = jasmine.createSpy(),
refreshSpy = jasmine.createSpy();
store.on('refresh', refreshSpy);
store.on('datachanged', dataChangedSpy);
source.loadData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(refreshSpy).toHaveBeenCalled();
expect(refreshSpy.mostRecentCall.args[0]).toBe(store);
expect(dataChangedSpy).toHaveBeenCalled();
expect(dataChangedSpy.mostRecentCall.args[0]).toBe(store);
});
});
describe("via loadRawData", function() {
it("should populate the store", function() {
source.removeAll();
createStore();
source.loadRawData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expectOrder(source.getRange(), store);
});
it("should clear any existing data", function() {
createStore();
source.loadRawData([{
id: 'foo@sencha.com'
}]);
expect(store.getCount()).toBe(1);
expect(store.getAt(0)).toBe(source.getAt(0));
});
it("should not fire the add event", function() {
source.removeAll();
createStore();
var spy = jasmine.createSpy();
store.on('add', spy);
source.loadRawData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(spy).not.toHaveBeenCalled();
});
it("should not fire the remove event", function() {
createStore();
var spy = jasmine.createSpy();
store.on('remove', spy);
source.loadRawData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(spy).not.toHaveBeenCalled();
});
it("should fire the refresh and datachanged event", function() {
createStore();
var dataChangedSpy = jasmine.createSpy(),
refreshSpy = jasmine.createSpy();
store.on('refresh', refreshSpy);
store.on('datachanged', dataChangedSpy);
source.loadRawData([edRaw, tommyRaw, aaronRaw, abeRaw]);
expect(refreshSpy).toHaveBeenCalled();
expect(refreshSpy.mostRecentCall.args[0]).toBe(store);
expect(dataChangedSpy).toHaveBeenCalled();
expect(dataChangedSpy.mostRecentCall.args[0]).toBe(store);
});
});
describe("with sorters", function() {
it("should apply sorters from the store", function() {
source.removeAll();
createStore();
store.sort('name', 'DESC');
source.load();
completeWithData([abeRaw, edRaw, tommyRaw, aaronRaw]);
expect(store.getAt(0).id).toBe('tommy@sencha.com');
expect(store.getAt(1).id).toBe('ed@sencha.com');
expect(store.getAt(2).id).toBe('abe@sencha.com');
expect(store.getAt(3).id).toBe('aaron@sencha.com');
});
});
describe("filters", function() {
it("should apply filters from the store", function() {
source.removeAll();
createStore();
store.getFilters().add({
property: 'group',
value: 'code'
});
source.load();
completeWithData([abeRaw, edRaw, tommyRaw, aaronRaw]);
expect(store.getCount()).toBe(2);
expect(store.getAt(0).id).toBe('ed@sencha.com');
expect(store.getAt(1).id).toBe('tommy@sencha.com');
});
});
});
describe("adding", function() {
beforeEach(function() {
createStore();
});
describe("adding to the source", function() {
it("should also add to the store", function() {
var rec = source.add({
id: 'new@sencha.com'
})[0];
expect(store.getAt(4)).toBe(rec);
});
describe("events", function() {
it("should fire the add/datachanged event on the store", function() {
var addSpy = jasmine.createSpy(),
datachangedSpy = jasmine.createSpy(),
rec, args;
store.on('add', addSpy);
store.on('datachanged', datachangedSpy);
rec = source.add({
id: 'new@sencha.com'
})[0];
expect(addSpy).toHaveBeenCalled();
args = addSpy.mostRecentCall.args;
expect(args[0]).toBe(store);
expect(args[1]).toEqual([rec]);
expect(args[2]).toBe(4);
expect(datachangedSpy).toHaveBeenCalled();
expect(datachangedSpy.mostRecentCall.args[0]).toBe(store);
});
it("should fire add on the source, then the store", function() {
var order = [];
source.on('add', function() {
order.push('source');
});
store.on('add', function() {
order.push('store');
});
source.add({
id: 'foo@sencha.com'
});
expect(order).toEqual(['source', 'store']);
});
});
describe("with sorting", function() {
describe("with the source sorted", function() {
it("should use the position from the source", function() {
source.sort('email');
var rec = source.add({
email: 'aaaa@sencha.com'
})[0];
expect(source.getAt(0)).toBe(rec);
expect(store.getAt(0)).toBe(rec);
});
});
describe("with the store sorted", function() {
it("should add to the end of the source and insert into the sorted position in the store", function() {
store.sort('email');
var rec = source.add({
email: 'bbb@sencha.com'
})[0];
expect(source.getAt(4)).toBe(rec);
expect(store.getAt(2)).toBe(rec);
});
});
describe("with both sorted", function() {
it("should insert into the correct sorted position", function() {
store.sort('email');
source.sort('email', 'desc');
var rec = source.add({
email: 'aazzon@sencha.com'
})[0];
expect(source.getAt(3)).toBe(rec);
expect(store.getAt(1)).toBe(rec);
});
});
});
describe("with filtering", function() {
it("should filter out non-matching records", function() {
store.filter('group', 'admin');
var rec = source.add({
email: 'new@sencha.com',
group: 'code'
})[0];
expect(store.indexOf(rec)).toBe(-1);
});
it("should include the filtered out record when filters are cleared", function() {
store.filter('group', 'admin');
var rec = source.add({
email: 'new@sencha.com',
group: 'code'
})[0];
store.getFilters().removeAll();
expect(store.getAt(4)).toBe(rec);
});
});
});
describe("adding to the store", function() {
it("should also add the record to the source", function() {
var rec = store.add({
id: 'new@sencha.com'
})[0];
expect(source.getAt(4)).toBe(rec);
});
describe("events", function() {
it("should fire the add/datachanged event on the source", function() {
var addSpy = jasmine.createSpy(),
datachangedSpy = jasmine.createSpy();
source.on('add', addSpy);
source.on('datachanged', datachangedSpy);
var rec = store.add({
id: 'new@sencha.com'
})[0], args;
expect(addSpy).toHaveBeenCalled();
args = addSpy.mostRecentCall.args;
expect(args[0]).toBe(source);
expect(args[1]).toEqual([rec]);
expect(args[2]).toBe(4);
expect(datachangedSpy).toHaveBeenCalled();
expect(datachangedSpy.mostRecentCall.args[0]).toBe(source);
});
it("should fire add on the source, then the store", function() {
var order = [];
source.on('add', function() {
order.push('source');
});
store.on('add', function() {
order.push('store');
});
store.add({
id: 'foo@sencha.com'
});
expect(order).toEqual(['source', 'store']);
});
});
describe("with sorting", function() {
describe("with the source sorted", function() {
it("should append to the store and add to the sorted position in the source", function() {
source.sort('email');
var rec = store.add({
email: 'aaaa@sencha.com'
})[0];
expect(source.getAt(0)).toBe(rec);
expect(store.getAt(4)).toBe(rec);
});
});
describe("with the store sorted", function() {
it("should append to the source and add to the sorted position in the store", function() {
store.sort('email');
var rec = source.add({
email: 'aaaa@sencha.com'
})[0];
expect(store.getAt(0)).toBe(rec);
});
});
describe("with both sorted", function() {
it("should insert into the correct sorted position", function() {
store.sort('email');
source.sort('email', 'desc');
var rec = source.add({
email: 'aazzon@sencha.com'
})[0];
expect(source.getAt(3)).toBe(rec);
expect(store.getAt(1)).toBe(rec);
});
});
});
});
});
describe("inserting", function() {
beforeEach(function() {
createStore();
});
describe("inserting in the source", function() {
it("should also add to the store", function() {
var rec = source.insert(0, {
id: 'new@sencha.com'
})[0];
expect(source.getAt(0)).toBe(rec);
expect(store.getAt(0)).toBe(rec);
});
describe("events", function() {
it("should fire the add/datachanged event on the store", function() {
var addSpy = jasmine.createSpy(),
datachangedSpy = jasmine.createSpy(),
rec, args;
store.on('add', addSpy);
store.on('datachanged', datachangedSpy);
rec = source.insert(0, {
id: 'new@sencha.com'
})[0];
expect(addSpy).toHaveBeenCalled();
args = addSpy.mostRecentCall.args;
expect(args[0]).toBe(store);
expect(args[1]).toEqual([rec]);
expect(args[2]).toBe(0);
expect(datachangedSpy).toHaveBeenCalled();
expect(datachangedSpy.mostRecentCall.args[0]).toBe(store);
});
it("should fire add on the source, then the store", function() {
var order = [];
source.on('add', function() {
order.push('source');
});
store.on('add', function() {
order.push('store');
});
source.insert(0, {
id: 'foo@sencha.com'
});
expect(order).toEqual(['source', 'store']);
});
});
describe("with sorting", function() {
describe("with the source sorted", function() {
it("should use the position from the source", function() {
source.sort('email');
var rec = source.insert(2, {
email: 'aaaa@sencha.com'
})[0];
expect(source.getAt(0)).toBe(rec);
expect(store.getAt(0)).toBe(rec);
});
});
describe("with the store sorted", function() {
it("should insert into the specified position in the source and the sorted position in the store", function() {
store.sort('email');
var rec = source.insert(3, {
email: 'aaaa@sencha.com'
})[0];
expect(source.getAt(3)).toBe(rec);
expect(store.getAt(0)).toBe(rec);
});
});
describe("with both sorted", function() {
it("should insert into the sorted position in both stores", function() {
store.sort('email');
source.sort('email', 'desc');
var rec = source.insert(3, {
email: 'aazzon@sencha.com'
})[0];
expect(source.getAt(3)).toBe(rec);
expect(store.getAt(1)).toBe(rec);
});
});
});
describe("with filtering", function() {
it("should filter out non-matching records", function() {
store.filter('group', 'admin');
var rec = source.insert(0, {
email: 'new@sencha.com',
group: 'code'
})[0];
expect(store.indexOf(rec)).toBe(-1);
});
it("should include the filtered out record when filters are cleared", function() {
store.filter('group', 'admin');
var rec = source.insert(0, {
email: 'new@sencha.com',
group: 'code'
})[0];
store.getFilters().removeAll();
expect(source.getAt(0)).toBe(rec);
});
it("should position the item correctly when filtered out", function() {
store.filter('group', 'admin');
var rec = source.insert(2, {
email: 'new@sencha.com',
group: 'code'
})[0];
store.getFilters().removeAll();
expect(store.getAt(2)).toBe(rec);
});
});
});
describe("inserting in the store", function() {
it("should also add the record to the source", function() {
var rec = store.insert(0, {
id: 'new@sencha.com'
})[0];
expect(source.getAt(0)).toBe(rec);
});
describe("events", function() {
it("should fire the add/datachanged event on the source", function() {
var addSpy = jasmine.createSpy(),
datachangedSpy = jasmine.createSpy();
source.on('add', addSpy);
source.on('datachanged', datachangedSpy);
var rec = store.insert(2, {