[Plots] #638 added onchange handling in order to synchronize forms with domain object model.
Fixed failing test Added tests jslint errors Minor refactoring of layout bundle revert layout/bundle.json
This commit is contained in:
@@ -25,45 +25,15 @@ define([
|
||||
"./src/LayoutController",
|
||||
"./src/FixedController",
|
||||
"./src/LayoutCompositionPolicy",
|
||||
"../../commonUI/browse/src/InspectorRegion",
|
||||
"./src/PlotOptionsController",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
LayoutController,
|
||||
FixedController,
|
||||
LayoutCompositionPolicy,
|
||||
InspectorRegion,
|
||||
PlotOptionsController,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Customize and extend the default 'Inspector' region for the panel
|
||||
* type, to add display options for plots. This should be moved to a
|
||||
* dedicated type.
|
||||
* @type {InspectorRegion}
|
||||
*/
|
||||
var plotInspector = new InspectorRegion(),
|
||||
plotOptionsBrowsePart = {
|
||||
name: "plot-options",
|
||||
title: "Plot Options",
|
||||
modes: ['browse'],
|
||||
content: {
|
||||
key: "plot-options-browse"
|
||||
}
|
||||
},
|
||||
plotOptionsEditPart = {
|
||||
name: "plot-options",
|
||||
title: "Plot Options",
|
||||
modes: ['edit'],
|
||||
content: {
|
||||
key: "plot-options-browse"
|
||||
}
|
||||
};
|
||||
plotInspector.addPart(plotOptionsBrowsePart);
|
||||
plotInspector.addPart(plotOptionsEditPart);
|
||||
|
||||
legacyRegistry.register("platform/features/layout", {
|
||||
"name": "Layout components.",
|
||||
"description": "Plug in adding Layout capabilities.",
|
||||
@@ -222,10 +192,6 @@ define([
|
||||
{
|
||||
"key": "frame",
|
||||
"templateUrl": "templates/frame.html"
|
||||
},
|
||||
{
|
||||
"key": "plot-options-browse",
|
||||
"templateUrl": "templates/plot-options-browse.html"
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
@@ -247,13 +213,6 @@ define([
|
||||
"telemetryFormatter",
|
||||
"throttle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "PlotOptionsController",
|
||||
"implementation": PlotOptionsController,
|
||||
"depends": [
|
||||
"$scope"
|
||||
]
|
||||
}
|
||||
],
|
||||
"templates": [
|
||||
@@ -353,12 +312,7 @@ define([
|
||||
"property": "layoutGrid",
|
||||
"conversion": "number[]"
|
||||
}
|
||||
],
|
||||
"regions": {
|
||||
"inspector": plotInspector
|
||||
}
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -19,8 +19,31 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<style>
|
||||
.l-inspect .l-inspector-part .no-margin .form {
|
||||
margin-left: 0;
|
||||
}
|
||||
.reduced-min-width .form .form-row > .label {
|
||||
min-width: 80px;
|
||||
}
|
||||
</style>
|
||||
<div ng-controller="PlotOptionsController" class="flex-elem grows l-inspector-part">
|
||||
<em class="t-inspector-part-header" title="Display properties for this object">Display</em>
|
||||
<mct-form
|
||||
ng-model="configuration.plot.xAxis"
|
||||
structure="xAxisForm"
|
||||
name="xAxisFormState"
|
||||
class="flex-elem l-flex-row no-validate no-margin reduced-min-width">
|
||||
</mct-form>
|
||||
<mct-form
|
||||
ng-model="configuration.plot.yAxis"
|
||||
structure="yAxisForm"
|
||||
name="yAxisFormState"
|
||||
class="flex-elem l-flex-row no-validate no-margin reduced-min-width">
|
||||
</mct-form>
|
||||
<div class="section-header ng-binding ng-scope">
|
||||
Plot Series
|
||||
</div>
|
||||
<ul class="first flex-elem grows vscroll">
|
||||
<ul class="tree">
|
||||
<li ng-repeat="child in children">
|
||||
@@ -41,8 +64,8 @@
|
||||
</span>
|
||||
<mct-form
|
||||
ng-class="{hidden: !toggle.isActive()}"
|
||||
ng-model="plotOptionsModel"
|
||||
structure="plotOptionsStructure"
|
||||
ng-model="configuration.plot.series[child.getId()]"
|
||||
structure="plotSeriesForm"
|
||||
name="plotOptionsState"
|
||||
class="flex-elem l-flex-row l-controls-first no-validate">
|
||||
</mct-form>
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
* @namespace platform/features/layout
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
['./PlotOptionsForm'],
|
||||
function (PlotOptionsForm) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
@@ -50,136 +50,98 @@ define(
|
||||
* @constructor
|
||||
* @param {Scope} $scope the controller's Angular scope
|
||||
*/
|
||||
function PlotOptionsController($scope) {
|
||||
function PlotOptionsController($scope, topic) {
|
||||
|
||||
var self = this,
|
||||
domainObject = $scope.domainObject,
|
||||
xAxisForm = {
|
||||
'name':'x-axis',
|
||||
'sections': [{
|
||||
'name': 'x-axis',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Domain',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
//TODO fetch options from platform or object type configuration
|
||||
'options': [
|
||||
{'name':'scet', 'value': 'scet'},
|
||||
{'name':'sclk', 'value': 'sclk'},
|
||||
{'name':'lst', 'value': 'lst'}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]},
|
||||
yAxisForm = {
|
||||
'name':'y-axis',
|
||||
'sections': [{
|
||||
// Will need to be repeated for each y-axis, with a
|
||||
// distinct name each. Ideally the name of the axis itself.
|
||||
'name': 'y-axis',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Autoscale',
|
||||
'control': 'checkbox',
|
||||
'key': 'autoscale',
|
||||
},
|
||||
{
|
||||
'name': 'Min',
|
||||
'control': 'textfield',
|
||||
'key': 'min',
|
||||
'pattern': '[0-9]'
|
||||
},
|
||||
{
|
||||
'name': 'Max',
|
||||
'control': 'textfield',
|
||||
'key': 'min',
|
||||
'pattern': '[0-9]'
|
||||
},
|
||||
{
|
||||
'name': 'Range',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'options': [
|
||||
{'name':'eu', 'value': 'eu'},
|
||||
{'name':'dn', 'value': 'dn'},
|
||||
{'name':'status', 'value': 'status'}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
plotSeriesForm = {
|
||||
// For correctness of the rendered markup, repeated forms
|
||||
// will probably need to have unique names.
|
||||
'name': 'plotSeries',
|
||||
'sections': [{
|
||||
'name': 'Plot Series',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Markers',
|
||||
'control': 'checkbox',
|
||||
'key': 'markers'
|
||||
},
|
||||
{
|
||||
'name': 'No Line',
|
||||
'control': 'radio',
|
||||
'key': 'noLine'
|
||||
},
|
||||
{
|
||||
'name': 'Step Line',
|
||||
'control': 'radio',
|
||||
'key': 'stepLine'
|
||||
},
|
||||
{
|
||||
'name': 'Linear Line',
|
||||
'control': 'radio',
|
||||
'key': 'linearLine'
|
||||
}
|
||||
]
|
||||
}]
|
||||
},
|
||||
plotOptionsModel = {};
|
||||
composition,
|
||||
mutationListener,
|
||||
formListener,
|
||||
configuration = domainObject.getModel().configuration || {};
|
||||
|
||||
/*domainObject.getModel().configuration.plot.xAxis= {
|
||||
'key': 'scet'
|
||||
};
|
||||
this.plotOptionsForm = new PlotOptionsForm(topic);
|
||||
|
||||
domainObject.getModel().configuration.plot.yAxis = [{
|
||||
'autoscale': true,
|
||||
'min': 0,
|
||||
'max': 15,
|
||||
'key': 'eu'
|
||||
}];
|
||||
/*
|
||||
* Determine whether the changes to the model that triggered a
|
||||
* mutation event were purely compositional.
|
||||
*/
|
||||
function hasCompositionChanged(oldComposition, newComposition){
|
||||
// Framed slightly strangely, but the boolean logic is
|
||||
// easier to follow for the unchanged case.
|
||||
var isUnchanged = oldComposition === newComposition ||
|
||||
(
|
||||
oldComposition.length === newComposition.length &&
|
||||
oldComposition.every( function (currentValue, index) {
|
||||
return newComposition[index] && currentValue === newComposition[index];
|
||||
})
|
||||
);
|
||||
return !isUnchanged;
|
||||
}
|
||||
|
||||
domainObject.getModel().configuration.plot.series = [
|
||||
{
|
||||
'id': '',
|
||||
'lineStyle': '',
|
||||
'color': '#aaddaa',
|
||||
'interpolation': 'none'
|
||||
},
|
||||
//etc
|
||||
];*/
|
||||
|
||||
$scope.plotOptionsStructure = plotSeriesForm;
|
||||
$scope.plotOptionsModel = plotOptionsModel;
|
||||
/*
|
||||
Default the plot options model
|
||||
*/
|
||||
function defaultConfiguration() {
|
||||
configuration.plot = configuration.plot || {};
|
||||
configuration.plot.xAxis = configuration.plot.xAxis || {};
|
||||
configuration.plot.yAxis = configuration.plot.yAxis || {}; // y-axes will be associative array keyed on axis key
|
||||
configuration.plot.series = configuration.plot.series || {}; // series will be associative array keyed on sub-object id
|
||||
$scope.configuration = configuration;
|
||||
}
|
||||
|
||||
/*
|
||||
When a child is added to, or removed from a plot, update the
|
||||
plot options model
|
||||
*/
|
||||
function updateChildren() {
|
||||
domainObject.useCapability('composition').then(function(children){
|
||||
$scope.children = children;
|
||||
composition = domainObject.getModel().composition;
|
||||
children.forEach(function(child){
|
||||
configuration.plot.series[child.getId()] = configuration.plot.series[child.getId()] || {};
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
On changes to the form, update the configuration on the domain
|
||||
object
|
||||
*/
|
||||
function updateConfiguration() {
|
||||
domainObject.useCapability('mutation', function(model){
|
||||
model.configuration = model.configuration || {};
|
||||
model.configuration.plot = configuration.plot;
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
Set form structures on scope
|
||||
*/
|
||||
$scope.plotSeriesForm = this.plotOptionsForm.plotSeriesForm;
|
||||
$scope.xAxisForm = this.plotOptionsForm.xAxisForm;
|
||||
$scope.yAxisForm = this.plotOptionsForm.yAxisForm;
|
||||
|
||||
/*
|
||||
Listen for changes to the domain object and update the object's
|
||||
children.
|
||||
*/
|
||||
domainObject.getCapability('mutation').listen(function(model) {
|
||||
updateChildren();
|
||||
mutationListener = domainObject.getCapability('mutation').listen(function(model) {
|
||||
if (hasCompositionChanged(composition, model.composition)) {
|
||||
updateChildren();
|
||||
}
|
||||
});
|
||||
|
||||
formListener = this.plotOptionsForm.listen(updateConfiguration);
|
||||
|
||||
defaultConfiguration();
|
||||
updateChildren();
|
||||
|
||||
$scope.$on("$destroy", function() {
|
||||
//Clean up any listeners on destruction of controller
|
||||
mutationListener();
|
||||
formListener();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return PlotOptionsController;
|
||||
|
||||
166
platform/features/layout/src/PlotOptionsForm.js
Normal file
166
platform/features/layout/src/PlotOptionsForm.js
Normal 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*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* A class for encapsulating structure and behaviour of the plot
|
||||
* options form
|
||||
* @memberOf platform/features/layout
|
||||
* @param topic
|
||||
* @constructor
|
||||
*/
|
||||
function PlotOptionsForm(topic) {
|
||||
var self = this;
|
||||
this.onchangeTopic = topic();
|
||||
|
||||
function onchange(value){
|
||||
self.onchangeTopic.notify(value);
|
||||
}
|
||||
|
||||
/*
|
||||
Defined below are the form structures for the plot options.
|
||||
*/
|
||||
this.xAxisForm = {
|
||||
'name':'x-axis',
|
||||
'sections': [{
|
||||
'name': 'x-axis',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Domain',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'onchange': onchange,
|
||||
'options': [
|
||||
{'name':'scet', 'value': 'scet'},
|
||||
{'name':'sclk', 'value': 'sclk'},
|
||||
{'name':'lst', 'value': 'lst'}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]};
|
||||
|
||||
this.yAxisForm = {
|
||||
'name':'y-axis',
|
||||
'sections': [{
|
||||
// Will need to be repeated for each y-axis, with a
|
||||
// distinct name for each. Ideally the name of the axis
|
||||
// itself.
|
||||
'name': 'y-axis',
|
||||
'rows': [
|
||||
{
|
||||
'name': 'Autoscale',
|
||||
'control': 'checkbox',
|
||||
'key': 'autoscale',
|
||||
'onchange': onchange
|
||||
},
|
||||
{
|
||||
'name': 'Min',
|
||||
'control': 'textfield',
|
||||
'key': 'min',
|
||||
'pattern': '[0-9]',
|
||||
'onchange': onchange
|
||||
},
|
||||
{
|
||||
'name': 'Max',
|
||||
'control': 'textfield',
|
||||
'key': 'max',
|
||||
'pattern': '[0-9]',
|
||||
'onchange': onchange
|
||||
},
|
||||
{
|
||||
'name': 'Range',
|
||||
'control': 'select',
|
||||
'key': 'key',
|
||||
'onchange': onchange,
|
||||
'options': [
|
||||
{'name':'eu', 'value': 'eu'},
|
||||
{'name':'dn', 'value': 'dn'},
|
||||
{'name':'status', 'value': 'status'}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
this.plotSeriesForm = {
|
||||
'name':'Series Options',
|
||||
'sections': [
|
||||
{
|
||||
rows: [
|
||||
{
|
||||
'name': 'Color',
|
||||
'control': 'color',
|
||||
'key': 'color',
|
||||
'onchange': onchange
|
||||
}]
|
||||
},
|
||||
{
|
||||
'rows':[
|
||||
{
|
||||
'name': 'Markers',
|
||||
'control': 'checkbox',
|
||||
'key': 'markers',
|
||||
'onchange': onchange
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'rows':[
|
||||
{
|
||||
'name': 'No Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'noLine',
|
||||
'onchange': onchange
|
||||
},
|
||||
{
|
||||
'name': 'Step Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'stepLine',
|
||||
'onchange': onchange
|
||||
},
|
||||
{
|
||||
'name': 'Linear Line',
|
||||
'control': 'radio',
|
||||
'key': 'lineType',
|
||||
'value': 'linearLine',
|
||||
'onchange': onchange
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
PlotOptionsForm.prototype.listen = function (callback){
|
||||
return this.onchangeTopic.listen(callback);
|
||||
};
|
||||
|
||||
return PlotOptionsForm;
|
||||
}
|
||||
);
|
||||
|
||||
161
platform/features/layout/test/PlotOptionsControllerSpec.js
Normal file
161
platform/features/layout/test/PlotOptionsControllerSpec.js
Normal file
@@ -0,0 +1,161 @@
|
||||
/*****************************************************************************
|
||||
* 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,xit*/
|
||||
|
||||
define(
|
||||
['../src/PlotOptionsController'],
|
||||
function (PlotOptionsController) {
|
||||
"use strict";
|
||||
|
||||
describe("The Plot Options controller", function () {
|
||||
var plotOptionsController,
|
||||
mockTopicFunction,
|
||||
mockTopicObject,
|
||||
mockDomainObject,
|
||||
mockMutationCapability,
|
||||
mockUseCapabilities,
|
||||
mockCompositionCapability,
|
||||
mockComposition,
|
||||
mockUnlisten,
|
||||
mockFormUnlisten,
|
||||
mockChildOne,
|
||||
mockChildTwo,
|
||||
model,
|
||||
mockScope;
|
||||
|
||||
beforeEach(function () {
|
||||
model = {
|
||||
composition: ['childOne']
|
||||
};
|
||||
|
||||
mockChildOne = jasmine.createSpyObj('domainObject', [
|
||||
'getId'
|
||||
]);
|
||||
mockChildOne.getId.andReturn('childOne');
|
||||
|
||||
mockChildTwo = jasmine.createSpyObj('childTwo', [
|
||||
'getId'
|
||||
]);
|
||||
mockChildOne.getId.andReturn('childTwo');
|
||||
|
||||
mockCompositionCapability = jasmine.createSpyObj('compositionCapability', [
|
||||
'then'
|
||||
]);
|
||||
mockComposition = [
|
||||
mockChildOne
|
||||
];
|
||||
mockCompositionCapability.then.andCallFake(function (callback){
|
||||
callback(mockComposition);
|
||||
});
|
||||
|
||||
mockUseCapabilities = jasmine.createSpyObj('useCapabilities', [
|
||||
'composition',
|
||||
'mutation'
|
||||
]);
|
||||
mockUseCapabilities.composition.andReturn(mockCompositionCapability);
|
||||
|
||||
mockMutationCapability = jasmine.createSpyObj('mutationCapability', [
|
||||
'listen'
|
||||
]);
|
||||
mockUnlisten = jasmine.createSpy('unlisten');
|
||||
mockMutationCapability.listen.andReturn(mockUnlisten);
|
||||
|
||||
|
||||
mockTopicObject = jasmine.createSpyObj('Topic', [
|
||||
'listen',
|
||||
'notify'
|
||||
]);
|
||||
mockFormUnlisten = jasmine.createSpy('formUnlisten');
|
||||
mockTopicObject.listen.andReturn(mockFormUnlisten);
|
||||
|
||||
mockTopicFunction = function() {
|
||||
return mockTopicObject;
|
||||
};
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj('domainObject', [
|
||||
'getModel',
|
||||
'useCapability',
|
||||
'getCapability'
|
||||
]);
|
||||
mockDomainObject.useCapability.andCallFake(function(capability){
|
||||
return mockUseCapabilities[capability]();
|
||||
});
|
||||
mockDomainObject.getCapability.andReturn(mockMutationCapability);
|
||||
mockDomainObject.getModel.andReturn(model);
|
||||
|
||||
mockScope = jasmine.createSpyObj('scope', [
|
||||
'$on'
|
||||
]);
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
|
||||
plotOptionsController = new PlotOptionsController(mockScope, mockTopicFunction);
|
||||
});
|
||||
|
||||
it("sets form definitions on scope", function () {
|
||||
expect(mockScope.xAxisForm).toBeDefined();
|
||||
expect(mockScope.yAxisForm).toBeDefined();
|
||||
expect(mockScope.plotSeriesForm).toBeDefined();
|
||||
});
|
||||
|
||||
it("sets object children on scope", function () {
|
||||
expect(mockScope.children).toBe(mockComposition);
|
||||
});
|
||||
|
||||
it("on changes in object composition, updates the form", function () {
|
||||
expect(mockMutationCapability.listen).toHaveBeenCalled();
|
||||
expect(mockScope.children).toBe(mockComposition);
|
||||
expect(mockScope.children.length).toBe(1);
|
||||
mockComposition.push(mockChildTwo);
|
||||
model.composition.push('childTwo');
|
||||
mockMutationCapability.listen.mostRecentCall.args[0](model);
|
||||
expect(mockScope.children).toBe(mockComposition);
|
||||
expect(mockScope.children.length).toBe(2);
|
||||
});
|
||||
|
||||
it("on changes in form values, updates the object model", function () {
|
||||
var scopeConfiguration = mockScope.configuration,
|
||||
model = mockDomainObject.getModel();
|
||||
|
||||
scopeConfiguration.plot.xAxis.key = 'lst';
|
||||
scopeConfiguration.plot.yAxis.autoScale = true;
|
||||
scopeConfiguration.plot.yAxis.key = 'eu';
|
||||
|
||||
expect(mockTopicObject.listen).toHaveBeenCalled();
|
||||
mockTopicObject.listen.mostRecentCall.args[0]();
|
||||
expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function));
|
||||
|
||||
mockDomainObject.useCapability.mostRecentCall.args[1](model);
|
||||
expect(model.configuration.plot.xAxis.key).toBe('lst');
|
||||
expect(model.configuration.plot.yAxis.autoScale).toBe(true);
|
||||
expect(model.configuration.plot.yAxis.key).toBe('eu');
|
||||
|
||||
});
|
||||
|
||||
it("cleans up listeners on destruction of the controller", function () {
|
||||
mockScope.$on.mostRecentCall.args[1]();
|
||||
expect(mockUnlisten).toHaveBeenCalled();
|
||||
expect(mockFormUnlisten).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
73
platform/features/layout/test/PlotOptionsFormSpec.js
Normal file
73
platform/features/layout/test/PlotOptionsFormSpec.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
* 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,xit*/
|
||||
|
||||
define(
|
||||
['../src/PlotOptionsForm'],
|
||||
function (PlotOptionsForm) {
|
||||
"use strict";
|
||||
|
||||
describe("The Plot Options form", function () {
|
||||
var plotOptionsForm,
|
||||
mockTopicFunction,
|
||||
mockTopicObject,
|
||||
listener;
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
mockTopicObject = jasmine.createSpyObj('Topic', [
|
||||
'listen',
|
||||
'notify'
|
||||
]);
|
||||
mockTopicFunction = function() {
|
||||
return mockTopicObject;
|
||||
};
|
||||
|
||||
plotOptionsForm = new PlotOptionsForm(mockTopicFunction);
|
||||
});
|
||||
|
||||
it("defines form specs for x-axis, y-axis, and series data", function () {
|
||||
expect(plotOptionsForm.xAxisForm).toBeDefined();
|
||||
expect(plotOptionsForm.xAxisForm.sections).toBeDefined();
|
||||
expect(plotOptionsForm.xAxisForm.sections[0].rows).toBeDefined();
|
||||
expect(plotOptionsForm.xAxisForm.sections[0].rows.length).toBeGreaterThan(0);
|
||||
|
||||
expect(plotOptionsForm.yAxisForm).toBeDefined();
|
||||
expect(plotOptionsForm.plotSeriesForm).toBeDefined();
|
||||
});
|
||||
|
||||
it("uses a topic to register listeners and inform them when a" +
|
||||
" form value changes", function () {
|
||||
var changedValue = 'changedValue';
|
||||
|
||||
expect(plotOptionsForm.xAxisForm.sections[0].rows[0].onchange).toBeDefined();
|
||||
|
||||
plotOptionsForm.listen(listener);
|
||||
expect(mockTopicObject.listen).toHaveBeenCalledWith(listener);
|
||||
|
||||
plotOptionsForm.xAxisForm.sections[0].rows[0].onchange(changedValue);
|
||||
expect(mockTopicObject.notify).toHaveBeenCalledWith(changedValue);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user