Compare commits
13 Commits
new-tutori
...
open1494
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a9df47abf6 | ||
|
|
f9c4247d01 | ||
|
|
12d1302138 | ||
|
|
09419398e9 | ||
|
|
b69e03368a | ||
|
|
4196da9f52 | ||
|
|
f09a76e23b | ||
|
|
16b6a70e22 | ||
|
|
1a7260cc14 | ||
|
|
8a75381a3d | ||
|
|
c394fe9287 | ||
|
|
06f4a955b5 | ||
|
|
a2bf92db97 |
@@ -31,10 +31,25 @@ define(
|
||||
|
||||
var firstObservedTime = Date.now(),
|
||||
images = [
|
||||
"http://www.nasa.gov/393811main_Palomar_ao_bouchez_10s_after_impact_4x3_946-710.png",
|
||||
"http://www.nasa.gov/393821main_Palomar_ao_bouchez_15s_after_impact_4x3_946-710.png",
|
||||
"http://www.nasa.gov/images/content/393801main_CfhtVeillet2_4x3_516-387.jpg",
|
||||
"http://www.nasa.gov/images/content/392790main_1024_768_GeminiNorth_NightBeforeImpact_946-710.jpg"
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg",
|
||||
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg"
|
||||
|
||||
].map(function (url, index) {
|
||||
return {
|
||||
timestamp: firstObservedTime + 1000 * index,
|
||||
|
||||
11
index.html
11
index.html
@@ -25,16 +25,8 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title></title>
|
||||
<script src="openmct-tutorial/lib/http.js">
|
||||
</script>
|
||||
<script src="bower_components/requirejs/require.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/dictionary-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/realtime-telemetry-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/historical-telemetry-plugin.js">
|
||||
</script>
|
||||
<script>
|
||||
require(['openmct'], function (openmct) {
|
||||
[
|
||||
@@ -48,9 +40,6 @@
|
||||
openmct.install(openmct.plugins.Espresso());
|
||||
openmct.install(openmct.plugins.Generator());
|
||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||
openmct.install(DictionaryPlugin());
|
||||
openmct.install(RealtimeTelemetryPlugin());
|
||||
openmct.install(HistoricalTelemetryPlugin());
|
||||
openmct.start();
|
||||
});
|
||||
</script>
|
||||
|
||||
Submodule openmct-tutorial deleted from 7076a15d3a
@@ -76,17 +76,18 @@
|
||||
&:not(.first) {
|
||||
border-top: 1px solid $colorFormLines;
|
||||
}
|
||||
.form-row {
|
||||
@include align-items(center);
|
||||
border: none;
|
||||
padding: $interiorMarginSm 0;
|
||||
.label {
|
||||
min-width: 80px;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='search'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.form-row {
|
||||
@include align-items(center);
|
||||
border: none !important;
|
||||
margin-bottom: 0 !important;
|
||||
padding: $interiorMarginSm 0;
|
||||
.label {
|
||||
min-width: 80px;
|
||||
}
|
||||
input[type='text'],
|
||||
input[type='search'] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,8 +237,7 @@ define([
|
||||
"$scope",
|
||||
"$q",
|
||||
"dialogService",
|
||||
"telemetryHandler",
|
||||
"telemetryFormatter",
|
||||
"openmct",
|
||||
"throttle"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -35,13 +35,15 @@ define(
|
||||
* @constructor
|
||||
* @param {Scope} $scope the controller's Angular scope
|
||||
*/
|
||||
function FixedController($scope, $q, dialogService, telemetryHandler, telemetryFormatter) {
|
||||
function FixedController($scope, $q, dialogService, openmct) {
|
||||
var self = this,
|
||||
handle,
|
||||
names = {}, // Cache names by ID
|
||||
values = {}, // Cache values by ID
|
||||
elementProxiesById = {},
|
||||
maxDomainValue = Number.POSITIVE_INFINITY;
|
||||
var subscriptions = [];
|
||||
var limitEvaluators = {};
|
||||
|
||||
// Convert from element x/y/width/height to an
|
||||
// appropriate ng-style argument, to position elements.
|
||||
@@ -112,18 +114,20 @@ define(
|
||||
}
|
||||
|
||||
// Update the displayed value for this object
|
||||
function updateValue(telemetryObject) {
|
||||
var limit = telemetryObject &&
|
||||
telemetryObject.getCapability('limit'),
|
||||
datum = telemetryObject &&
|
||||
handle.getDatum(telemetryObject);
|
||||
function updateValue(telemetryObject, datum) {
|
||||
var limitEvaluator = limitEvaluators[telemetryObject];
|
||||
var timeSystem = openmct.conductor.timeSystem();
|
||||
var metadata = openmct.telemetry.getMetadata(telemetryObject);
|
||||
var domain = timeSystem && openmct.conductor.timeSystem().metadata.key;
|
||||
var domainValue = timeSystem && datum[domain];
|
||||
var rangeField =
|
||||
var rangeValue =
|
||||
|
||||
if (telemetryObject &&
|
||||
(handle.getDomainValue(telemetryObject) < maxDomainValue)) {
|
||||
if (timeSystem && domainValue < maxDomainValue) {
|
||||
setDisplayedValue(
|
||||
telemetryObject,
|
||||
handle.getRangeValue(telemetryObject),
|
||||
limit && datum && limit.evaluate(datum)
|
||||
limitEvaluator && limitEvaluator.evaluate(datum)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -197,35 +201,32 @@ define(
|
||||
elementProxiesById[id].push(elementProxy);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Ensure elements for all domain objects?
|
||||
}
|
||||
|
||||
// Free up subscription to telemetry
|
||||
function releaseSubscription() {
|
||||
if (handle) {
|
||||
handle.unsubscribe();
|
||||
handle = undefined;
|
||||
}
|
||||
function unsubscribe() {
|
||||
subscriptions.forEach(function (unsubscribe) {
|
||||
unsubscribe();
|
||||
})
|
||||
subscriptions = [];
|
||||
}
|
||||
|
||||
// Subscribe to telemetry updates for this domain object
|
||||
function subscribe(domainObject) {
|
||||
// Release existing subscription (if any)
|
||||
if (handle) {
|
||||
handle.unsubscribe();
|
||||
var newObject = domainObject.getCapability('adapter');
|
||||
|
||||
if (subscriptions.length > 0) {
|
||||
unsubscribe();
|
||||
}
|
||||
|
||||
// Make a new subscription
|
||||
handle = domainObject && telemetryHandler.handle(
|
||||
domainObject,
|
||||
updateValues
|
||||
);
|
||||
// Request an initial historical telemetry value
|
||||
handle.request(
|
||||
{ size: 1 }, // Only need a single data point
|
||||
updateValueFromSeries
|
||||
);
|
||||
if (openmct.telemetry.canProvideTelemetry(newObject)){
|
||||
subscriptions = [openmct.telemetry.subscribe(newObject)];
|
||||
} else {
|
||||
openmct.composition.get(newObject).load().then(function (composees) {
|
||||
subscriptions = composees.filter(openmct.telemetry.canProvideTelemetry).map(function(object) {
|
||||
return openmct.telemetry.subscribe(object, updateValue.bind(object));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Handle changes in the object's composition
|
||||
@@ -321,7 +322,7 @@ define(
|
||||
$scope.$watch("domainObject", subscribe);
|
||||
|
||||
// Free up subscription on destroy
|
||||
$scope.$on("$destroy", releaseSubscription);
|
||||
$scope.$on("$destroy", unsubscribe);
|
||||
|
||||
// Position panes where they are dropped
|
||||
$scope.$on("mctDrop", handleDrop);
|
||||
|
||||
@@ -112,22 +112,6 @@ define(
|
||||
this.lastBounds = bounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines is a given telemetry datum is within the bounds currently
|
||||
* defined for this telemetry collection.
|
||||
* @private
|
||||
* @param datum
|
||||
* @returns {boolean}
|
||||
*/
|
||||
TelemetryCollection.prototype.inBounds = function (datum) {
|
||||
var noBoundsDefined = !this.lastBounds || (this.lastBounds.start === undefined && this.lastBounds.end === undefined);
|
||||
var withinBounds =
|
||||
_.get(datum, this.sortField) >= this.lastBounds.start &&
|
||||
_.get(datum, this.sortField) <= this.lastBounds.end;
|
||||
|
||||
return noBoundsDefined || withinBounds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an individual item to the collection. Used internally only
|
||||
* @private
|
||||
@@ -173,9 +157,10 @@ define(
|
||||
// based on time stamp because the array is guaranteed ordered due
|
||||
// to sorted insertion.
|
||||
var startIx = _.sortedIndex(array, item, this.sortField);
|
||||
var endIx;
|
||||
|
||||
if (startIx !== array.length) {
|
||||
var endIx = _.sortedLastIndex(array, item, this.sortField);
|
||||
endIx = _.sortedLastIndex(array, item, this.sortField);
|
||||
|
||||
// Create an array of potential dupes, based on having the
|
||||
// same time stamp
|
||||
@@ -185,7 +170,7 @@ define(
|
||||
}
|
||||
|
||||
if (!isDuplicate) {
|
||||
array.splice(startIx, 0, item);
|
||||
array.splice(endIx || startIx, 0, item);
|
||||
|
||||
//Return true if it was added and in bounds
|
||||
return array === this.telemetry;
|
||||
|
||||
@@ -425,6 +425,38 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Finds the correct insertion point for a new row, which takes into
|
||||
* account duplicates to make sure new rows are inserted in a way that
|
||||
* maintains arrival order.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} searchArray
|
||||
* @param {Object} searchElement Object to find the insertion point for
|
||||
*/
|
||||
MCTTableController.prototype.findInsertionPoint = function (searchArray, searchElement) {
|
||||
//First, use a binary search to find the correct insertion point
|
||||
var index = this.binarySearch(searchArray, searchElement, 0, searchArray.length - 1);
|
||||
var testIndex = index;
|
||||
|
||||
//It's possible that the insertion point is a duplicate of the element to be inserted
|
||||
var isDupe = function () {
|
||||
return this.sortComparator(searchElement,
|
||||
searchArray[testIndex][this.$scope.sortColumn].text) === 0;
|
||||
}.bind(this);
|
||||
|
||||
// In the event of a duplicate, scan left or right (depending on
|
||||
// sort order) to find an insertion point that maintains order received
|
||||
while (testIndex >= 0 && testIndex < searchArray.length && isDupe()) {
|
||||
if (this.$scope.sortDirection === 'asc') {
|
||||
index = ++testIndex;
|
||||
} else {
|
||||
index = testIndex--;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -439,9 +471,9 @@ define(
|
||||
case -1:
|
||||
return this.binarySearch(searchArray, searchElement, min,
|
||||
sampleAt - 1);
|
||||
case 0 :
|
||||
case 0:
|
||||
return sampleAt;
|
||||
case 1 :
|
||||
case 1:
|
||||
return this.binarySearch(searchArray, searchElement,
|
||||
sampleAt + 1, max);
|
||||
}
|
||||
@@ -458,7 +490,7 @@ define(
|
||||
index = array.length;
|
||||
} else {
|
||||
//Sort is enabled, perform binary search to find insertion point
|
||||
index = this.binarySearch(array, element[this.$scope.sortColumn].text, 0, array.length - 1);
|
||||
index = this.findInsertionPoint(array, element[this.$scope.sortColumn].text);
|
||||
}
|
||||
if (index === -1) {
|
||||
array.unshift(element);
|
||||
|
||||
@@ -72,7 +72,7 @@ define(
|
||||
* Create a new format object from legacy object, and replace it
|
||||
* when it changes
|
||||
*/
|
||||
this.newObject = objectUtils.toNewFormat($scope.domainObject.getModel(),
|
||||
this.domainObject = objectUtils.toNewFormat($scope.domainObject.getModel(),
|
||||
$scope.domainObject.getId());
|
||||
|
||||
_.bindAll(this, [
|
||||
@@ -144,9 +144,9 @@ define(
|
||||
this.unobserveObject();
|
||||
}
|
||||
|
||||
this.unobserveObject = this.openmct.objects.observe(this.newObject, "*",
|
||||
this.unobserveObject = this.openmct.objects.observe(this.domainObject, "*",
|
||||
function (domainObject) {
|
||||
this.newObject = domainObject;
|
||||
this.domainObject = domainObject;
|
||||
this.getData();
|
||||
}.bind(this)
|
||||
);
|
||||
@@ -364,11 +364,8 @@ define(
|
||||
var telemetryApi = this.openmct.telemetry;
|
||||
var telemetryCollection = this.telemetry;
|
||||
//Set table max length to avoid unbounded growth.
|
||||
//var maxRows = 100000;
|
||||
var maxRows = Number.MAX_VALUE;
|
||||
var limitEvaluator;
|
||||
var added = false;
|
||||
var scope = this.$scope;
|
||||
var table = this.table;
|
||||
|
||||
this.subscriptions.forEach(function (subscription) {
|
||||
@@ -379,16 +376,6 @@ define(
|
||||
function newData(domainObject, datum) {
|
||||
limitEvaluator = telemetryApi.limitEvaluator(domainObject);
|
||||
added = telemetryCollection.add([table.getRowValues(limitEvaluator, datum)]);
|
||||
|
||||
//Inform table that a new row has been added
|
||||
if (scope.rows.length > maxRows) {
|
||||
scope.$broadcast('remove:rows', scope.rows[0]);
|
||||
scope.rows.shift();
|
||||
}
|
||||
if (!scope.loading && added) {
|
||||
scope.$broadcast('add:row',
|
||||
scope.rows.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
objects.forEach(function (object) {
|
||||
@@ -399,6 +386,42 @@ define(
|
||||
return objects;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an array of telemetry objects in this view that should be
|
||||
* subscribed to.
|
||||
* @private
|
||||
* @returns {Promise<Array>} a promise that resolves with an array of
|
||||
* telemetry objects in this view.
|
||||
*/
|
||||
TelemetryTableController.prototype.getTelemetryObjects = function () {
|
||||
var telemetryApi = this.openmct.telemetry;
|
||||
var compositionApi = this.openmct.composition;
|
||||
|
||||
function filterForTelemetry(objects) {
|
||||
return objects.filter(telemetryApi.canProvideTelemetry.bind(telemetryApi));
|
||||
}
|
||||
|
||||
/*
|
||||
* If parent object is a telemetry object, subscribe to it. Do not
|
||||
* test composees.
|
||||
*/
|
||||
if (telemetryApi.canProvideTelemetry(this.domainObject)) {
|
||||
return Promise.resolve([this.domainObject]);
|
||||
} else {
|
||||
/*
|
||||
* If parent object is not a telemetry object, subscribe to all
|
||||
* composees that are telemetry producing objects.
|
||||
*/
|
||||
var composition = compositionApi.get(this.domainObject);
|
||||
|
||||
if (composition) {
|
||||
return composition
|
||||
.load()
|
||||
.then(filterForTelemetry);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Request historical data, and subscribe to for real-time data.
|
||||
* @private
|
||||
@@ -406,10 +429,7 @@ define(
|
||||
* established, and historical telemetry is received and processed.
|
||||
*/
|
||||
TelemetryTableController.prototype.getData = function () {
|
||||
var telemetryApi = this.openmct.telemetry;
|
||||
var compositionApi = this.openmct.composition;
|
||||
var scope = this.$scope;
|
||||
var newObject = this.newObject;
|
||||
|
||||
this.telemetry.clear();
|
||||
this.telemetry.bounds(this.openmct.conductor.bounds());
|
||||
@@ -421,28 +441,9 @@ define(
|
||||
console.error(e.stack);
|
||||
}
|
||||
|
||||
function filterForTelemetry(objects) {
|
||||
return objects.filter(telemetryApi.canProvideTelemetry.bind(telemetryApi));
|
||||
}
|
||||
|
||||
function getDomainObjects() {
|
||||
var objects = [newObject];
|
||||
var composition = compositionApi.get(newObject);
|
||||
|
||||
if (composition) {
|
||||
return composition
|
||||
.load()
|
||||
.then(function (children) {
|
||||
return objects.concat(children);
|
||||
});
|
||||
} else {
|
||||
return Promise.resolve(objects);
|
||||
}
|
||||
}
|
||||
scope.rows = [];
|
||||
|
||||
return getDomainObjects()
|
||||
.then(filterForTelemetry)
|
||||
return this.getTelemetryObjects()
|
||||
.then(this.loadColumns)
|
||||
.then(this.subscribeToNewData)
|
||||
.then(this.getHistoricalData)
|
||||
|
||||
@@ -138,6 +138,27 @@ define(
|
||||
};
|
||||
collection.add([addedObjectB, addedObjectA]);
|
||||
|
||||
expect(collection.telemetry[11]).toBe(addedObjectB);
|
||||
}
|
||||
);
|
||||
it("maintains insertion order in the case of duplicate time stamps",
|
||||
function () {
|
||||
var addedObjectA = {
|
||||
timestamp: 10000,
|
||||
value: {
|
||||
integer: 10,
|
||||
text: integerTextMap[10]
|
||||
}
|
||||
};
|
||||
var addedObjectB = {
|
||||
timestamp: 10000,
|
||||
value: {
|
||||
integer: 11,
|
||||
text: integerTextMap[11]
|
||||
}
|
||||
};
|
||||
collection.add([addedObjectA, addedObjectB]);
|
||||
|
||||
expect(collection.telemetry[11]).toBe(addedObjectB);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -459,14 +459,14 @@ define(
|
||||
|
||||
beforeEach(function () {
|
||||
row4 = {
|
||||
'col1': {'text': 'row5 col1'},
|
||||
'col1': {'text': 'row4 col1'},
|
||||
'col2': {'text': 'xyz'},
|
||||
'col3': {'text': 'row5 col3'}
|
||||
'col3': {'text': 'row4 col3'}
|
||||
};
|
||||
row5 = {
|
||||
'col1': {'text': 'row6 col1'},
|
||||
'col1': {'text': 'row5 col1'},
|
||||
'col2': {'text': 'aaa'},
|
||||
'col3': {'text': 'row6 col3'}
|
||||
'col3': {'text': 'row5 col3'}
|
||||
};
|
||||
row6 = {
|
||||
'col1': {'text': 'row6 col1'},
|
||||
@@ -490,6 +490,71 @@ define(
|
||||
expect(mockScope.displayRows[3].col2.text).toEqual('ggg');
|
||||
});
|
||||
|
||||
it('Inserts duplicate values for sort column in order received when sorted descending', function () {
|
||||
mockScope.sortColumn = 'col2';
|
||||
mockScope.sortDirection = 'desc';
|
||||
|
||||
mockScope.displayRows = controller.sortRows(testRows.slice(0));
|
||||
|
||||
var row6b = {
|
||||
'col1': {'text': 'row6b col1'},
|
||||
'col2': {'text': 'ggg'},
|
||||
'col3': {'text': 'row6b col3'}
|
||||
};
|
||||
var row6c = {
|
||||
'col1': {'text': 'row6c col1'},
|
||||
'col2': {'text': 'ggg'},
|
||||
'col3': {'text': 'row6c col3'}
|
||||
};
|
||||
|
||||
controller.addRows(undefined, [row4, row5]);
|
||||
controller.addRows(undefined, [row6, row6b, row6c]);
|
||||
expect(mockScope.displayRows[0].col2.text).toEqual('xyz');
|
||||
expect(mockScope.displayRows[7].col2.text).toEqual('aaa');
|
||||
|
||||
// Added duplicate rows
|
||||
expect(mockScope.displayRows[2].col2.text).toEqual('ggg');
|
||||
expect(mockScope.displayRows[3].col2.text).toEqual('ggg');
|
||||
expect(mockScope.displayRows[4].col2.text).toEqual('ggg');
|
||||
|
||||
// Check that original order is maintained with dupes
|
||||
expect(mockScope.displayRows[2].col3.text).toEqual('row6c col3');
|
||||
expect(mockScope.displayRows[3].col3.text).toEqual('row6b col3');
|
||||
expect(mockScope.displayRows[4].col3.text).toEqual('row6 col3');
|
||||
});
|
||||
|
||||
it('Inserts duplicate values for sort column in order received when sorted ascending', function () {
|
||||
mockScope.sortColumn = 'col2';
|
||||
mockScope.sortDirection = 'asc';
|
||||
|
||||
mockScope.displayRows = controller.sortRows(testRows.slice(0));
|
||||
|
||||
var row6b = {
|
||||
'col1': {'text': 'row6b col1'},
|
||||
'col2': {'text': 'ggg'},
|
||||
'col3': {'text': 'row6b col3'}
|
||||
};
|
||||
var row6c = {
|
||||
'col1': {'text': 'row6c col1'},
|
||||
'col2': {'text': 'ggg'},
|
||||
'col3': {'text': 'row6c col3'}
|
||||
};
|
||||
|
||||
controller.addRows(undefined, [row4, row5, row6]);
|
||||
controller.addRows(undefined, [row6b, row6c]);
|
||||
expect(mockScope.displayRows[0].col2.text).toEqual('aaa');
|
||||
expect(mockScope.displayRows[7].col2.text).toEqual('xyz');
|
||||
|
||||
// Added duplicate rows
|
||||
expect(mockScope.displayRows[3].col2.text).toEqual('ggg');
|
||||
expect(mockScope.displayRows[4].col2.text).toEqual('ggg');
|
||||
expect(mockScope.displayRows[5].col2.text).toEqual('ggg');
|
||||
// Check that original order is maintained with dupes
|
||||
expect(mockScope.displayRows[3].col3.text).toEqual('row6 col3');
|
||||
expect(mockScope.displayRows[4].col3.text).toEqual('row6b col3');
|
||||
expect(mockScope.displayRows[5].col3.text).toEqual('row6c col3');
|
||||
});
|
||||
|
||||
it('Adds new rows at the correct sort position when' +
|
||||
' sorted and filtered', function () {
|
||||
mockScope.sortColumn = 'col2';
|
||||
|
||||
@@ -161,7 +161,7 @@ define(
|
||||
});
|
||||
});
|
||||
|
||||
describe ('Subscribes to new data', function () {
|
||||
describe ('when getting telemetry', function () {
|
||||
var mockComposition,
|
||||
mockTelemetryObject,
|
||||
mockChildren,
|
||||
@@ -173,9 +173,7 @@ define(
|
||||
"load"
|
||||
]);
|
||||
|
||||
mockTelemetryObject = jasmine.createSpyObj("mockTelemetryObject", [
|
||||
"something"
|
||||
]);
|
||||
mockTelemetryObject = {};
|
||||
mockTelemetryObject.identifier = {
|
||||
key: "mockTelemetryObject"
|
||||
};
|
||||
@@ -192,22 +190,12 @@ define(
|
||||
});
|
||||
|
||||
done = false;
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
});
|
||||
|
||||
it('fetches historical data', function () {
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
expect(mockTelemetryAPI.request).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Object));
|
||||
});
|
||||
});
|
||||
|
||||
it('fetches historical data for the time period specified by the conductor bounds', function () {
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
@@ -217,17 +205,11 @@ define(
|
||||
});
|
||||
});
|
||||
|
||||
it('subscribes to new data', function () {
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Function), {});
|
||||
it('unsubscribes on view destruction', function () {
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
|
||||
});
|
||||
it('and unsubscribes on view destruction', function () {
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
@@ -239,6 +221,87 @@ define(
|
||||
expect(unsubscribe).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
it('fetches historical data for the time period specified by the conductor bounds', function () {
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
expect(mockTelemetryAPI.request).toHaveBeenCalledWith(mockTelemetryObject, mockBounds);
|
||||
});
|
||||
});
|
||||
|
||||
it('fetches data for, and subscribes to parent object if it is a telemetry object', function () {
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Function), {});
|
||||
expect(mockTelemetryAPI.request).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Object));
|
||||
});
|
||||
});
|
||||
it('fetches data for, and subscribes to parent object if it is a telemetry object', function () {
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Function), {});
|
||||
expect(mockTelemetryAPI.request).toHaveBeenCalledWith(mockTelemetryObject, jasmine.any(Object));
|
||||
});
|
||||
});
|
||||
|
||||
it('fetches data for, and subscribes to any composees that are telemetry objects if parent is not', function () {
|
||||
mockChildren = [
|
||||
{name: "child 1"}
|
||||
];
|
||||
var mockTelemetryChildren = [
|
||||
{name: "child 2"},
|
||||
{name: "child 3"},
|
||||
{name: "child 4"}
|
||||
];
|
||||
mockChildren = mockChildren.concat(mockTelemetryChildren);
|
||||
mockComposition.load.andReturn(Promise.resolve(mockChildren));
|
||||
|
||||
mockTelemetryAPI.canProvideTelemetry.andCallFake(function (object) {
|
||||
if (object === mockTelemetryObject) {
|
||||
return false;
|
||||
} else {
|
||||
return mockTelemetryChildren.indexOf(object) !== -1;
|
||||
}
|
||||
});
|
||||
|
||||
controller.getData().then(function () {
|
||||
done = true;
|
||||
});
|
||||
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
}, "getData to return", 100);
|
||||
|
||||
runs(function () {
|
||||
mockTelemetryChildren.forEach(function (child) {
|
||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(child, jasmine.any(Function), {});
|
||||
});
|
||||
|
||||
mockTelemetryChildren.forEach(function (child) {
|
||||
expect(mockTelemetryAPI.request).toHaveBeenCalledWith(child, jasmine.any(Object));
|
||||
});
|
||||
|
||||
expect(mockTelemetryAPI.subscribe).not.toHaveBeenCalledWith(mockChildren[0], jasmine.any(Function), {});
|
||||
expect(mockTelemetryAPI.subscribe).not.toHaveBeenCalledWith(mockTelemetryObject[0], jasmine.any(Function), {});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('When in real-time mode, enables auto-scroll', function () {
|
||||
|
||||
@@ -140,7 +140,8 @@ define(
|
||||
typeRequest = (type && type.getDefinition().telemetry) || {},
|
||||
modelTelemetry = domainObject.getModel().telemetry,
|
||||
fullRequest = Object.create(typeRequest),
|
||||
bounds;
|
||||
bounds,
|
||||
timeSystem;
|
||||
|
||||
// Add properties from the telemetry field of this
|
||||
// specific domain object.
|
||||
@@ -167,6 +168,13 @@ define(
|
||||
fullRequest.end = bounds.end;
|
||||
}
|
||||
|
||||
if (request.domain === undefined) {
|
||||
timeSystem = this.openmct.conductor.timeSystem();
|
||||
if (timeSystem !== undefined) {
|
||||
fullRequest.domain = timeSystem.metadata.key;
|
||||
}
|
||||
}
|
||||
|
||||
return fullRequest;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,6 +104,13 @@ define(
|
||||
start: 0,
|
||||
end: 1
|
||||
};
|
||||
},
|
||||
timeSystem: function () {
|
||||
return {
|
||||
metadata: {
|
||||
key: 'mockTimeSystem'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -141,7 +148,8 @@ define(
|
||||
id: "testId", // from domain object
|
||||
source: "testSource", // from model
|
||||
key: "testKey", // from model
|
||||
start: 42 // from argument
|
||||
start: 42, // from argument
|
||||
domain: 'mockTimeSystem'
|
||||
}]);
|
||||
});
|
||||
|
||||
@@ -160,7 +168,8 @@ define(
|
||||
source: "testSource",
|
||||
key: "testKey",
|
||||
start: 0,
|
||||
end: 1
|
||||
end: 1,
|
||||
domain: 'mockTimeSystem'
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,7 +185,8 @@ define(
|
||||
source: "testSource", // from model
|
||||
key: "testId", // from domain object
|
||||
start: 0,
|
||||
end: 1
|
||||
end: 1,
|
||||
domain: 'mockTimeSystem'
|
||||
});
|
||||
});
|
||||
|
||||
@@ -257,7 +267,8 @@ define(
|
||||
source: "testSource",
|
||||
key: "testKey",
|
||||
start: 0,
|
||||
end: 1
|
||||
end: 1,
|
||||
domain: 'mockTimeSystem'
|
||||
}]
|
||||
);
|
||||
|
||||
@@ -274,8 +285,28 @@ define(
|
||||
expect(mockUnsubscribe).not.toHaveBeenCalled();
|
||||
subscription(); // should be an unsubscribe function
|
||||
expect(mockUnsubscribe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("applies time conductor bounds if request bounds not defined", function () {
|
||||
var fullRequest = telemetry.buildRequest({});
|
||||
var mockBounds = mockAPI.conductor.bounds();
|
||||
|
||||
expect(fullRequest.start).toBe(mockBounds.start);
|
||||
expect(fullRequest.end).toBe(mockBounds.end);
|
||||
|
||||
fullRequest = telemetry.buildRequest({start: 10, end: 20});
|
||||
|
||||
expect(fullRequest.start).toBe(10);
|
||||
expect(fullRequest.end).toBe(20);
|
||||
});
|
||||
|
||||
it("applies domain from time system if none defined", function () {
|
||||
var fullRequest = telemetry.buildRequest({});
|
||||
var mockTimeSystem = mockAPI.conductor.timeSystem();
|
||||
expect(fullRequest.domain).toBe(mockTimeSystem.metadata.key);
|
||||
|
||||
fullRequest = telemetry.buildRequest({domain: 'someOtherDomain'});
|
||||
expect(fullRequest.domain).toBe('someOtherDomain');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user