611 lines
21 KiB
JavaScript
611 lines
21 KiB
JavaScript
define("dstore/tests/Trackable", [
|
|
'intern!object',
|
|
'intern/chai!assert',
|
|
'dojo/_base/array',
|
|
'dojo/_base/declare',
|
|
'dojo/_base/lang',
|
|
'dstore/Memory',
|
|
'dstore/Store',
|
|
'dstore/Trackable',
|
|
'dstore/SimpleQuery'
|
|
], function (registerSuite, assert, arrayUtil, declare, lang, Memory, Store, Trackable, SimpleQuery) {
|
|
|
|
function createData(numItems) {
|
|
var data = [];
|
|
var i;
|
|
for (i = 0; i < numItems; i++) {
|
|
data.push({id: i, name: 'item ' + i, order: i});
|
|
}
|
|
return data;
|
|
}
|
|
|
|
function createTestSuite(suiteName, createStore) {
|
|
|
|
// A store for testing Trackable with only partial in-memory data
|
|
var PartialDataStore = declare([ Store, SimpleQuery ], (function () {
|
|
var proto = {
|
|
constructor: function () {
|
|
this.backingMemoryStore = createStore({ data: this.data }, Memory);
|
|
delete this.data;
|
|
|
|
}
|
|
};
|
|
|
|
arrayUtil.forEach(
|
|
[
|
|
'getIdentity', 'get', 'add', 'put', 'remove', 'getSync', 'addSync', 'putSync', 'removeSync',
|
|
'fetch', 'fetchRange', 'fetchSync', 'fetchRangeSync'
|
|
],
|
|
function (method) {
|
|
proto[method] = function () {
|
|
var backingStore = this.backingMemoryStore;
|
|
return backingStore[method].apply(backingStore, arguments);
|
|
};
|
|
}
|
|
);
|
|
|
|
arrayUtil.forEach(['filter', 'sort'], function (method) {
|
|
proto[method] = function () {
|
|
var newBackingStore = this.backingMemoryStore[method].apply(this.backingMemoryStore, arguments);
|
|
return lang.mixin(this.inherited(arguments), {
|
|
backingMemoryStore: newBackingStore
|
|
});
|
|
};
|
|
});
|
|
|
|
return proto;
|
|
})());
|
|
|
|
function createPrimeNumberStore() {
|
|
return createStore({
|
|
data: [
|
|
{id: 0, name: 'zero', even: true, prime: false},
|
|
{id: 1, name: 'one', prime: false},
|
|
{id: 2, name: 'two', even: true, prime: true},
|
|
{id: 3, name: 'three', prime: true},
|
|
{id: 4, name: 'four', even: true, prime: false},
|
|
{id: 5, name: 'five', prime: true}
|
|
]
|
|
}, Memory);
|
|
}
|
|
|
|
function createPartialDataStore(numItems) {
|
|
return createStore({
|
|
data: createData(numItems),
|
|
|
|
// Make backing store an observed collection so its data is kept up-to-date
|
|
track: function () {
|
|
this.backingMemoryStore = this.backingMemoryStore.track();
|
|
return this.inherited(arguments);
|
|
}
|
|
}, PartialDataStore);
|
|
}
|
|
|
|
var store = createPrimeNumberStore();
|
|
|
|
return {
|
|
name: suiteName,
|
|
|
|
'get': function () {
|
|
assert.strictEqual(store.getSync(1).name, 'one');
|
|
assert.strictEqual(store.getSync(4).name, 'four');
|
|
assert.isTrue(store.getSync(5).prime);
|
|
},
|
|
|
|
'filter': function () {
|
|
var filteredCollection = store.filter({prime: true});
|
|
|
|
var changes = [], secondChanges = [];
|
|
var tracked = filteredCollection.track();
|
|
tracked.fetch();
|
|
assert.strictEqual(tracked._results.length, 3);
|
|
tracked.on('add, update, delete', function (event) {
|
|
changes.push(event);
|
|
});
|
|
var secondObserverUpdate = tracked.on('update', function (event) {
|
|
secondChanges.push(event);
|
|
});
|
|
var secondObserverRemove = tracked.on('delete', function (event) {
|
|
secondChanges.push(event);
|
|
});
|
|
var secondObserverAdd = tracked.on('add', function (event) {
|
|
secondChanges.push(event);
|
|
});
|
|
var expectedChanges = [],
|
|
expectedSecondChanges = [];
|
|
var two = tracked._results[0];
|
|
two.prime = false;
|
|
store.put(two); // should remove it from the array
|
|
assert.strictEqual(tracked._results.length, 2);
|
|
expectedChanges.push({
|
|
type: 'update',
|
|
target: two,
|
|
index: undefined,
|
|
previousIndex: 0,
|
|
totalLength: 2
|
|
});
|
|
expectedSecondChanges.push(expectedChanges[expectedChanges.length - 1]);
|
|
secondObserverUpdate.remove();
|
|
secondObserverRemove.remove();
|
|
secondObserverAdd.remove();
|
|
var one = store.getSync(1);
|
|
one.prime = true;
|
|
store.put(one); // should add it
|
|
expectedChanges.push({
|
|
type: 'update',
|
|
target: one,
|
|
index: 2,
|
|
previousIndex: undefined,
|
|
totalLength: 3
|
|
});
|
|
assert.strictEqual(tracked._results.length, 3);
|
|
// shouldn't be added
|
|
var six = {id: 6, name: 'six'};
|
|
store.add(six);
|
|
assert.strictEqual(tracked._results.length, 3);
|
|
|
|
expectedChanges.push({
|
|
type: 'add',
|
|
target: store._restore(six),
|
|
index: undefined,
|
|
totalLength: 3
|
|
// no index because the addition doesn't have a place in the filtered results
|
|
});
|
|
|
|
// should be added
|
|
var seven = {id: 7, name: 'seven', prime: true};
|
|
store.add(seven);
|
|
assert.strictEqual(tracked._results.length, 4);
|
|
|
|
expectedChanges.push({
|
|
type: 'add',
|
|
target: store._restore(seven),
|
|
index: 3,
|
|
totalLength: 4
|
|
});
|
|
var three = store.getSync(3);
|
|
store.remove(3);
|
|
expectedChanges.push({
|
|
type: 'delete',
|
|
id: 3,
|
|
target: store._restore(three),
|
|
previousIndex: 0,
|
|
totalLength: 3
|
|
});
|
|
assert.strictEqual(tracked._results.length, 3);
|
|
|
|
assert.deepEqual(secondChanges, expectedSecondChanges);
|
|
assert.deepEqual(changes, expectedChanges);
|
|
},
|
|
|
|
'filter with zero id': function () {
|
|
var filteredCollection = store.filter({});
|
|
var results;
|
|
filteredCollection.fetch().then(function (data) {
|
|
results = data;
|
|
});
|
|
assert.strictEqual(results.length, 7);
|
|
var tracked = filteredCollection.track();
|
|
tracked.on('update', function (event) {
|
|
// we only do puts so previous & new indices must always been the same
|
|
assert.ok(event.index === event.previousIndex);
|
|
});
|
|
store.put({id: 5, name: '-FIVE-', prime: true});
|
|
store.put({id: 0, name: '-ZERO-', prime: false});
|
|
},
|
|
|
|
'paging with store.data': function () {
|
|
var results,
|
|
bigStore = createStore({ data: createData(100) }, Memory),
|
|
bigFiltered = bigStore.filter({}).sort('order');
|
|
|
|
var observations = [];
|
|
var bigObserved = bigFiltered.track();
|
|
bigObserved.on('update', function (event) {
|
|
observations.push(event);
|
|
console.log(' observed: ', event);
|
|
});
|
|
bigObserved.on('add', function (event) {
|
|
observations.push(event);
|
|
console.log(' observed: ', event);
|
|
});
|
|
bigObserved.on('delete', function (event) {
|
|
observations.push(event);
|
|
console.log(' observed: ', event);
|
|
});
|
|
bigObserved.fetchRange({ start: 0, end: 25 });
|
|
bigObserved.fetchRange({ start: 25, end: 50 });
|
|
bigObserved.fetchRange({ start: 50, end: 75 });
|
|
bigObserved.fetchRange({ start: 75, end: 100 });
|
|
|
|
var results = bigObserved.fetchSync();
|
|
bigStore.add({id: 101, name: 'one oh one', order: 2.5});
|
|
assert.strictEqual(results.length, 101);
|
|
assert.strictEqual(observations.length, 1);
|
|
bigStore.remove(101);
|
|
assert.strictEqual(observations.length, 2);
|
|
assert.strictEqual(results.length, 100);
|
|
bigStore.add({id: 102, name: 'one oh two', order: 26.5});
|
|
assert.strictEqual(results.length, 101);
|
|
assert.strictEqual(observations.length, 3);
|
|
},
|
|
|
|
'paging with store._partialResults': function () {
|
|
var bigStore = createPartialDataStore(100),
|
|
bigFiltered = bigStore.filter({}).sort('order'),
|
|
latestObservation,
|
|
bigObserved = bigFiltered.track(),
|
|
item,
|
|
assertObservationIs = function (expectedObservation) {
|
|
expectedObservation = lang.delegate(expectedObservation);
|
|
if (expectedObservation.type in { add: 1, update: 1 }
|
|
&& !('index' in expectedObservation)) {
|
|
expectedObservation.index = undefined;
|
|
}
|
|
if (expectedObservation.type in { update: 1, 'delete': 1 }
|
|
&& !('previousIndex' in expectedObservation)) {
|
|
expectedObservation.previousIndex = undefined;
|
|
}
|
|
assert.deepEqual(latestObservation, expectedObservation);
|
|
};
|
|
bigObserved.on('update', function (event) {
|
|
latestObservation = event;
|
|
});
|
|
bigObserved.on('add', function (event) {
|
|
latestObservation = event;
|
|
});
|
|
bigObserved.on('delete', function (event) {
|
|
latestObservation = event;
|
|
});
|
|
|
|
// An update outside of requested ranges has an indeterminate index
|
|
item = bigStore.getSync(0);
|
|
item.order = 1.25;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item });
|
|
|
|
// An addition outside of requested ranges has an indeterminate index
|
|
item = bigStore._restore({ id: 1.5, name: 'item 1.5', order: 1.5 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item });
|
|
|
|
// Remove additional item to make subsequent item indices and id's line up
|
|
bigStore.remove(item.id);
|
|
assertObservationIs({ type: 'delete', id: item.id });
|
|
|
|
// An update sorted to the beginning of a range and the data has a known index
|
|
bigObserved.fetchRange({ start: 0, end: 25 });
|
|
item = bigStore.getSync(0);
|
|
item.order = 0;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, index: 0, previousIndex: 1, totalLength: 100 });
|
|
|
|
// An addition sorted to the beginning of a range and the data has a known index
|
|
item = bigStore._restore({ id: -1, name: 'item -1', order: -1 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, index: 0, totalLength: 101 });
|
|
|
|
// Remove additional item to make subsequent item indices and id's line up
|
|
bigStore.remove(item.id);
|
|
assertObservationIs({ type: 'delete', id: item.id, previousIndex: 0, totalLength: 100 });
|
|
|
|
// An update sorted to the end of a range has an indeterminate index
|
|
item = bigStore.getSync(24);
|
|
item.name = 'item 24 updated';
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, previousIndex: 24, totalLength: 99 });
|
|
|
|
// An addition sorted to the end of a range has an indeterminate index
|
|
item = bigStore._restore({ id: 24.1, name: 'item 24.1', order: 24.1 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, totalLength: 99 });
|
|
|
|
// Remove additional item to make subsequent item indices and id's line up
|
|
bigStore.remove(item.id);
|
|
assertObservationIs({ type: 'delete', id: item.id, totalLength: 99 });
|
|
|
|
// The previous update with an undetermined index resulted in an item dropping from the first range
|
|
// and the first range being reduced to 0-23 instead of 0-24.
|
|
// Requesting 24-50 instead of 25-50 in order to request a contiguous range.
|
|
// Trackable should treat contiguous requested ranges as a single range.
|
|
bigObserved.fetchRange({ start: 24, end: 50 });
|
|
|
|
// An update sorted to the end of a range but adjacent to another range has a known index
|
|
item = bigStore.getSync(22);
|
|
item.order = 23.1;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, index: 23, previousIndex: 22, totalLength: 100 });
|
|
|
|
// An addition sorted to the end of a range but adjacent to another range has a known index
|
|
item = bigStore._restore({ id: 23.2, name: 'item 23.2', order: 23.2 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, index: 24, totalLength: 101 });
|
|
|
|
// Remove additional item to make subsequent item indices and id's line up
|
|
bigStore.remove(item.id);
|
|
assertObservationIs({ type: 'delete', id: item.id, previousIndex: 24, totalLength: 100 });
|
|
|
|
// An update sorted to the beginning of a range but adjacent to another range has a known index
|
|
item = bigStore.getSync(25);
|
|
item.order = 23.9;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, index: 24, previousIndex: 25, totalLength: 100 });
|
|
|
|
// An addition sorted to the beginning of a range but adjacent to another range has a known index
|
|
item = bigStore._restore({ id: 23.8, name: 'item 23.8', order: 23.8 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, index: 24, totalLength: 101 });
|
|
|
|
// Remove additional item to make subsequent item indices and id's line up
|
|
bigStore.remove(item.id);
|
|
assertObservationIs({ type: 'delete', id: item.id, previousIndex: 24, totalLength: 100 });
|
|
|
|
// Request range at end of data
|
|
bigObserved.fetchRange({ start: 75, end: 100 });
|
|
|
|
// An update at the end of a range and the data has a known index
|
|
item = bigStore.getSync(98);
|
|
item.order = 99.1;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, index: 99, previousIndex: 98, totalLength: 100 });
|
|
|
|
// An addition at the end of a range and the data has a known index
|
|
item = bigStore._restore({ id: 99.2, name: 'item 99.2', order: 99.2 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, index: 100, totalLength: 101 });
|
|
|
|
// An update at the beginning of a range has an indeterminate index
|
|
item = bigStore.getSync(76);
|
|
item.order = 74.9;
|
|
bigStore.put(item);
|
|
assertObservationIs({ type: 'update', target: item, previousIndex: 76, totalLength: 100 });
|
|
|
|
// An addition at the beginning of a range has an indeterminate index
|
|
item = bigStore._restore({ id: 74.8, name: 'item 74.8', order: 74.8 });
|
|
bigStore.add(item);
|
|
assertObservationIs({ type: 'add', target: item, totalLength: 100 });
|
|
},
|
|
|
|
'paging releaseRange with store._partialResults': function () {
|
|
var itemCount = 100,
|
|
store = createPartialDataStore(itemCount),
|
|
rangeToBeEclipsed = { start: 5, end: 15 },
|
|
rangeToBeSplit = { start: 25, end: 45 },
|
|
rangeToBeHeadTrimmed = { start: 55, end: 65 },
|
|
rangeToBeTailTrimmed = { start: 80, end: 95 },
|
|
eclipsingRange = { start: 0, end: 20 },
|
|
splittingRange = { start: 30, end: 40 },
|
|
headTrimmingRange = { start: 50, end: 60 },
|
|
tailTrimmingRange = { start: 90, end: 100 };
|
|
|
|
var trackedStore = store.track(),
|
|
assertRangeDefined = function (start, end) {
|
|
for(var i = start; i < end; ++i) {
|
|
assert.notEqual(trackedStore._partialResults[i], undefined);
|
|
}
|
|
},
|
|
assertRangeUndefined = function (start, end) {
|
|
for(var i = start; i < end; ++i) {
|
|
assert.equal(trackedStore._partialResults[i], undefined);
|
|
}
|
|
};
|
|
|
|
// Remove all of a range
|
|
trackedStore.fetchRange({ start: rangeToBeEclipsed.start, end: rangeToBeEclipsed.end });
|
|
assertRangeDefined(rangeToBeEclipsed.start, rangeToBeEclipsed.end);
|
|
trackedStore.releaseRange(eclipsingRange.start, eclipsingRange.end);
|
|
assertRangeUndefined(rangeToBeEclipsed.start, rangeToBeEclipsed.end);
|
|
|
|
// Split a range
|
|
trackedStore.fetchRange({ start: rangeToBeSplit.start, end: rangeToBeSplit.end });
|
|
assertRangeDefined(rangeToBeSplit.start, rangeToBeSplit.end);
|
|
trackedStore.releaseRange(splittingRange.start, splittingRange.end);
|
|
assertRangeDefined(rangeToBeSplit.start, splittingRange.start);
|
|
assertRangeUndefined(splittingRange.start, splittingRange.end);
|
|
assertRangeDefined(splittingRange.end, rangeToBeSplit.end);
|
|
|
|
// Remove from range head
|
|
trackedStore.fetchRange({ start: rangeToBeHeadTrimmed.start, end: rangeToBeHeadTrimmed.end });
|
|
assertRangeDefined(rangeToBeHeadTrimmed.start, rangeToBeHeadTrimmed.end);
|
|
trackedStore.releaseRange(headTrimmingRange.start, headTrimmingRange.end);
|
|
assertRangeUndefined(headTrimmingRange.start, headTrimmingRange.end);
|
|
assertRangeDefined(headTrimmingRange.end, rangeToBeHeadTrimmed.end);
|
|
|
|
// Remove from range tail
|
|
trackedStore.fetchRange({ start: rangeToBeTailTrimmed.start, end: rangeToBeTailTrimmed.end });
|
|
assertRangeDefined(rangeToBeTailTrimmed.start, rangeToBeTailTrimmed.end);
|
|
trackedStore.releaseRange(tailTrimmingRange.start, tailTrimmingRange.end);
|
|
assertRangeDefined(rangeToBeTailTrimmed.start, tailTrimmingRange.start);
|
|
assertRangeUndefined(tailTrimmingRange.start, tailTrimmingRange.end);
|
|
},
|
|
|
|
'new item with default index': function () {
|
|
var store = createPartialDataStore(100),
|
|
trackedStore = store.track();
|
|
|
|
return trackedStore.fetchRange({ start: 0, end: 25 }).then(function () {
|
|
var addEvent = null;
|
|
trackedStore.on('add', function (event) {
|
|
addEvent = event;
|
|
});
|
|
|
|
// add a new item with the default of bottom
|
|
// a new item with a default index outside a known range is treated as if it has no known index
|
|
var expectedNewItem = store._restore({ id: 200, name: 'item-200', order: Infinity });
|
|
store.add(expectedNewItem);
|
|
assert.isNotNull(addEvent);
|
|
assert.deepEqual(addEvent.target, expectedNewItem);
|
|
assert.isTrue('index' in addEvent);
|
|
assert.isUndefined(addEvent.index);
|
|
|
|
// choose a defaultIndex at the top (in known range)
|
|
store.defaultNewToStart = true;
|
|
// a new item with a default index within a known range has a known index
|
|
addEvent = null;
|
|
expectedNewItem = store._restore({ id: 201, name: 'item-201', order: Infinity });
|
|
|
|
store.add(expectedNewItem);
|
|
assert.isDefined(addEvent);
|
|
assert.deepEqual(addEvent.target, expectedNewItem);
|
|
assert.propertyVal(addEvent, 'index', 0);
|
|
|
|
store.defaultNewToStart = false;
|
|
return trackedStore.fetchRange({ start: 25, end: 102 }).then(function () {
|
|
// now add to the bottom, where it is in range
|
|
expectedNewItem = store._restore({ id: 202, name: 'item-202', order: Infinity });
|
|
|
|
store.add(expectedNewItem);
|
|
assert.isDefined(addEvent);
|
|
assert.deepEqual(addEvent.target, expectedNewItem);
|
|
assert.propertyVal(addEvent, 'index', 102);
|
|
});
|
|
});
|
|
},
|
|
|
|
'new item in empty store - with queryExecutor': function () {
|
|
var store = createStore({ data: [] }, Memory),
|
|
collection = store.filter({ type: 'test-item' }).track();
|
|
|
|
// Fetch so tracking has data to work with
|
|
collection.fetch();
|
|
|
|
var actualEvent;
|
|
collection.on('add', function (event) {
|
|
actualEvent = event;
|
|
});
|
|
|
|
var expectedTarget = collection.addSync({
|
|
type: 'test-item',
|
|
id: 1,
|
|
name: 'one'
|
|
});
|
|
|
|
assert.deepEqual(actualEvent, {
|
|
type: 'add',
|
|
index: 0,
|
|
target: expectedTarget,
|
|
totalLength: 1
|
|
});
|
|
},
|
|
|
|
'new item in empty store - without queryExecutor': function () {
|
|
var store = createStore({ data: [] }, Memory),
|
|
collection = store.track();
|
|
|
|
// Fetch so tracking has data to work with
|
|
collection.fetch();
|
|
|
|
var actualEvent;
|
|
collection.on('add', function (event) {
|
|
actualEvent = event;
|
|
});
|
|
|
|
var expectedTarget = collection.addSync({
|
|
type: 'test-item',
|
|
id: 1,
|
|
name: 'one'
|
|
});
|
|
|
|
assert.deepEqual(actualEvent, {
|
|
type: 'add',
|
|
index: 0,
|
|
target: expectedTarget,
|
|
totalLength: 1
|
|
});
|
|
},
|
|
|
|
'new item - with options.beforeId and queryExecutor': function () {
|
|
var store = createPrimeNumberStore(),
|
|
evenCollection = store.filter({ even: true }).track(),
|
|
data = evenCollection.fetchSync();
|
|
|
|
store.defaultNewToStart = true;
|
|
store.add({ id: 6, name: 'six', even: true }, { beforeId: 2 });
|
|
store.add({ id: -2, name: 'negative-two', even: true }, { beforeId: null });
|
|
|
|
assert.strictEqual(data[1].id, 6);
|
|
assert.strictEqual(data[2].id, 2);
|
|
assert.strictEqual(data[data.length - 1].id, -2);
|
|
},
|
|
|
|
'new item - with options.beforeId and no queryExecutor': function () {
|
|
var store = createPrimeNumberStore(),
|
|
collection = store.track(),
|
|
data = collection.fetchSync();
|
|
|
|
store.defaultNewToStart = true;
|
|
store.add({ id: 6, name: 'six', even: true }, { beforeId: 2 });
|
|
store.add({ id: -2, name: 'negative-two', even: true }, { beforeId: null });
|
|
|
|
assert.strictEqual(data[2].id, 6);
|
|
assert.strictEqual(data[3].id, 2);
|
|
assert.strictEqual(data[data.length - 1].id, -2);
|
|
},
|
|
|
|
'updated item - with options.beforeId and queryExecutor': function () {
|
|
var store = createPrimeNumberStore(),
|
|
evenCollection = store.filter({ even: true }).track(),
|
|
data = evenCollection.fetchSync();
|
|
|
|
store.defaultNewToStart = true;
|
|
store.put(store.getSync(4), { beforeId: 2 });
|
|
store.put(store.getSync(0), { beforeId: null });
|
|
|
|
assert.strictEqual(data[0].id, 4);
|
|
assert.strictEqual(data[1].id, 2);
|
|
assert.strictEqual(data[data.length - 1].id, 0);
|
|
},
|
|
|
|
'updated item - with options.beforeId and no queryExecutor': function () {
|
|
var store = createPrimeNumberStore(),
|
|
collection = store.track(),
|
|
data = collection.fetchSync();
|
|
|
|
store.defaultNewToStart = true;
|
|
store.put(store.getSync(4), { beforeId: 2 });
|
|
store.put(store.getSync(3), { beforeId: null });
|
|
|
|
assert.strictEqual(data[2].id, 4);
|
|
assert.strictEqual(data[3].id, 2);
|
|
assert.strictEqual(data[data.length - 1].id, 3);
|
|
},
|
|
|
|
'type': function () {
|
|
assert.isFalse(store === store.track(function () {}));
|
|
},
|
|
|
|
'track and collection.tracking.remove': function () {
|
|
var store = createStore({ data: createData(10) }, Memory),
|
|
trackedCollection = store.track();
|
|
|
|
assert.property(trackedCollection, 'tracking');
|
|
|
|
// Fetch so tracking has data to work with
|
|
trackedCollection.fetch();
|
|
|
|
var lastEvent = null;
|
|
trackedCollection.on('add, update', function (event) {
|
|
lastEvent = event;
|
|
});
|
|
|
|
store.put({ id: 11, name: 'item-11', order: 11 });
|
|
assert.isNotNull(lastEvent);
|
|
assert.isDefined(lastEvent.index);
|
|
|
|
trackedCollection.tracking.remove();
|
|
lastEvent = null;
|
|
store.put({ id: 12, name: 'item-12', order: 12 });
|
|
assert.isNull(lastEvent);
|
|
}
|
|
};
|
|
}
|
|
|
|
registerSuite(createTestSuite('Trackable mixin', function (properties, BaseStore) {
|
|
return new (declare([ BaseStore, Trackable ]))(properties);
|
|
}));
|
|
|
|
registerSuite(createTestSuite('Trackable.create()', function (properties, BaseStore) {
|
|
return Trackable.create(new BaseStore(properties));
|
|
}));
|
|
});
|