Merge branch 'master' into open671

Conflicts:
	main.js
	platform/commonUI/edit/src/policies/EditableMovePolicy.js
	platform/commonUI/general/src/directives/MCTTree.js
	platform/commonUI/general/src/ui/ToggleView.js
	platform/core/src/actions/ActionCapability.js
	platform/core/test/models/CachingModelDecoratorSpec.js
	platform/core/test/services/InstantiateSpec.js
	platform/features/events/bundle.js
	platform/features/events/src/DomainColumn.js
	platform/features/events/src/EventListController.js
	platform/features/events/src/EventListPopulator.js
	platform/features/events/src/RangeColumn.js
	platform/features/events/src/directives/MCTDataTable.js
	platform/features/events/src/policies/MessagesViewPolicy.js
	platform/features/events/test/DomainColumnSpec.js
	platform/features/events/test/EventListControllerSpec.js
	platform/features/events/test/EventListPopulatorSpec.js
	platform/features/events/test/RangeColumnSpec.js
	platform/features/events/test/policies/MessagesViewPolicySpec.js
	platform/features/rtevents/bundle.js
	platform/features/rtevents/src/DomainColumn.js
	platform/features/rtevents/src/RTEventListController.js
	platform/features/rtevents/src/RangeColumn.js
	platform/features/rtevents/src/directives/MCTRTDataTable.js
	platform/features/rtevents/src/policies/RTMessagesViewPolicy.js
	platform/features/rtevents/test/DomainColumnSpec.js
	platform/features/rtevents/test/RTEventListControllerSpec.js
	platform/features/rtevents/test/RangeColumnSpec.js
	platform/features/rtevents/test/policies/RTMessagesViewPolicySpec.js
	platform/features/rtscrolling/bundle.js
	platform/features/rtscrolling/src/DomainColumn.js
	platform/features/rtscrolling/src/NameColumn.js
	platform/features/rtscrolling/src/RTScrollingListController.js
	platform/features/rtscrolling/src/RangeColumn.js
	platform/features/scrolling/src/DomainColumn.js
	platform/features/scrolling/src/RangeColumn.js
	platform/features/scrolling/src/ScrollingListController.js
	platform/features/scrolling/src/ScrollingListPopulator.js
	platform/features/scrolling/test/DomainColumnSpec.js
	platform/features/scrolling/test/RangeColumnSpec.js
	platform/features/scrolling/test/ScrollingListControllerSpec.js
	platform/features/scrolling/test/ScrollingListPopulatorSpec.js
	platform/features/table/src/directives/MCTTable.js
	platform/features/table/test/controllers/TelemetryTableControllerSpec.js
	platform/representation/src/gestures/DropGesture.js
	platform/telemetry/src/TelemetryFormatter.js
	test-main.js
This commit is contained in:
Victor Woeltjen
2016-04-08 16:05:04 -07:00
179 changed files with 6732 additions and 19586 deletions

View File

