control-freak-ide/server/nodejs/tests/mixins/Selection.js
plastic-hub-dev-node-saturn 538369cff7 latest
2021-05-12 18:35:18 +02:00

557 lines
16 KiB
JavaScript

define([
'intern!tdd',
'intern/chai!assert',
'dojo/_base/declare',
'dojo/_base/array',
'dojo/_base/lang',
'dojo/json',
'dojo/dom-class',
'dstore/Memory',
'dstore/Trackable',
'dgrid/Grid',
'dgrid/OnDemandGrid',
'dgrid/Selection',
'dgrid/CellSelection',
'dgrid/extensions/Pagination'
], function (test, assert, declare, arrayUtil, lang, JSON, domClass, Memory, Trackable,
Grid, OnDemandGrid, Selection, CellSelection, Pagination) {
var mixins = {
Selection: Selection,
CellSelection: CellSelection
},
notificationTests = {},
grid,
TrackableMemory = declare([ Memory, Trackable ]);
function _createTestData(size) {
var data = [],
aCode = 'A'.charCodeAt(0),
i;
size = size || 15;
for (i = 0; i < size; i++) {
data.push({
id: i,
first: 'First' + String.fromCharCode(aCode + (i % 26)),
last: 'Last' + String.fromCharCode(aCode + 25 - (i % 26))
});
}
return data;
}
function countProperties(object) {
var count = 0,
key;
for (key in object) {
if (object.hasOwnProperty(key)) {
count++;
}
}
return count;
}
function getColumns() {
return {
first: 'First Name',
last: 'Last Name'
};
}
arrayUtil.forEach([ 'Selection', 'CellSelection' ], function (name) {
var SelectionMixin = mixins[name];
notificationTests[name + ' + update'] = function () {
var store = new TrackableMemory({
data: _createTestData()
});
grid = new (declare([OnDemandGrid, SelectionMixin]))({
columns: getColumns(),
collection: store,
sort: 'id'
});
document.body.appendChild(grid.domNode);
grid.startup();
// Using this long-winded approach for the purposes
// of the same logic working for both Selection and
// CellSelection
grid.select(grid.row(3));
grid.select(grid.row(4));
grid.select(grid.row(5));
grid.select(grid.row(6));
grid.select(grid.row(7));
var selection = grid.selection;
assert.strictEqual(countProperties(selection), 5,
'Selection contains the expected number of items');
assert.ok(selection[3] && selection[4] && selection[5] &&
selection[6] && selection[7],
'Selection contains the expected items');
store.put({ id: 5, first: 'Updated First', last: 'Updated Last'});
store.put({ id: 99, first: 'New First', last: 'New Last'});
assert.ok(selection[3] && selection[4] && selection[5] &&
selection[6] && selection[7],
'Selection still contains the same items');
assert.ok(!selection[99],
'Selection does not contain newly-added item');
store.remove(5);
assert.ok(selection[3] && selection[4] && !selection[5] &&
selection[6] && selection[7],
'Item 5 has been removed from the selection');
// Calling remove row does not notify the store so the selection is not updated.
grid.row(4).remove();
assert.ok(selection[3] && selection[4] && !selection[5] &&
selection[6] && selection[7],
'Selection is unchanged when calling removeRow directly on a store-backed grid');
grid.destroy();
};
notificationTests[name + ' + update + no store'] = function () {
grid = new (declare([Grid, SelectionMixin]))({
columns: getColumns()
});
document.body.appendChild(grid.domNode);
grid.startup();
grid.renderArray(_createTestData());
// Using this long-winded approach for the purposes
// of the same logic working for both Selection and
// CellSelection
grid.select(grid.row(3));
grid.select(grid.row(4));
grid.select(grid.row(5));
grid.select(grid.row(6));
grid.select(grid.row(7));
var selection = grid.selection;
assert.strictEqual(countProperties(selection), 5,
'Selection contains the expected number of items');
assert.ok(selection[3] && selection[4] && selection[5] &&
selection[6] && selection[7],
'Selection contains the expected items');
grid.row(4).remove();
assert.strictEqual(countProperties(selection), 4,
'Selection contains 1 fewer items after removal of selected item');
assert.ok(selection[3] && !selection[4] && selection[5] &&
selection[6] && selection[7],
'Item 4 has been removed from the selection');
grid.row(1).remove();
assert.strictEqual(countProperties(selection), 4,
'Selection is unchanged after removal of unselected item');
assert.ok(selection[3] && !selection[4] && selection[5] &&
selection[6] && selection[7],
'Selection is unchanged after removal of unselected item');
grid.row(3).remove();
assert.strictEqual(countProperties(selection), 3,
'Selection contains 1 fewer items after removal of selected item');
assert.ok(!selection[3] && !selection[4] && selection[5] &&
selection[6] && selection[7],
'Item 3 has been removed from the selection');
grid.row(5).remove();
grid.row(6).remove();
grid.row(7).remove();
assert.strictEqual(countProperties(selection), 0,
'No items are selected after all selected items have been removed');
grid.destroy();
};
notificationTests[name + ' + update + store + paging'] = function () {
// Create a selection, trigger paging, notify
var store = new TrackableMemory({
data: _createTestData(100)
});
grid = new (declare([Grid, SelectionMixin, Pagination]))({
collection: store,
columns: getColumns()
});
document.body.appendChild(grid.domNode);
grid.startup();
function checkStyles() {
// Checks to see if the rendered rows that are selected have the dgrid-selected style
// and no unselected rows have that style
var selection = grid.selection,
id,
rowElement,
rowObject,
isHighlighted,
shouldBeHighlighted;
for (id in grid._rowIdToObject) {
rowElement = document.getElementById(id);
rowObject = grid._rowIdToObject[id];
if (rowElement) {
if (name === 'Selection') {
isHighlighted = domClass.contains(rowElement, 'dgrid-selected');
}
else {
isHighlighted = domClass.contains(grid.cell(rowObject.id, 'first').element,
'dgrid-selected');
}
shouldBeHighlighted = !!selection[rowObject.id];
assert.strictEqual(isHighlighted, shouldBeHighlighted,
'Expected ' + JSON.stringify(rowObject) + ' to' +
(shouldBeHighlighted ? '' : ' not') + ' be selected.');
}
}
}
function checkSelected(ids) {
var selection = grid.selection;
var numIds = ids.length;
checkStyles();
assert.strictEqual(countProperties(selection), numIds,
'Selection contains the expected number of items: ' + numIds);
assert.ok(arrayUtil.every(ids, function (id) {
return id in selection;
}), 'Selection contains the expected items');
}
var initSelection = [3, 4, 5, 23, 24, 25];
arrayUtil.forEach(initSelection, function (id) {
grid.select(grid.row(id));
});
checkSelected(initSelection);
grid.gotoPage(4);
checkSelected(initSelection);
grid.gotoPage(1);
store.put({ id: 1, first: 'Updated First 1', last: 'Updated Last 1'});
checkSelected(initSelection);
assert.isTrue(grid.cell(1, 'first').element.innerHTML.indexOf('Updated First 1') > -1);
store.put({ id: 4, first: 'Updated First 4', last: 'Updated Last 4'});
checkSelected(initSelection);
assert.isTrue(grid.cell(4, 'first').element.innerHTML.indexOf('Updated First 4') > -1);
store.put({ id: 24, first: 'Updated First', last: 'Updated Last'});
checkSelected(initSelection);
store.put({ id: 1999, first: 'New First', last: 'New Last'});
checkSelected(initSelection);
store.remove(2);
checkSelected(initSelection);
store.remove(3);
checkSelected([4, 5, 23, 24, 25]);
store.remove(25);
checkSelected([4, 5, 23, 24]);
grid.destroy();
};
notificationTests[name + ' events + store'] = function () {
// Create and remove selections, watch for events
var store = new TrackableMemory({
data: _createTestData()
});
grid = new (declare([OnDemandGrid, SelectionMixin]))({
columns: getColumns(),
collection: store,
sort: 'id'
});
document.body.appendChild(grid.domNode);
grid.startup();
var selectEventFired;
var deselectEventFired;
grid.on('dgrid-select', function () {
selectEventFired++;
});
grid.on('dgrid-deselect', function () {
deselectEventFired++;
});
function testEvents() {
selectEventFired = 0;
deselectEventFired = 0;
grid.select(3);
assert.strictEqual(selectEventFired, 1, 'Select event fired once: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 0, 'Deselect event not fired: ' + deselectEventFired);
grid.deselect(3);
assert.strictEqual(selectEventFired, 1, 'Select event fired once: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.select(3);
assert.strictEqual(selectEventFired, 2, 'Select event fired twice: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.select(4);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.deselect(3);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 2, 'Deselect event fired twice: ' + deselectEventFired);
grid.deselect(4);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 3, 'Deselect event fired three times: ' + deselectEventFired);
}
// Run the event tests
testEvents();
// Change the store
store = new TrackableMemory({
data: _createTestData()
});
grid.set('collection', store);
// Run the tests again
testEvents();
grid.destroy();
};
notificationTests[name + ' events + no store'] = function () {
// Create and remove selections, watch for events
var selectEventFired = 0,
deselectEventFired = 0;
grid = new (declare([Grid, SelectionMixin]))({
columns: getColumns()
});
document.body.appendChild(grid.domNode);
grid.startup();
grid.renderArray(_createTestData());
grid.on('dgrid-select', function () {
selectEventFired++;
});
grid.on('dgrid-deselect', function () {
deselectEventFired++;
});
grid.select(3);
assert.strictEqual(selectEventFired, 1, 'Select event fired once: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 0, 'Deselect event not fired: ' + deselectEventFired);
grid.deselect(3);
assert.strictEqual(selectEventFired, 1, 'Select event fired once: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.select(3);
assert.strictEqual(selectEventFired, 2, 'Select event fired twice: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.select(4);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.deselect(3);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 2, 'Deselect event fired twice: ' + deselectEventFired);
grid.deselect(4);
assert.strictEqual(selectEventFired, 3, 'Select event fired three times: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 3, 'Deselect event fired three times: ' + deselectEventFired);
grid.destroy();
};
notificationTests[name + ' events + no store + remove'] = function () {
// Create selections, remove rows, watch for events
var deselectEventFired = 0;
grid = new (declare([Grid, SelectionMixin]))({
columns: getColumns()
});
document.body.appendChild(grid.domNode);
grid.startup();
grid.renderArray(_createTestData());
grid.on('dgrid-deselect', function () {
deselectEventFired++;
});
grid.select(3);
grid.select(4);
assert.strictEqual(deselectEventFired, 0, 'Deselect event not fired: ' + deselectEventFired);
grid.row(3).remove();
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
grid.row(5).remove();
assert.strictEqual(deselectEventFired, 1, 'Deselect event not fired again: ' + deselectEventFired);
grid.row(4).remove();
assert.strictEqual(deselectEventFired, 2, 'Deselect event fired a second time: ' + deselectEventFired);
grid.destroy();
};
notificationTests[name + ' events + store + remove'] = function () {
// Create selections, remove data, watch for events
var store = new TrackableMemory({
data: _createTestData()
}),
selectEventFired,
deselectEventFired;
grid = new (declare([OnDemandGrid, SelectionMixin]))({
columns: getColumns(),
collection: store,
sort: 'id'
});
document.body.appendChild(grid.domNode);
grid.startup();
grid.on('dgrid-select', function () {
selectEventFired++;
});
grid.on('dgrid-deselect', function () {
deselectEventFired++;
});
function testEvents() {
selectEventFired = 0;
deselectEventFired = 0;
grid.select(3);
grid.select(4);
assert.strictEqual(deselectEventFired, 0, 'Deselect event not fired: ' + deselectEventFired);
// Reset the select event counter. It should not fire on remove.
selectEventFired = 0;
store.remove(3);
assert.strictEqual(selectEventFired, 0, 'Select event not fired: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event fired once: ' + deselectEventFired);
store.remove(5);
assert.strictEqual(selectEventFired, 0, 'Select event not fired: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 1, 'Deselect event not fired again: ' + deselectEventFired);
store.remove(4);
assert.strictEqual(selectEventFired, 0, 'Select event not fired: ' + selectEventFired);
assert.strictEqual(deselectEventFired, 2, 'Deselect event fired a second time: ' + deselectEventFired);
}
// Test the events
testEvents();
// Change the store
store = new TrackableMemory({
data: _createTestData()
});
grid.set('collection', store);
// Test the events again
testEvents();
grid.destroy();
};
});
test.suite('Selection update handling', function () {
test.afterEach(function () {
grid.destroy();
});
for (var name in notificationTests) {
test.test(name, notificationTests[name]);
}
});
test.suite('Selection events', function () {
var store = new TrackableMemory({
data: _createTestData()
});
var handles = [];
test.beforeEach(function () {
grid = new (declare([OnDemandGrid, Selection]))({
columns: getColumns(),
sort: 'id',
collection: store
});
document.body.appendChild(grid.domNode);
grid.startup();
});
test.afterEach(function () {
grid.destroy();
for (var i = handles.length; i--;) {
handles[i].remove();
}
handles = [];
});
test.test('programmatic row deselection event', function () {
var lastEventType,
expectedEventType = 'dgrid-deselect',
eventCount = 0;
grid.select('1');
// Intentionally check for both select and deselect events -
// we should only receive a single deselect event
grid.on('dgrid-select, dgrid-deselect', function (event) {
lastEventType = event.type;
eventCount++;
});
grid.deselect('1');
grid.deselect('1');
assert.equal(eventCount, 1);
assert.equal(expectedEventType, lastEventType);
});
test.test('programmatic row selection event', function () {
var lastEventType,
expectedEventType = 'dgrid-select',
eventCount = 0;
grid.on('dgrid-select, dgrid-deselect', function (event) {
lastEventType = event.type;
eventCount++;
});
grid.select('1');
grid.select('1');
assert.equal(eventCount, 1);
assert.equal(expectedEventType, lastEventType);
});
test.test('clearSelection() within event handler', function () {
var dfd = this.async();
var numCalls = 0;
handles.push(grid.on('dgrid-select', dfd.rejectOnError(function (event) {
numCalls++;
assert.isTrue(numCalls < 2, 'dgrid-select handler should only fire once');
// clearSelection will cause selection events to be fired,
// but that should not include the originally-queued event
grid.clearSelection();
})));
grid.select('1');
// Since this test passes on 1 event firing but fails on multiple,
// resolve on a small timeout (since failure will occur instantaneously)
setTimeout(function () { dfd.resolve(); }, 100);
});
});
});