diff --git a/platform/features/layout/test/FixedControllerSpec.js b/platform/features/layout/test/FixedControllerSpec.js index 31d5e06659..90a397f374 100644 --- a/platform/features/layout/test/FixedControllerSpec.js +++ b/platform/features/layout/test/FixedControllerSpec.js @@ -423,6 +423,42 @@ define( // Style should have been updated expect(controller.selected().style).not.toEqual(oldStyle); }); + + it("reflects limit status", function () { + var elements; + + mockHandle.getDatum.andReturn({}); + mockHandle.getTelemetryObjects().forEach(function (mockObject) { + var id = mockObject.getId(), + mockLimitCapability = + jasmine.createSpyObj('limit-' + id, ['evaluate']); + + mockObject.getCapability.andCallFake(function (key) { + return (key === 'limit') && mockLimitCapability; + }); + + mockLimitCapability.evaluate + .andReturn({ cssClass: 'alarm-' + id }); + }); + + // Initialize + mockScope.domainObject = mockDomainObject; + mockScope.model = testModel; + findWatch("domainObject")(mockDomainObject); + findWatch("model.modified")(1); + findWatch("model.composition")(mockScope.model.composition); + + // Invoke the subscription callback + mockHandler.handle.mostRecentCall.args[1](); + + // Get elements that controller is now exposing + elements = controller.getElements(); + + // Limit-based CSS classes should be available + expect(elements[0].cssClass).toEqual("alarm-a"); + expect(elements[1].cssClass).toEqual("alarm-b"); + expect(elements[2].cssClass).toEqual("alarm-c"); + }); }); } ); diff --git a/platform/features/plot/test/PlotControllerSpec.js b/platform/features/plot/test/PlotControllerSpec.js index 8edab2fc6d..d5100ab426 100644 --- a/platform/features/plot/test/PlotControllerSpec.js +++ b/platform/features/plot/test/PlotControllerSpec.js @@ -285,6 +285,33 @@ define( fireWatch("axes[1].active.key", 'someNewKey'); expect(mockHandle.request.calls.length).toEqual(2); }); + + it("provides classes for legends based on limit state", function () { + var mockTelemetryObjects = mockHandle.getTelemetryObjects(); + + mockHandle.getDatum.andReturn({}); + mockTelemetryObjects.forEach(function (mockObject, i) { + var id = 'object-' + i, + mockLimitCapability = + jasmine.createSpyObj('limit-' + id, ['evaluate']); + + mockObject.getId.andReturn(id); + mockObject.getCapability.andCallFake(function (key) { + return (key === 'limit') && mockLimitCapability; + }); + + mockLimitCapability.evaluate + .andReturn({ cssClass: 'alarm-' + id }); + }); + + mockScope.$watch.mostRecentCall.args[1](mockDomainObject); + mockHandler.handle.mostRecentCall.args[1](); + + mockTelemetryObjects.forEach(function (mockTelemetryObject) { + expect(controller.getLegendClass(mockTelemetryObject)) + .toEqual('alarm-' + mockTelemetryObject.getId()); + }); + }); }); } ); diff --git a/platform/features/plot/test/elements/PlotLimitTrackerSpec.js b/platform/features/plot/test/elements/PlotLimitTrackerSpec.js new file mode 100644 index 0000000000..1ba428115f --- /dev/null +++ b/platform/features/plot/test/elements/PlotLimitTrackerSpec.js @@ -0,0 +1,103 @@ +/***************************************************************************** + * 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,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/ + +define( + ["../../src/elements/PlotLimitTracker"], + function (PlotLimitTracker) { + "use strict"; + + describe("A plot's limit tracker", function () { + var mockHandle, + testRange, + mockTelemetryObjects, + testData, + mockLimitCapabilities, + tracker; + + beforeEach(function () { + testRange = "some-range"; + testData = {}; + mockHandle = jasmine.createSpyObj( + 'handle', + ['getTelemetryObjects', 'getDatum'] + ); + mockTelemetryObjects = ['a', 'b', 'c'].map(function (id, i) { + var mockTelemetryObject = jasmine.createSpyObj( + 'object-' + id, + [ 'getId', 'getCapability', 'getModel' ] + ), + mockLimitCapability = jasmine.createSpyObj( + 'limit-' + id, + [ 'evaluate' ] + ); + testData[id] = { id: id, value: i }; + mockTelemetryObject.getId.andReturn(id); + mockTelemetryObject.getCapability.andCallFake(function (key) { + return key === 'limit' && mockLimitCapability; + }); + mockLimitCapability.evaluate + .andReturn({ cssClass: 'alarm-' + id}); + return mockTelemetryObject; + }); + mockHandle.getTelemetryObjects.andReturn(mockTelemetryObjects); + mockHandle.getDatum.andCallFake(function (telemetryObject) { + return testData[telemetryObject.getId()]; + }); + + tracker = new PlotLimitTracker(mockHandle, testRange); + }); + + it("initially provides no limit state", function () { + mockTelemetryObjects.forEach(function (mockTelemetryObject) { + expect(tracker.getLegendClass(mockTelemetryObject)) + .toBeUndefined(); + }); + }); + + describe("when asked to update", function () { + beforeEach(function () { + tracker.update(); + }); + + it("evaluates limits using the limit capability", function () { + mockTelemetryObjects.forEach(function (mockTelemetryObject) { + var id = mockTelemetryObject.getId(), + mockLimit = + mockTelemetryObject.getCapability('limit'); + expect(mockLimit.evaluate) + .toHaveBeenCalledWith(testData[id], testRange); + }); + }); + + it("exposes legend classes returned by the limit capability", function () { + mockTelemetryObjects.forEach(function (mockTelemetryObject) { + var id = mockTelemetryObject.getId(); + expect(tracker.getLegendClass(mockTelemetryObject)) + .toEqual('alarm-' + id); + }); + }); + }); + + }); + } +); diff --git a/platform/features/plot/test/suite.json b/platform/features/plot/test/suite.json index 92dfcb1e8a..cec8798d77 100644 --- a/platform/features/plot/test/suite.json +++ b/platform/features/plot/test/suite.json @@ -6,6 +6,7 @@ "SubPlot", "SubPlotFactory", "elements/PlotAxis", + "elements/PlotLimitTracker", "elements/PlotLine", "elements/PlotLineBuffer", "elements/PlotPalette", diff --git a/platform/telemetry/test/TelemetrySubscriptionSpec.js b/platform/telemetry/test/TelemetrySubscriptionSpec.js index 1715504b6e..e179a76bff 100644 --- a/platform/telemetry/test/TelemetrySubscriptionSpec.js +++ b/platform/telemetry/test/TelemetrySubscriptionSpec.js @@ -243,6 +243,26 @@ define( subscription.unsubscribe(); expect(mockUnlisten).toHaveBeenCalled(); }); + + it("provides telemetry as datum objects", function () { + var testDatum = { a: 1, b: 13, c: 42, d: -1977 }; + + function lookup(index, key) { + return testDatum[key]; + } + + mockSeries.getDomainValue.andCallFake(lookup); + mockSeries.getRangeValue.andCallFake(lookup); + + testMetadata.domains = [ { key: 'a' }, { key: 'b'} ]; + testMetadata.ranges = [ { key: 'c' }, { key: 'd'} ]; + + mockTelemetry.subscribe.mostRecentCall.args[0](mockSeries); + mockTimeout.mostRecentCall.args[0](); + + expect(subscription.getDatum(mockDomainObject)) + .toEqual(testDatum); + }); }); } );