@ -118,13 +118,13 @@ define(
});
it("populates the columns attribute", function() {
expect(table.columns.length).toBe(4);
expect(table.columns.length).toBe(5);
});
it("Build columns populates columns with domains to the left", function() {
expect(table.columns[0] instanceof DomainColumn).toBeTruthy();
expect(table.columns[1] instanceof DomainColumn).toBeTruthy();
expect(table.columns[2] instanceof DomainColumn).toBeFalsy();
expect(table.columns[2] instanceof DomainColumn).toBeTruthy();
expect(table.columns[3] instanceof DomainColumn).toBeFalsy();
});
it("Produces headers for each column based on title", function() {
@ -133,7 +133,7 @@ define(
spyOn(firstColumn, 'getTitle');
headers = table.getHeaders();
expect(headers.length).toBe(4);
expect(headers.length).toBe(5);
expect(firstColumn.getTitle).toHaveBeenCalled();
});

View File

@ -34,10 +34,20 @@ define(
mockTimeout,
mockElement;
function promise(value) {
return {
then: function (callback) {
return promise(callback(value));
}
};
}
beforeEach(function() {
watches = {};
mockScope = jasmine.createSpyObj('scope', [
'$watch',
'$on',
'$watchCollection'
]);
mockScope.$watchCollection.andCallFake(function(event, callback) {
@ -52,14 +62,15 @@ define(
mockScope.displayHeaders = true;
mockTimeout = jasmine.createSpy('$timeout');
mockTimeout.andReturn(promise(undefined));
controller = new MCTTableController(mockScope, mockTimeout, mockElement);
});
it('Reacts to changes to filters, headers, and rows', function() {
expect(mockScope.$watchCollection).toHaveBeenCalledWith('filters', jasmine.any(Function));
expect(mockScope.$watchCollection).toHaveBeenCalledWith('headers', jasmine.any(Function));
expect(mockScope.$watchCollection).toHaveBeenCalledWith('rows', jasmine.any(Function));
expect(mockScope.$watch).toHaveBeenCalledWith('headers', jasmine.any(Function));
expect(mockScope.$watch).toHaveBeenCalledWith('rows', jasmine.any(Function));
});
describe('rows', function() {
@ -82,6 +93,7 @@ define(
'col3': {'text': 'row3 col3'}
}
];
mockScope.rows = testRows;
});
it('Filters results based on filter input', function() {
@ -106,6 +118,31 @@ define(
expect(mockScope.displayRows).toEqual(testRows);
});
it('Supports adding rows individually', function() {
var addRowFunc = mockScope.$on.calls[mockScope.$on.calls.length-2].args[1],
row4 = {
'col1': {'text': 'row3 col1'},
'col2': {'text': 'ghi'},
'col3': {'text': 'row3 col3'}
};
controller.updateRows(testRows);
expect(mockScope.displayRows.length).toBe(3);
testRows.push(row4);
addRowFunc(undefined, 3);
expect(mockScope.displayRows.length).toBe(4);
});
it('Supports removing rows individually', function() {
var removeRowFunc = mockScope.$on.calls[mockScope.$on.calls.length-1].args[1];
controller.updateRows(testRows);
expect(mockScope.displayRows.length).toBe(3);
spyOn(controller, 'setVisibleRows');
//controller.setVisibleRows.andReturn(undefined);
removeRowFunc(undefined, 2);
expect(mockScope.displayRows.length).toBe(2);
expect(controller.setVisibleRows).toHaveBeenCalled();
});
describe('sorting', function() {
var sortedRows;
@ -139,7 +176,98 @@ define(
expect(sortedRows[1].col2.text).toEqual('def');
expect(sortedRows[2].col2.text).toEqual('abc');
});
describe('Adding new rows', function() {
var row4,
row5,
row6;
beforeEach(function() {
row4 = {
'col1': {'text': 'row5 col1'},
'col2': {'text': 'xyz'},
'col3': {'text': 'row5 col3'}
};
row5 = {
'col1': {'text': 'row6 col1'},
'col2': {'text': 'aaa'},
'col3': {'text': 'row6 col3'}
};
row6 = {
'col1': {'text': 'row6 col1'},
'col2': {'text': 'ggg'},
'col3': {'text': 'row6 col3'}
};
});
it('Adds new rows at the correct sort position when' +
' sorted ', function() {
mockScope.sortColumn = 'col2';
mockScope.sortDirection = 'desc';
mockScope.displayRows = controller.sortRows(testRows.slice(0));
mockScope.rows.push(row4);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[0].col2.text).toEqual('xyz');
mockScope.rows.push(row5);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[4].col2.text).toEqual('aaa');
mockScope.rows.push(row6);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[2].col2.text).toEqual('ggg');
//Add a duplicate row
mockScope.rows.push(row6);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[2].col2.text).toEqual('ggg');
expect(mockScope.displayRows[3].col2.text).toEqual('ggg');
});
it('Adds new rows at the correct sort position when' +
' sorted and filtered', function() {
mockScope.sortColumn = 'col2';
mockScope.sortDirection = 'desc';
mockScope.filters = {'col2': 'a'};//Include only
// rows with 'a'
mockScope.displayRows = controller.sortRows(testRows.slice(0));
mockScope.displayRows = controller.filterRows(testRows);
mockScope.rows.push(row5);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows.length).toBe(2);
expect(mockScope.displayRows[1].col2.text).toEqual('aaa');
mockScope.rows.push(row6);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows.length).toBe(2);
//Row was not added because does not match filter
});
it('Adds new rows at the correct sort position when' +
' not sorted ', function() {
mockScope.sortColumn = undefined;
mockScope.sortDirection = undefined;
mockScope.filters = {};
mockScope.displayRows = testRows.slice(0);
mockScope.rows.push(row5);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[3].col2.text).toEqual('aaa');
mockScope.rows.push(row6);
controller.newRow(undefined, mockScope.rows.length-1);
expect(mockScope.displayRows[4].col2.text).toEqual('ggg');
});
});
});
});
});
});

View File

