diff --git a/platform/features/rtevents/bundle.json b/platform/features/rtevents/bundle.json
new file mode 100644
index 0000000000..04400d8223
--- /dev/null
+++ b/platform/features/rtevents/bundle.json
@@ -0,0 +1,37 @@
+{
+ "name": "Event Messages",
+ "description": "List of time-ordered event messages",
+ "extensions": {
+ "views": [
+ {
+ "key": "messages",
+ "name": "RT Messages",
+ "glyph": "5",
+ "description": "Scrolling list of messages.",
+ "templateUrl": "templates/messages.html",
+ "needs": [ "telemetry" ],
+ "delegation": true
+ }
+ ],
+ "controllers": [
+ {
+ "key": "RTEventListController",
+ "implementation": "RTEventListController.js",
+ "depends": [ "$scope", "telemetryHandler", "telemetryFormatter" ]
+ }
+ ],
+ "directives": [
+ {
+ "key": "mctDataTable",
+ "implementation": "directives/MCTDataTable.js",
+ "depends": [ "$window" ]
+ }
+ ],
+ "policies": [
+ {
+ "category": "view",
+ "implementation": "policies/MessagesViewPolicy.js"
+ }
+ ]
+ }
+}
diff --git a/platform/features/rtevents/res/templates/mct-data-table.html b/platform/features/rtevents/res/templates/mct-data-table.html
new file mode 100644
index 0000000000..5b8dd786bc
--- /dev/null
+++ b/platform/features/rtevents/res/templates/mct-data-table.html
@@ -0,0 +1,37 @@
+
+
+
+
+
+ {{header}}
+ |
+
+
+
+
+
+ {{cell}}
+ |
+
+
+
\ No newline at end of file
diff --git a/platform/features/rtevents/res/templates/messages.html b/platform/features/rtevents/res/templates/messages.html
new file mode 100644
index 0000000000..82db5d0f9c
--- /dev/null
+++ b/platform/features/rtevents/res/templates/messages.html
@@ -0,0 +1,29 @@
+
+
+
+
diff --git a/platform/features/rtevents/src/DomainColumn.js b/platform/features/rtevents/src/DomainColumn.js
new file mode 100644
index 0000000000..95a6222553
--- /dev/null
+++ b/platform/features/rtevents/src/DomainColumn.js
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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,moment*/
+
+/**
+ * Module defining DomainColumn. Created by vwoeltje on 11/18/14.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ /**
+ * A column which will report telemetry domain values
+ * (typically, timestamps.) Used by the ScrollingListController.
+ *
+ * @constructor
+ * @param domainMetadata an object with the machine- and human-
+ * readable names for this domain (in `key` and `name`
+ * fields, respectively.)
+ * @param {TelemetryFormatter} telemetryFormatter the telemetry
+ * formatting service, for making values human-readable.
+ */
+ function DomainColumn(domainMetadata, telemetryFormatter) {
+ return {
+ /**
+ * Get the title to display in this column's header.
+ * @returns {string} the title to display
+ */
+ getTitle: function () {
+ return domainMetadata.name;
+ },
+ /**
+ * Get the text to display inside a row under this
+ * column.
+ * @returns {string} the text to display
+ */
+ getValue: function (domainObject, data, index) {
+ return telemetryFormatter.formatDomainValue(
+ data.getDomainValue(index, domainMetadata.key)
+ );
+ }
+ };
+ }
+
+ return DomainColumn;
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/src/RTEventListController.js b/platform/features/rtevents/src/RTEventListController.js
new file mode 100644
index 0000000000..b84d339bd6
--- /dev/null
+++ b/platform/features/rtevents/src/RTEventListController.js
@@ -0,0 +1,139 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining RTEventListController.
+ * Created by shale on 06/25/2014. Based on RT Scrolling lists.
+ */
+define(
+ ["./DomainColumn", "./RangeColumn"],
+ function (DomainColumn, RangeColumn) {
+ "use strict";
+
+ var ROW_COUNT = 100;
+
+ /**
+ * The RTEventListController is responsible for populating
+ * the contents of the messages view.
+ * @constructor
+ */
+ function RTEventListController($scope, telemetryHandler, telemetryFormatter) {
+ var handle,
+ lastUpdated = {},
+ lastIds = [],
+ columns = [],
+ headers = [],
+ rows = [];
+
+ function getTelemetryObjects() {
+ return handle ? handle.getTelemetryObjects() : [];
+ }
+
+ function idsChanged(telemetryObjects) {
+ function mismatch(id, index) {
+ return id !== telemetryObjects[index].getId();
+ }
+
+ return lastIds.length !== telemetryObjects.length ||
+ lastIds.some(mismatch);
+ }
+
+ function setupColumns(telemetryObjects) {
+ var id = $scope.domainObject && $scope.domainObject.getId(),
+ firstId =
+ telemetryObjects[0] && telemetryObjects[0].getId();
+
+ columns = [];
+
+ if (telemetryObjects > 1 || id !== firstId) {
+ columns.push(new NameColumn());
+ }
+ columns.push(new DomainColumn(telemetryFormatter));
+ columns.push(new RangeColumn());
+
+ headers = columns.map(function (column) {
+ return column.getTitle();
+ });
+ }
+
+ function updateObjects(telemetryObjects) {
+ if (idsChanged(telemetryObjects)) {
+ setupColumns(telemetryObjects);
+ lastIds = telemetryObjects.map(function (telemetryObject) {
+ return telemetryObject.getId();
+ });
+ }
+ }
+
+ function addRow(telemetryObject) {
+ var id = telemetryObject.getId(),
+ domainValue = handle.getDomainValue(telemetryObject);
+ if (lastUpdated[id] !== domainValue &&
+ domainValue !== undefined) {
+ // Instead of unshift (scrolling), use push (messages)
+ rows.push(columns.map(function (column) {
+ return column.getValue(telemetryObject, handle);
+ }));
+ rows.splice(ROW_COUNT, Number.MAX_VALUE);
+ lastUpdated[id] = domainValue;
+ }
+ }
+
+ function updateValues() {
+ getTelemetryObjects().forEach(addRow);
+ }
+
+ function releaseSubscription() {
+ if (handle) {
+ handle.unsubscribe();
+ }
+ }
+
+ function makeSubscription(domainObject) {
+ releaseSubscription();
+ rows = [];
+ handle = telemetryHandler.handle(
+ domainObject,
+ updateValues,
+ true
+ );
+ }
+
+ $scope.$on("$destroy", releaseSubscription);
+
+ $scope.$watch("domainObject", makeSubscription);
+ $scope.$watch(getTelemetryObjects, updateObjects);
+
+ return {
+ rows: function () {
+ return rows;
+ },
+ headers: function () {
+ return headers;
+ }
+ };
+ }
+
+ return RTEventListController;
+ }
+);
diff --git a/platform/features/rtevents/src/RangeColumn.js b/platform/features/rtevents/src/RangeColumn.js
new file mode 100644
index 0000000000..2b11de43c7
--- /dev/null
+++ b/platform/features/rtevents/src/RangeColumn.js
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining DomainColumn. Created by vwoeltje on 11/18/14.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ /**
+ * A column which will report telemetry range values
+ * (typically, measurements.) Used by the ScrollingListController.
+ *
+ * @constructor
+ * @param rangeMetadata an object with the machine- and human-
+ * readable names for this range (in `key` and `name`
+ * fields, respectively.)
+ * @param {TelemetryFormatter} telemetryFormatter the telemetry
+ * formatting service, for making values human-readable.
+ */
+ function RangeColumn(rangeMetadata, telemetryFormatter) {
+ return {
+ /**
+ * Get the title to display in this column's header.
+ * @returns {string} the title to display
+ */
+ getTitle: function () {
+ return rangeMetadata.name;
+ },
+ /**
+ * Get the text to display inside a row under this
+ * column.
+ * @returns {string} the text to display
+ */
+ getValue: function (domainObject, data, index) {
+ return telemetryFormatter.formatRangeValue(
+ data.getRangeValue(index, rangeMetadata.key)
+ );
+ }
+ };
+ }
+
+ return RangeColumn;
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/src/directives/MCTDataTable.js b/platform/features/rtevents/src/directives/MCTDataTable.js
new file mode 100644
index 0000000000..c4cb9970e6
--- /dev/null
+++ b/platform/features/rtevents/src/directives/MCTDataTable.js
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining MCTDataTable. Created by shale on 06/22/2015.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ function MCTDataTable($window) {
+ return {
+ restrict: "E",
+ templateUrl: "platform/features/events/res/templates/mct-data-table.html",
+ scope: {
+ headers: "=",
+ rows: "=",
+ ascendingScroll: "="
+ },
+ link: function ($scope, $element) {
+ var currentHeight,
+ previousHeight,
+ scrollParent;
+
+ // If the scroll is set to ascending, we want to
+ // check when elements are added to the table, and move the scroll
+ // bar accordingly.
+ // (When viewing at the bottom of the page, the scroll bar will
+ // stay at the bottom despite additions to the table)
+ if ($scope.ascendingScroll) {
+ $scope.$watch("rows", function () {
+ // Wait until the page as been repainted (otherwise the
+ // height will always be zero)
+ $window.requestAnimationFrame(function () {
+ previousHeight = currentHeight;
+ // The height of the table body
+ currentHeight = $element[0].firstElementChild.firstElementChild.nextElementSibling.clientHeight;
+
+ // One of the parents is a div that has vscroll
+ scrollParent = $element[0].parentElement.parentElement.parentElement.parentElement.parentElement;
+
+ // Move the scrollbar down the amount that the height has changed
+ scrollParent.scrollTop = scrollParent.scrollTop + (currentHeight - previousHeight);
+ });
+ });
+ }
+ }
+ };
+ }
+
+ return MCTDataTable;
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/src/policies/MessagesViewPolicy.js b/platform/features/rtevents/src/policies/MessagesViewPolicy.js
new file mode 100644
index 0000000000..4426872b1e
--- /dev/null
+++ b/platform/features/rtevents/src/policies/MessagesViewPolicy.js
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * Module defining MessagesViewPolicy. Created by shale on 06/24/2015.
+ */
+define(
+ [],
+ function () {
+ "use strict";
+
+ /**
+ * Policy controlling when the Messages view should be avaliable.
+ * @constructor
+ */
+ function MessagesViewPolicy() {
+
+ function hasStringTelemetry(domainObject) {
+ var telemetry = domainObject &&
+ domainObject.getCapability('telemetry'),
+ metadata = telemetry ? telemetry.getMetadata() : {},
+ ranges = metadata.ranges || [];
+
+ return ranges.some(function (range) {
+ return range.format === 'string';
+ });
+ }
+ return {
+ /**
+ * Check whether or not a given action is allowed by this
+ * policy.
+ * @param {Action} action the action
+ * @param domainObject the domain object which will be viewed
+ * @returns {boolean} true if not disallowed
+ */
+ allow: function (view, domainObject) {
+ // This policy only applies for the Messages view
+ if (view.key === 'messages') {
+ // The Messages view is allowed only if the domain
+ // object has string telemetry
+ if (!hasStringTelemetry(domainObject)) {
+ return false;
+ }
+ }
+
+ // Like all policies, allow by default.
+ return true;
+ }
+ };
+ }
+
+ return MessagesViewPolicy;
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/test/DomainColumnSpec.js b/platform/features/rtevents/test/DomainColumnSpec.js
new file mode 100644
index 0000000000..dc1011648f
--- /dev/null
+++ b/platform/features/rtevents/test/DomainColumnSpec.js
@@ -0,0 +1,84 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * RTEventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
+ */
+define(
+ ["../src/DomainColumn"],
+ function (DomainColumn) {
+ "use strict";
+
+ var TEST_DOMAIN_VALUE = "some formatted domain value";
+
+ describe("An event list domain column", function () {
+ var mockDataSet,
+ testMetadata,
+ mockFormatter,
+ column;
+
+ beforeEach(function () {
+ mockDataSet = jasmine.createSpyObj(
+ "data",
+ [ "getDomainValue" ]
+ );
+ mockFormatter = jasmine.createSpyObj(
+ "formatter",
+ [ "formatDomainValue", "formatRangeValue" ]
+ );
+ testMetadata = {
+ key: "testKey",
+ name: "Test Name"
+ };
+ mockFormatter.formatDomainValue.andReturn(TEST_DOMAIN_VALUE);
+
+ column = new DomainColumn(testMetadata, mockFormatter);
+ });
+
+ it("reports a column header from domain metadata", function () {
+ expect(column.getTitle()).toEqual("Test Name");
+ });
+
+ it("looks up data from a data set", function () {
+ column.getValue(undefined, mockDataSet, 42);
+ expect(mockDataSet.getDomainValue)
+ .toHaveBeenCalledWith(42, "testKey");
+ });
+
+ it("formats domain values as time", function () {
+ mockDataSet.getDomainValue.andReturn(402513731000);
+
+ // Should have just given the value the formatter gave
+ expect(column.getValue(undefined, mockDataSet, 42))
+ .toEqual(TEST_DOMAIN_VALUE);
+
+ // Make sure that service interactions were as expected
+ expect(mockFormatter.formatDomainValue)
+ .toHaveBeenCalledWith(402513731000);
+ expect(mockFormatter.formatRangeValue)
+ .not.toHaveBeenCalled();
+ });
+
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/test/RTEventListControllerSpec.js b/platform/features/rtevents/test/RTEventListControllerSpec.js
new file mode 100644
index 0000000000..bd72dd23f3
--- /dev/null
+++ b/platform/features/rtevents/test/RTEventListControllerSpec.js
@@ -0,0 +1,110 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * RTEventSpec. Created by shale on 06/25/2015.
+ */
+define(
+ ["../src/RTEventListController"],
+ function (RTEventListController) {
+ "use strict";
+
+ describe("The real time event list controller", function () {
+ var mockScope,
+ mockTelemetry,
+ testMetadata,
+ controller;
+
+ beforeEach(function () {
+ mockScope = jasmine.createSpyObj(
+ "$scope",
+ [ "$on", "$watch" ]
+ );
+ mockTelemetry = jasmine.createSpyObj(
+ "telemetryController",
+ [ "getResponse", "getMetadata", "getTelemetryObjects" ]
+ );
+ testMetadata = [
+ {
+ domains: [
+ { key: "d0", name: "D0" },
+ { key: "d1", name: "D1" }
+ ],
+ ranges: [
+ { key: "r0", name: "R0" },
+ { key: "r1", name: "R1" }
+ ]
+ },
+ {
+ domains: [
+ { key: "d0", name: "D0" },
+ { key: "d2", name: "D2" }
+ ],
+ ranges: [
+ { key: "r0", name: "R0" }
+ ]
+ }
+ ];
+ mockTelemetry.getMetadata.andReturn(testMetadata);
+ mockTelemetry.getResponse.andReturn([]);
+ mockTelemetry.getTelemetryObjects.andReturn([]);
+ mockScope.telemetry = mockTelemetry;
+ controller = new EventListController(mockScope);
+ });
+
+ it("listens for telemetry data updates", function () {
+ expect(mockScope.$on).toHaveBeenCalledWith(
+ "telemetryUpdate",
+ jasmine.any(Function)
+ );
+ });
+
+ it("watches for telemetry controller changes", function () {
+ expect(mockScope.$watch).toHaveBeenCalledWith(
+ "telemetry",
+ jasmine.any(Function)
+ );
+ });
+
+ it("provides a column for each unique domain and range", function () {
+ // Should have five columns based on metadata above,
+ // (d0, d1, d2, r0, r1)
+ mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
+ expect(mockScope.headers).toEqual(["D0", "D1", "D2", "R0", "R1"]);
+ });
+
+ it("does not throw if telemetry controller is undefined", function () {
+ // Just a general robustness check
+ mockScope.telemetry = undefined;
+ expect(mockScope.$watch.mostRecentCall.args[1])
+ .not.toThrow();
+ });
+
+ it("provides default columns if domain/range metadata is unavailable", function () {
+ mockTelemetry.getMetadata.andReturn([]);
+ mockScope.$watch.mostRecentCall.args[1](mockTelemetry);
+ expect(mockScope.headers).toEqual(["Time", "Message"]);
+ });
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/test/RangeColumnSpec.js b/platform/features/rtevents/test/RangeColumnSpec.js
new file mode 100644
index 0000000000..3dc46c2ad9
--- /dev/null
+++ b/platform/features/rtevents/test/RangeColumnSpec.js
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * 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*/
+
+/**
+ * RTEventSpec. Created by vwoeltje on 11/6/14. Modified by shale on 06/23/2015.
+ */
+define(
+ ["../src/RangeColumn"],
+ function (RangeColumn) {
+ "use strict";
+
+ var TEST_RANGE_VALUE = "some formatted range value";
+
+ describe("An event list range column", function () {
+ var mockDataSet,
+ testMetadata,
+ mockFormatter,
+ column;
+
+ beforeEach(function () {
+ mockDataSet = jasmine.createSpyObj(
+ "data",
+ [ "getRangeValue" ]
+ );
+ mockFormatter = jasmine.createSpyObj(
+ "formatter",
+ [ "formatDomainValue", "formatRangeValue" ]
+ );
+ testMetadata = {
+ key: "testKey",
+ name: "Test Name"
+ };
+ mockFormatter.formatRangeValue.andReturn(TEST_RANGE_VALUE);
+
+ column = new RangeColumn(testMetadata, mockFormatter);
+ });
+
+ it("reports a column header from range metadata", function () {
+ expect(column.getTitle()).toEqual("Test Name");
+ });
+
+ it("looks up data from a data set", function () {
+ column.getValue(undefined, mockDataSet, 42);
+ expect(mockDataSet.getRangeValue)
+ .toHaveBeenCalledWith(42, "testKey");
+ });
+
+ it("formats range values as time", function () {
+ mockDataSet.getRangeValue.andReturn(123.45678);
+ expect(column.getValue(undefined, mockDataSet, 42))
+ .toEqual(TEST_RANGE_VALUE);
+
+ // Make sure that service interactions were as expected
+ expect(mockFormatter.formatRangeValue)
+ .toHaveBeenCalledWith(123.45678);
+ expect(mockFormatter.formatDomainValue)
+ .not.toHaveBeenCalled();
+ });
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/test/policies/MessagesViewPolicySpec.js b/platform/features/rtevents/test/policies/MessagesViewPolicySpec.js
new file mode 100644
index 0000000000..6e3430f64e
--- /dev/null
+++ b/platform/features/rtevents/test/policies/MessagesViewPolicySpec.js
@@ -0,0 +1,68 @@
+/*****************************************************************************
+ * 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,jasmine*/
+
+/**
+ * EventSpec. Created by shale on 06/24/2015.
+ */
+define(
+ ["../../src/policies/MessagesViewPolicy"],
+ function (MessagesViewPolicy) {
+ "use strict";
+
+ describe("The messages view policy", function () {
+ var mockDomainObject,
+ testType,
+ telemetryType,
+ policy;
+
+ beforeEach(function () {
+ mockDomainObject = jasmine.createSpyObj(
+ 'domainObject',
+ ['getModel']
+ );
+ mockDomainObject.getModel.andCallFake(function (c) {
+ return {type: testType};
+ });
+
+ policy = new MessagesViewPolicy();
+ });
+
+ it("disallows the message view for objects without string telemetry", function () {
+ telemetryType = 'notString';
+ expect(policy.allow({ key: 'messages' }, mockDomainObject))
+ .toBeFalsy();
+ });
+
+ it("allows the message view for objects with string telemetry", function () {
+ telemetryType = 'string';
+ expect(policy.allow({ key: 'messages' }, mockDomainObject))
+ .toBeTruthy();
+ });
+
+ it("returns true when the current view is not the Messages view", function () {
+ expect(policy.allow({ key: 'notMessages' }, mockDomainObject))
+ .toBeTruthy();
+ });
+ });
+ }
+);
\ No newline at end of file
diff --git a/platform/features/rtevents/test/suite.json b/platform/features/rtevents/test/suite.json
new file mode 100644
index 0000000000..260e84474b
--- /dev/null
+++ b/platform/features/rtevents/test/suite.json
@@ -0,0 +1,6 @@
+[
+ "DomainColumn",
+ "RTEventListController",
+ "policies/MessagesViewPolicy",
+ "RangeColumn"
+]
\ No newline at end of file