@ -0,0 +1,166 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT Web includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,xit*/
define(
[
"../../src/controllers/RTTelemetryTableController"
],
function (TableController) {
"use strict";
describe('The real-time table controller', function () {
var mockScope,
mockTelemetryHandler,
mockTelemetryHandle,
mockTelemetryFormatter,
mockDomainObject,
mockTable,
mockConfiguration,
watches,
mockTableRow,
controller;
function promise(value) {
return {
then: function (callback){
return promise(callback(value));
}
};
}
beforeEach(function () {
watches = {};
mockTableRow = {'col1': 'val1', 'col2': 'row2'};
mockScope = jasmine.createSpyObj('scope', [
'$on',
'$watch',
'$watchCollection',
'$digest',
'$broadcast'
]);
mockScope.$on.andCallFake(function (expression, callback){
watches[expression] = callback;
});
mockScope.$watch.andCallFake(function (expression, callback){
watches[expression] = callback;
});
mockScope.$watchCollection.andCallFake(function (expression, callback){
watches[expression] = callback;
});
mockConfiguration = {
'range1': true,
'range2': true,
'domain1': true
};
mockTable = jasmine.createSpyObj('table',
[
'buildColumns',
'getColumnConfiguration',
'getRowValues',
'saveColumnConfiguration'
]
);
mockTable.columns = [];
mockTable.getColumnConfiguration.andReturn(mockConfiguration);
mockTable.getRowValues.andReturn(mockTableRow);
mockDomainObject= jasmine.createSpyObj('domainObject', [
'getCapability',
'useCapability',
'getModel'
]);
mockDomainObject.getModel.andReturn({});
mockDomainObject.getCapability.andReturn(
{
getMetadata: function (){
return {ranges: [{format: 'string'}]};
}
});
mockScope.domainObject = mockDomainObject;
mockTelemetryHandle = jasmine.createSpyObj('telemetryHandle', [
'getMetadata',
'unsubscribe',
'getDatum',
'promiseTelemetryObjects',
'getTelemetryObjects'
]);
// Arbitrary array with non-zero length, contents are not
// used by mocks
mockTelemetryHandle.getTelemetryObjects.andReturn([{}]);
mockTelemetryHandle.promiseTelemetryObjects.andReturn(promise(undefined));
mockTelemetryHandle.getDatum.andReturn({});
mockTelemetryHandler = jasmine.createSpyObj('telemetryHandler', [
'handle'
]);
mockTelemetryHandler.handle.andReturn(mockTelemetryHandle);
controller = new TableController(mockScope, mockTelemetryHandler, mockTelemetryFormatter);
controller.table = mockTable;
controller.handle = mockTelemetryHandle;
});
it('registers for streaming telemetry', function () {
controller.subscribe();
expect(mockTelemetryHandler.handle).toHaveBeenCalledWith(jasmine.any(Object), jasmine.any(Function), true);
});
describe('receives new telemetry', function () {
beforeEach(function() {
controller.subscribe();
mockScope.rows = [];
});
it('updates table with new streaming telemetry', function () {
mockTelemetryHandler.handle.mostRecentCall.args[1]();
expect(mockScope.$broadcast).toHaveBeenCalledWith('add:row', 0);
});
it('observes the row limit', function () {
var i = 0;
controller.maxRows = 10;
//Fill rows array with elements
for (; i < 10; i++) {
mockScope.rows.push({row: i});
}
mockTelemetryHandler.handle.mostRecentCall.args[1]();
expect(mockScope.rows.length).toBe(controller.maxRows);
expect(mockScope.rows[mockScope.rows.length-1]).toBe(mockTableRow);
expect(mockScope.rows[0].row).toBe(1);
});
});
it('enables autoscroll for event telemetry', function () {
controller.subscribe();
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
expect(mockScope.autoScroll).toBe(true);
});
});
}
);

View File

@ -26,7 +26,7 @@ define(
],
function (TableController) {
describe('The Table Controller', function() {
describe('The Table Controller', function () {
var mockScope,
mockTelemetryHandler,
mockTelemetryHandle,
@ -45,7 +45,7 @@ define(
};
}
beforeEach(function() {
beforeEach(function () {
watches = {};
mockScope = jasmine.createSpyObj('scope', [
'$on',
@ -53,13 +53,13 @@ define(
'$watchCollection'
]);
mockScope.$on.andCallFake(function(expression, callback){
mockScope.$on.andCallFake(function (expression, callback){
watches[expression] = callback;
});
mockScope.$watch.andCallFake(function(expression, callback){
mockScope.$watch.andCallFake(function (expression, callback){
watches[expression] = callback;
});
mockScope.$watchCollection.andCallFake(function(expression, callback){
mockScope.$watchCollection.andCallFake(function (expression, callback){
watches[expression] = callback;
});
@ -92,11 +92,15 @@ define(
mockTelemetryHandle = jasmine.createSpyObj('telemetryHandle', [
'request',
'promiseTelemetryObjects',
'getTelemetryObjects',
'getMetadata',
'getSeries',
'unsubscribe',
'makeDatum'
]);
mockTelemetryHandle.promiseTelemetryObjects.andReturn(promise(undefined));
mockTelemetryHandle.request.andReturn(promise(undefined));
mockTelemetryHandle.getTelemetryObjects.andReturn([]);
mockTelemetryHandler = jasmine.createSpyObj('telemetryHandler', [
'handle'
@ -108,60 +112,63 @@ define(
controller.handle = mockTelemetryHandle;
});
it('subscribes to telemetry handler for telemetry updates', function() {
it('subscribes to telemetry handler for telemetry updates', function () {
controller.subscribe();
expect(mockTelemetryHandler.handle).toHaveBeenCalled();
expect(mockTelemetryHandle.request).toHaveBeenCalled();
});
it('Unsubscribes from telemetry when scope is destroyed',function() {
it('Unsubscribes from telemetry when scope is destroyed',function () {
controller.handle = mockTelemetryHandle;
watches.$destroy();
expect(mockTelemetryHandle.unsubscribe).toHaveBeenCalled();
});
describe('the controller makes use of the table', function() {
describe('the controller makes use of the table', function () {
it('to create column definitions from telemetry' +
' metadata', function() {
' metadata', function () {
controller.setup();
expect(mockTable.buildColumns).toHaveBeenCalled();
});
it('to create column configuration, which is written to the' +
' object model', function() {
' object model', function () {
controller.setup();
expect(mockTable.getColumnConfiguration).toHaveBeenCalled();
expect(mockTable.saveColumnConfiguration).toHaveBeenCalled();
});
});
it('updates the rows on scope when historical telemetry is received', function(){
it('updates the rows on scope when historical telemetry is received', function (){
var mockSeries = {
getPointCount: function() {
getPointCount: function () {
return 5;
},
getDomainValue: function() {
getDomainValue: function () {
return 'Domain Value';
},
getRangeValue: function() {
getRangeValue: function () {
return 'Range Value';
}
},
mockRow = {'domain': 'Domain Value', 'range': 'Range' +
' Value'};
mockTelemetryHandle.makeDatum.andCallFake(function(){
mockTelemetryHandle.makeDatum.andCallFake(function (){
return mockRow;
});
mockTable.getRowValues.andReturn(mockRow);
mockTelemetryHandle.getTelemetryObjects.andReturn([mockDomainObject]);
mockTelemetryHandle.getSeries.andReturn(mockSeries);
controller.addHistoricalData(mockDomainObject, mockSeries);
expect(controller.$scope.rows.length).toBe(5);
expect(controller.$scope.rows[0]).toBe(mockRow);
});
it('filters the visible columns based on configuration', function(){
it('filters the visible columns based on configuration', function (){
controller.filterColumns();
expect(controller.$scope.headers.length).toBe(3);
expect(controller.$scope.headers[2]).toEqual('domain1');
@ -172,14 +179,14 @@ define(
expect(controller.$scope.headers[2]).toBeUndefined();
});
describe('creates event listeners', function(){
beforeEach(function() {
describe('creates event listeners', function (){
beforeEach(function () {
spyOn(controller,'subscribe');
spyOn(controller, 'filterColumns');
});
it('triggers telemetry subscription update when domain' +
' object changes', function() {
' object changes', function () {
controller.registerChangeListeners();
//'watches' object is populated by fake scope watch and
// watchCollection functions defined above
@ -189,7 +196,7 @@ define(
});
it('triggers telemetry subscription update when domain' +
' object composition changes', function() {
' object composition changes', function () {
controller.registerChangeListeners();
expect(watches['domainObject.getModel().composition']).toBeDefined();
watches['domainObject.getModel().composition']();
@ -197,7 +204,7 @@ define(
});
it('triggers telemetry subscription update when time' +
' conductor bounds change', function() {
' conductor bounds change', function () {
controller.registerChangeListeners();
expect(watches['telemetry:display:bounds']).toBeDefined();
watches['telemetry:display:bounds']();
@ -205,7 +212,7 @@ define(
});
it('triggers refiltering of the columns when configuration' +
' changes', function() {
' changes', function () {
controller.setup();
expect(watches['domainObject.getModel().configuration.table.columns']).toBeDefined();
watches['domainObject.getModel().configuration.table.columns']();