mirror of
https://github.com/nasa/openmct.git
synced 2025-02-21 09:52:04 +00:00
Merge branch 'open623' of https://github.com/DocJava/openmct into DocJava-open623
This commit is contained in:
commit
8750bdd778
@ -28,6 +28,8 @@ define([
|
||||
"./src/controllers/RefreshingController",
|
||||
"./src/actions/StartTimerAction",
|
||||
"./src/actions/RestartTimerAction",
|
||||
"./src/actions/StopTimerAction",
|
||||
"./src/actions/PauseTimerAction",
|
||||
"text!./res/templates/clock.html",
|
||||
"text!./res/templates/timer.html",
|
||||
'legacyRegistry'
|
||||
@ -39,6 +41,8 @@ define([
|
||||
RefreshingController,
|
||||
StartTimerAction,
|
||||
RestartTimerAction,
|
||||
StopTimerAction,
|
||||
PauseTimerAction,
|
||||
clockTemplate,
|
||||
timerTemplate,
|
||||
legacyRegistry
|
||||
@ -139,6 +143,17 @@ define([
|
||||
"cssclass": "icon-play",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"key": "timer.pause",
|
||||
"implementation": PauseTimerAction,
|
||||
"depends": [
|
||||
"now"
|
||||
],
|
||||
"category": "contextual",
|
||||
"name": "Pause",
|
||||
"cssclass": "icon-pause",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"key": "timer.restart",
|
||||
"implementation": RestartTimerAction,
|
||||
@ -149,6 +164,17 @@ define([
|
||||
"name": "Restart at 0",
|
||||
"cssclass": "icon-refresh",
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"key": "timer.stop",
|
||||
"implementation": StopTimerAction,
|
||||
"depends": [
|
||||
"now"
|
||||
],
|
||||
"category": "contextual",
|
||||
"name": "Stop",
|
||||
"cssclass": "icon-box",
|
||||
"priority": "preferred"
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
|
@ -22,8 +22,12 @@
|
||||
<div class="l-time-display l-digital l-timer s-timer" ng-controller="TimerController as timer">
|
||||
<div class="l-elem-wrapper l-flex-row">
|
||||
<a ng-click="timer.clickButton()"
|
||||
title="{{timer.buttonText()}}"
|
||||
class="flex-elem control s-icon-button {{timer.buttonCssClass()}}"></a>
|
||||
title="{{timer.buttonText()}}"
|
||||
class="flex-elem control s-icon-button {{timer.buttonCssClass()}}"></a>
|
||||
<a ng-click="timer.clickStopButton()"
|
||||
title="{{timer.stopButtonText()}}"
|
||||
class="{{!timer.stopButtonCssClass() || 'flex-elem control s-icon-button'}} {{timer.stopButtonCssClass()}}"></a>
|
||||
<span class="flex-elem l-value {{timer.stateClass()}}"></span>
|
||||
<span class="flex-elem l-value {{timer.signClass()}}">
|
||||
<span class="value"
|
||||
ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}}
|
||||
|
@ -30,9 +30,6 @@ define(
|
||||
* Sets the reference timestamp in a timer to the current
|
||||
* time, such that it begins counting up.
|
||||
*
|
||||
* Both "Start" and "Restart" share this implementation, but
|
||||
* control their visibility with different `appliesTo` behavior.
|
||||
*
|
||||
* @implements {Action}
|
||||
* @memberof platform/features/clock
|
||||
* @constructor
|
||||
@ -40,22 +37,38 @@ define(
|
||||
* time (typically wrapping `Date.now`)
|
||||
* @param {ActionContext} context the context for this action
|
||||
*/
|
||||
function AbstractStartTimerAction(now, context) {
|
||||
function AbstractTimerAction(now, context) {
|
||||
this.domainObject = context.domainObject;
|
||||
this.now = now;
|
||||
}
|
||||
|
||||
AbstractStartTimerAction.prototype.perform = function () {
|
||||
AbstractTimerAction.prototype.perform = function () {
|
||||
var domainObject = this.domainObject,
|
||||
now = this.now;
|
||||
|
||||
function setTimestamp(model) {
|
||||
model.timestamp = now();
|
||||
//if we are resuming
|
||||
if (model.pausedTime) {
|
||||
var timeShift = now() - model.pausedTime;
|
||||
model.timestamp = model.timestamp + timeShift;
|
||||
} else {
|
||||
model.timestamp = now();
|
||||
}
|
||||
}
|
||||
|
||||
return domainObject.useCapability('mutation', setTimestamp);
|
||||
function setTimerState(model) {
|
||||
model.timerState = 'started';
|
||||
}
|
||||
|
||||
function setPausedTime(model) {
|
||||
model.pausedTime = undefined;
|
||||
}
|
||||
|
||||
return domainObject.useCapability('mutation', setTimestamp) &&
|
||||
domainObject.useCapability('mutation', setTimerState) &&
|
||||
domainObject.useCapability('mutation', setPausedTime);
|
||||
};
|
||||
|
||||
return AbstractStartTimerAction;
|
||||
return AbstractTimerAction;
|
||||
}
|
||||
);
|
78
platform/features/clock/src/actions/PauseTimerAction.js
Normal file
78
platform/features/clock/src/actions/PauseTimerAction.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT 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 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.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['./AbstractTimerAction'],
|
||||
function (AbstractTimerAction) {
|
||||
|
||||
/**
|
||||
* Implements the "Pause" action for timers.
|
||||
*
|
||||
* Sets the reference pausedTime in a timer to the current
|
||||
* time, such that it stops counting up.
|
||||
*
|
||||
* @extends {platform/features/clock.AbstractTimerAction}
|
||||
* @implements {Action}
|
||||
* @memberof platform/features/clock
|
||||
* @constructor
|
||||
* @param {Function} now a function which returns the current
|
||||
* time (typically wrapping `Date.now`)
|
||||
* @param {ActionContext} context the context for this action
|
||||
*/
|
||||
function PauseTimerAction(now, context) {
|
||||
AbstractTimerAction.apply(this, [now, context]);
|
||||
}
|
||||
|
||||
PauseTimerAction.prototype =
|
||||
Object.create(AbstractTimerAction.prototype);
|
||||
|
||||
PauseTimerAction.appliesTo = function (context) {
|
||||
var model =
|
||||
(context.domainObject && context.domainObject.getModel()) ||
|
||||
{};
|
||||
|
||||
|
||||
// We show this variant for timers which have
|
||||
// a target time, or is in a playing state.
|
||||
return model.type === 'timer' &&
|
||||
model.timerState === 'started';
|
||||
};
|
||||
|
||||
PauseTimerAction.prototype.perform = function () {
|
||||
var domainObject = this.domainObject,
|
||||
now = this.now;
|
||||
|
||||
function setTimerState(model) {
|
||||
model.timerState = 'paused';
|
||||
}
|
||||
|
||||
function setPausedTime(model) {
|
||||
model.pausedTime = now();
|
||||
}
|
||||
|
||||
return domainObject.useCapability('mutation', setTimerState) &&
|
||||
domainObject.useCapability('mutation', setPausedTime);
|
||||
};
|
||||
|
||||
return PauseTimerAction;
|
||||
}
|
||||
);
|
@ -21,8 +21,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['./AbstractStartTimerAction'],
|
||||
function (AbstractStartTimerAction) {
|
||||
['./AbstractTimerAction'],
|
||||
function (AbstractTimerAction) {
|
||||
|
||||
/**
|
||||
* Implements the "Restart at 0" action.
|
||||
@ -39,24 +39,43 @@ define(
|
||||
* @param {ActionContext} context the context for this action
|
||||
*/
|
||||
function RestartTimerAction(now, context) {
|
||||
AbstractStartTimerAction.apply(this, [now, context]);
|
||||
AbstractTimerAction.apply(this, [now, context]);
|
||||
}
|
||||
|
||||
RestartTimerAction.prototype =
|
||||
Object.create(AbstractStartTimerAction.prototype);
|
||||
Object.create(AbstractTimerAction.prototype);
|
||||
|
||||
RestartTimerAction.appliesTo = function (context) {
|
||||
var model =
|
||||
(context.domainObject && context.domainObject.getModel()) ||
|
||||
{};
|
||||
|
||||
// We show this variant for timers which already have
|
||||
// a target time.
|
||||
// We show this variant for timers which already have a target time.
|
||||
return model.type === 'timer' &&
|
||||
model.timestamp !== undefined;
|
||||
model.timerState !== 'stopped';
|
||||
};
|
||||
|
||||
RestartTimerAction.prototype.perform = function () {
|
||||
var domainObject = this.domainObject,
|
||||
now = this.now;
|
||||
|
||||
function setTimestamp(model) {
|
||||
model.timestamp = now();
|
||||
}
|
||||
|
||||
function setTimerState(model) {
|
||||
model.timerState = 'started';
|
||||
}
|
||||
|
||||
function setPausedTime(model) {
|
||||
model.pausedTime = undefined;
|
||||
}
|
||||
|
||||
return domainObject.useCapability('mutation', setTimestamp) &&
|
||||
domainObject.useCapability('mutation', setTimerState) &&
|
||||
domainObject.useCapability('mutation', setPausedTime);
|
||||
};
|
||||
|
||||
return RestartTimerAction;
|
||||
|
||||
}
|
||||
);
|
||||
|
@ -21,8 +21,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['./AbstractStartTimerAction'],
|
||||
function (AbstractStartTimerAction) {
|
||||
['./AbstractTimerAction'],
|
||||
function (AbstractTimerAction) {
|
||||
|
||||
/**
|
||||
* Implements the "Start" action for timers.
|
||||
@ -39,11 +39,11 @@ define(
|
||||
* @param {ActionContext} context the context for this action
|
||||
*/
|
||||
function StartTimerAction(now, context) {
|
||||
AbstractStartTimerAction.apply(this, [now, context]);
|
||||
AbstractTimerAction.apply(this, [now, context]);
|
||||
}
|
||||
|
||||
StartTimerAction.prototype =
|
||||
Object.create(AbstractStartTimerAction.prototype);
|
||||
Object.create(AbstractTimerAction.prototype);
|
||||
|
||||
StartTimerAction.appliesTo = function (context) {
|
||||
var model =
|
||||
@ -53,10 +53,9 @@ define(
|
||||
// We show this variant for timers which do not yet have
|
||||
// a target time.
|
||||
return model.type === 'timer' &&
|
||||
model.timestamp === undefined;
|
||||
model.timerState !== 'started';
|
||||
};
|
||||
|
||||
return StartTimerAction;
|
||||
|
||||
}
|
||||
);
|
||||
|
82
platform/features/clock/src/actions/StopTimerAction.js
Normal file
82
platform/features/clock/src/actions/StopTimerAction.js
Normal file
@ -0,0 +1,82 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT 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 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.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['./AbstractTimerAction'],
|
||||
function (AbstractTimerAction) {
|
||||
|
||||
/**
|
||||
* Implements the "Stop" action for timers.
|
||||
*
|
||||
* Sets the reference timestamp in a timer undefined,
|
||||
* such that it is reset and makes no movements.
|
||||
*
|
||||
* @extends {platform/features/clock.AbstractTimerAction}
|
||||
* @implements {Action}
|
||||
* @memberof platform/features/clock
|
||||
* @constructor
|
||||
* @param {Function} now a function which returns the current
|
||||
* time (typically wrapping `Date.now`)
|
||||
* @param {ActionContext} context the context for this action
|
||||
*/
|
||||
function StopTimerAction(now, context) {
|
||||
AbstractTimerAction.apply(this, [now, context]);
|
||||
}
|
||||
|
||||
StopTimerAction.prototype =
|
||||
Object.create(AbstractTimerAction.prototype);
|
||||
|
||||
StopTimerAction.appliesTo = function (context) {
|
||||
var model =
|
||||
(context.domainObject && context.domainObject.getModel()) ||
|
||||
{};
|
||||
|
||||
|
||||
// We show this variant for timers which do not yet have
|
||||
// a target time.
|
||||
return model.type === 'timer' &&
|
||||
model.timerState !== 'stopped';
|
||||
};
|
||||
|
||||
StopTimerAction.prototype.perform = function () {
|
||||
var domainObject = this.domainObject;
|
||||
|
||||
function setTimestamp(model) {
|
||||
model.timestamp = undefined;
|
||||
}
|
||||
|
||||
function setTimerState(model) {
|
||||
model.timerState = 'stopped';
|
||||
}
|
||||
|
||||
function setPausedTime(model) {
|
||||
model.pausedTime = undefined;
|
||||
}
|
||||
|
||||
return domainObject.useCapability('mutation', setTimestamp) &&
|
||||
domainObject.useCapability('mutation', setTimerState) &&
|
||||
domainObject.useCapability('mutation', setPausedTime);
|
||||
};
|
||||
|
||||
return StopTimerAction;
|
||||
}
|
||||
);
|
@ -42,6 +42,7 @@ define(
|
||||
active = true,
|
||||
relativeTimestamp,
|
||||
lastTimestamp,
|
||||
relativeTimerState,
|
||||
self = this;
|
||||
|
||||
function update() {
|
||||
@ -53,10 +54,13 @@ define(
|
||||
timeDelta >= 1000 ? "+" : "";
|
||||
self.signCssClass = timeDelta < 0 ? "icon-minus" :
|
||||
timeDelta >= 1000 ? "icon-plus" : "";
|
||||
self.stateCssClass = relativeTimerState === "play" ? "icon-play" :
|
||||
relativeTimerState === "pause" ? "icon-pause" : "icon-box";
|
||||
} else {
|
||||
self.textValue = "";
|
||||
self.signValue = "";
|
||||
self.signCssClass = "";
|
||||
self.stateCssClass = "icon-box";
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,19 +72,50 @@ define(
|
||||
relativeTimestamp = timestamp;
|
||||
}
|
||||
|
||||
function updateTimerState(timerState) {
|
||||
relativeTimerState = timerState;
|
||||
}
|
||||
|
||||
function updateActions(actionCapability, actionKey) {
|
||||
self.relevantAction = actionCapability &&
|
||||
actionCapability.getActions(actionKey)[0];
|
||||
|
||||
self.stopAction = relativeTimerState !== 'stopped' ?
|
||||
actionCapability && actionCapability.getActions('timer.stop')[0] : undefined;
|
||||
|
||||
}
|
||||
|
||||
function isPaused() {
|
||||
return relativeTimerState === 'paused';
|
||||
}
|
||||
|
||||
function handleLegacyTimer(model) {
|
||||
if (model.timerState === undefined) {
|
||||
model.timerState = model.timestamp === undefined ?
|
||||
'stopped' : 'started';
|
||||
}
|
||||
}
|
||||
|
||||
function updateObject(domainObject) {
|
||||
var model = domainObject.getModel(),
|
||||
timestamp = model.timestamp,
|
||||
var model = domainObject.getModel();
|
||||
handleLegacyTimer(model);
|
||||
|
||||
var timestamp = model.timestamp,
|
||||
formatKey = model.timerFormat,
|
||||
timerState = model.timerState,
|
||||
actionCapability = domainObject.getCapability('action'),
|
||||
actionKey = (timestamp === undefined) ?
|
||||
'timer.start' : 'timer.restart';
|
||||
actionKey = (timerState !== 'started') ?
|
||||
'timer.start' : 'timer.pause';
|
||||
|
||||
updateFormat(formatKey);
|
||||
updateTimestamp(timestamp);
|
||||
updateTimerState(timerState);
|
||||
updateActions(actionCapability, actionKey);
|
||||
|
||||
self.relevantAction = actionCapability &&
|
||||
actionCapability.getActions(actionKey)[0];
|
||||
//if paused on startup show last known position
|
||||
if (isPaused() && !lastTimestamp) {
|
||||
lastTimestamp = model.pausedTime;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
@ -98,8 +133,16 @@ define(
|
||||
function tick() {
|
||||
var lastSign = self.signValue,
|
||||
lastText = self.textValue;
|
||||
lastTimestamp = now();
|
||||
update();
|
||||
|
||||
if (!isPaused()) {
|
||||
lastTimestamp = now();
|
||||
update();
|
||||
}
|
||||
|
||||
if (relativeTimerState === undefined) {
|
||||
handleModification();
|
||||
}
|
||||
|
||||
// We're running in an animation frame, not in a digest cycle.
|
||||
// We need to trigger a digest cycle if our displayable data
|
||||
// changes.
|
||||
@ -130,27 +173,27 @@ define(
|
||||
|
||||
/**
|
||||
* Get the CSS class to display the right icon
|
||||
* for the start/restart button.
|
||||
* for the start/pause button.
|
||||
* @returns {string} cssclass to display
|
||||
*/
|
||||
TimerController.prototype.buttonCssClass = function () {
|
||||
return this.relevantAction ?
|
||||
this.relevantAction.getMetadata().cssclass : "";
|
||||
this.relevantAction.getMetadata().cssclass : "";
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text to show for the start/restart button
|
||||
* Get the text to show for the start/pause button
|
||||
* (e.g. in a tooltip)
|
||||
* @returns {string} name of the action
|
||||
*/
|
||||
TimerController.prototype.buttonText = function () {
|
||||
return this.relevantAction ?
|
||||
this.relevantAction.getMetadata().name : "";
|
||||
this.relevantAction.getMetadata().name : "";
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Perform the action associated with the start/restart button.
|
||||
* Perform the action associated with the start/pause button.
|
||||
*/
|
||||
TimerController.prototype.clickButton = function () {
|
||||
if (this.relevantAction) {
|
||||
@ -159,6 +202,36 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the CSS class to display the stop button
|
||||
* @returns {string} cssclass to display
|
||||
*/
|
||||
TimerController.prototype.stopButtonCssClass = function () {
|
||||
return this.stopAction ?
|
||||
this.stopAction.getMetadata().cssclass : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text to show the stop button
|
||||
* (e.g. in a tooltip)
|
||||
* @returns {string} name of the action
|
||||
*/
|
||||
TimerController.prototype.stopButtonText = function () {
|
||||
return this.stopAction ?
|
||||
this.stopAction.getMetadata().name : '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Perform the action associated with the stop button.
|
||||
*/
|
||||
TimerController.prototype.clickStopButton = function () {
|
||||
if (this.stopAction) {
|
||||
this.stopAction.perform();
|
||||
this.updateObject(this.$scope.domainObject);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the sign (+ or -) of the current timer value, as
|
||||
* displayable text.
|
||||
@ -177,6 +250,15 @@ define(
|
||||
return this.signCssClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the symbol (play, pause or stop) of the current timer state, as
|
||||
* a CSS class.
|
||||
* @returns {string} symbol of the current timer state
|
||||
*/
|
||||
TimerController.prototype.stateClass = function () {
|
||||
return this.stateCssClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text to display for the current timer value.
|
||||
* @returns {string} current timer value
|
||||
|
@ -21,8 +21,8 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/actions/AbstractStartTimerAction"],
|
||||
function (AbstractStartTimerAction) {
|
||||
["../../src/actions/AbstractTimerAction"],
|
||||
function (AbstractTimerAction) {
|
||||
|
||||
describe("A timer's start/restart action", function () {
|
||||
var mockNow,
|
||||
@ -54,7 +54,7 @@ define(
|
||||
|
||||
testModel = {};
|
||||
|
||||
action = new AbstractStartTimerAction(mockNow, {
|
||||
action = new AbstractTimerAction(mockNow, {
|
||||
domainObject: mockDomainObject
|
||||
});
|
||||
});
|
105
platform/features/clock/test/actions/PauseTimerActionSpec.js
Normal file
105
platform/features/clock/test/actions/PauseTimerActionSpec.js
Normal file
@ -0,0 +1,105 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT 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 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.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/actions/PauseTimerAction"],
|
||||
function (PauseTimerAction) {
|
||||
|
||||
describe("A timer's Pause action", function () {
|
||||
var mockNow,
|
||||
mockDomainObject,
|
||||
testModel,
|
||||
testContext,
|
||||
action;
|
||||
|
||||
function asPromise(value) {
|
||||
return (value || {}).then ? value : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockNow = jasmine.createSpy('now');
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getCapability', 'useCapability', 'getModel']
|
||||
);
|
||||
|
||||
mockDomainObject.useCapability.andCallFake(function (c, v) {
|
||||
if (c === 'mutation') {
|
||||
testModel = v(testModel) || testModel;
|
||||
return asPromise(true);
|
||||
}
|
||||
});
|
||||
mockDomainObject.getModel.andCallFake(function () {
|
||||
return testModel;
|
||||
});
|
||||
|
||||
testModel = {};
|
||||
testContext = {domainObject: mockDomainObject};
|
||||
|
||||
action = new PauseTimerAction(mockNow, testContext);
|
||||
});
|
||||
|
||||
it("updates the model with a timerState", function () {
|
||||
testModel.timerState = 'started';
|
||||
action.perform();
|
||||
expect(testModel.timerState).toEqual('paused');
|
||||
});
|
||||
|
||||
it("updates the model with a pausedTime", function () {
|
||||
testModel.pausedTime = undefined;
|
||||
mockNow.andReturn(12000);
|
||||
action.perform();
|
||||
expect(testModel.pausedTime).toEqual(12000);
|
||||
});
|
||||
|
||||
it("applies only to timers in a playing state", function () {
|
||||
//in a stopped state
|
||||
testState('timer', 'stopped', undefined, false);
|
||||
|
||||
//in a paused state
|
||||
testState('timer', 'paused', 12000, false);
|
||||
|
||||
//in a playing state
|
||||
testState('timer', 'started', 12000, true);
|
||||
|
||||
//not a timer
|
||||
testState('clock', 'started', 12000, false);
|
||||
});
|
||||
|
||||
function testState(type, timerState, timestamp, expected) {
|
||||
testModel.type = type;
|
||||
testModel.timerState = timerState;
|
||||
testModel.timestamp = timestamp;
|
||||
|
||||
if (expected) {
|
||||
expect(PauseTimerAction.appliesTo(testContext)).toBeTruthy()
|
||||
} else {
|
||||
expect(PauseTimerAction.appliesTo(testContext)).toBeFalsy()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
@ -63,24 +63,49 @@ define(
|
||||
});
|
||||
|
||||
it("updates the model with a timestamp", function () {
|
||||
testModel.pausedTime = 12000;
|
||||
mockNow.andReturn(12000);
|
||||
action.perform();
|
||||
expect(testModel.timestamp).toEqual(12000);
|
||||
});
|
||||
|
||||
it("applies only to timers with a target time", function () {
|
||||
testModel.type = 'timer';
|
||||
testModel.timestamp = 12000;
|
||||
expect(RestartTimerAction.appliesTo(testContext)).toBeTruthy();
|
||||
|
||||
testModel.type = 'timer';
|
||||
testModel.timestamp = undefined;
|
||||
expect(RestartTimerAction.appliesTo(testContext)).toBeFalsy();
|
||||
|
||||
testModel.type = 'clock';
|
||||
testModel.timestamp = 12000;
|
||||
expect(RestartTimerAction.appliesTo(testContext)).toBeFalsy();
|
||||
it("updates the model with a pausedTime", function () {
|
||||
testModel.pausedTime = 12000;
|
||||
action.perform();
|
||||
expect(testModel.pausedTime).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("updates the model with a timerState", function () {
|
||||
testModel.timerState = 'stopped';
|
||||
action.perform();
|
||||
expect(testModel.timerState).toEqual('started');
|
||||
});
|
||||
|
||||
it("applies only to timers in a non-stopped state", function () {
|
||||
//in a stopped state
|
||||
testState('timer', 'stopped', undefined, false);
|
||||
|
||||
//in a paused state
|
||||
testState('timer', 'paused', 12000, true);
|
||||
|
||||
//in a playing state
|
||||
testState('timer', 'started', 12000, true);
|
||||
|
||||
//not a timer
|
||||
testState('clock', 'paused', 12000, false);
|
||||
});
|
||||
|
||||
function testState(type, timerState, timestamp, expected) {
|
||||
testModel.type = type;
|
||||
testModel.timerState = timerState;
|
||||
testModel.timestamp = timestamp;
|
||||
|
||||
if (expected) {
|
||||
expect(RestartTimerAction.appliesTo(testContext)).toBeTruthy()
|
||||
} else {
|
||||
expect(RestartTimerAction.appliesTo(testContext)).toBeFalsy()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -33,10 +33,10 @@ define(
|
||||
|
||||
function asPromise(value) {
|
||||
return (value || {}).then ? value : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(value));
|
||||
}
|
||||
};
|
||||
then: function (callback) {
|
||||
return asPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
@ -57,7 +57,7 @@ define(
|
||||
});
|
||||
|
||||
testModel = {};
|
||||
testContext = { domainObject: mockDomainObject };
|
||||
testContext = {domainObject: mockDomainObject};
|
||||
|
||||
action = new StartTimerAction(mockNow, testContext);
|
||||
});
|
||||
@ -68,19 +68,43 @@ define(
|
||||
expect(testModel.timestamp).toEqual(12000);
|
||||
});
|
||||
|
||||
it("applies only to timers without a target time", function () {
|
||||
testModel.type = 'timer';
|
||||
testModel.timestamp = 12000;
|
||||
expect(StartTimerAction.appliesTo(testContext)).toBeFalsy();
|
||||
|
||||
testModel.type = 'timer';
|
||||
testModel.timestamp = undefined;
|
||||
expect(StartTimerAction.appliesTo(testContext)).toBeTruthy();
|
||||
|
||||
testModel.type = 'clock';
|
||||
testModel.timestamp = 12000;
|
||||
expect(StartTimerAction.appliesTo(testContext)).toBeFalsy();
|
||||
it("updates the model with a pausedTime", function () {
|
||||
testModel.pausedTime = 12000;
|
||||
action.perform();
|
||||
expect(testModel.pausedTime).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("updates the model with a timerState", function () {
|
||||
testModel.timerState = undefined;
|
||||
action.perform();
|
||||
expect(testModel.timerState).toEqual('started');
|
||||
});
|
||||
|
||||
it("applies only to timers not in a playing state", function () {
|
||||
//in a stopped state
|
||||
testState('timer', 'stopped', undefined, true);
|
||||
|
||||
//in a paused state
|
||||
testState('timer', 'paused', 12000, true);
|
||||
|
||||
//in a playing state
|
||||
testState('timer', 'started', 12000, false);
|
||||
|
||||
//not a timer
|
||||
testState('clock', 'paused', 12000, false);
|
||||
});
|
||||
|
||||
function testState(type, timerState, timestamp, expected) {
|
||||
testModel.type = type;
|
||||
testModel.timerState = timerState;
|
||||
testModel.timestamp = timestamp;
|
||||
|
||||
if (expected) {
|
||||
expect(StartTimerAction.appliesTo(testContext)).toBeTruthy()
|
||||
} else {
|
||||
expect(StartTimerAction.appliesTo(testContext)).toBeFalsy()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
110
platform/features/clock/test/actions/StopTimerActionSpec.js
Normal file
110
platform/features/clock/test/actions/StopTimerActionSpec.js
Normal file
@ -0,0 +1,110 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT 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 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.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/actions/StopTimerAction"],
|
||||
function (StopTimerAction) {
|
||||
|
||||
describe("A timer's stop action", function () {
|
||||
var mockNow,
|
||||
mockDomainObject,
|
||||
testModel,
|
||||
testContext,
|
||||
action;
|
||||
|
||||
function asPromise(value) {
|
||||
return (value || {}).then ? value : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockNow = jasmine.createSpy('now');
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getCapability', 'useCapability', 'getModel']
|
||||
);
|
||||
|
||||
mockDomainObject.useCapability.andCallFake(function (c, v) {
|
||||
if (c === 'mutation') {
|
||||
testModel = v(testModel) || testModel;
|
||||
return asPromise(true);
|
||||
}
|
||||
});
|
||||
mockDomainObject.getModel.andCallFake(function () {
|
||||
return testModel;
|
||||
});
|
||||
|
||||
testModel = {};
|
||||
testContext = {domainObject: mockDomainObject};
|
||||
|
||||
action = new StopTimerAction(mockNow, testContext);
|
||||
});
|
||||
|
||||
it("updates the model with a timestamp", function () {
|
||||
mockNow.andReturn(12000);
|
||||
action.perform();
|
||||
expect(testModel.timestamp).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("updates the model with a pausedTime", function () {
|
||||
testModel.pausedTime = 12000;
|
||||
action.perform();
|
||||
expect(testModel.pausedTime).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("updates the model with a timerState", function () {
|
||||
testModel.timerState = 'started';
|
||||
action.perform();
|
||||
expect(testModel.timerState).toEqual('stopped');
|
||||
});
|
||||
|
||||
it("applies only to timers in a non-stopped state", function () {
|
||||
//in a stopped state
|
||||
testState('timer', 'stopped', undefined, false);
|
||||
|
||||
//in a paused state
|
||||
testState('timer', 'paused', 12000, true);
|
||||
|
||||
//in a playing state
|
||||
testState('timer', 'started', 12000, true);
|
||||
|
||||
//not a timer
|
||||
testState('clock', 'paused', 12000, false);
|
||||
});
|
||||
|
||||
function testState(type, timerState, timestamp, expected) {
|
||||
testModel.type = type;
|
||||
testModel.timerState = timerState;
|
||||
testModel.timestamp = timestamp;
|
||||
|
||||
if (expected) {
|
||||
expect(StopTimerAction.appliesTo(testContext)).toBeTruthy()
|
||||
} else {
|
||||
expect(StopTimerAction.appliesTo(testContext)).toBeFalsy()
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
@ -34,13 +34,14 @@ define(
|
||||
mockDomainObject,
|
||||
mockActionCapability,
|
||||
mockStart,
|
||||
mockRestart,
|
||||
mockPause,
|
||||
mockStop,
|
||||
testModel,
|
||||
controller;
|
||||
|
||||
function invokeWatch(expr, value) {
|
||||
mockScope.$watch.calls.forEach(function (call) {
|
||||
if (call.args[0] === expr) {
|
||||
if (call.args[0] === expr) {
|
||||
call.args[1](value);
|
||||
}
|
||||
});
|
||||
@ -67,8 +68,12 @@ define(
|
||||
'start',
|
||||
['getMetadata', 'perform']
|
||||
);
|
||||
mockRestart = jasmine.createSpyObj(
|
||||
'restart',
|
||||
mockPause = jasmine.createSpyObj(
|
||||
'paused',
|
||||
['getMetadata', 'perform']
|
||||
);
|
||||
mockStop = jasmine.createSpyObj(
|
||||
'stopped',
|
||||
['getMetadata', 'perform']
|
||||
);
|
||||
mockNow = jasmine.createSpy('now');
|
||||
@ -82,11 +87,13 @@ define(
|
||||
mockActionCapability.getActions.andCallFake(function (k) {
|
||||
return [{
|
||||
'timer.start': mockStart,
|
||||
'timer.restart': mockRestart
|
||||
'timer.pause': mockPause,
|
||||
'timer.stop': mockStop
|
||||
}[k]];
|
||||
});
|
||||
mockStart.getMetadata.andReturn({ cssclass: "icon-play", name: "Start" });
|
||||
mockRestart.getMetadata.andReturn({ cssclass: "icon-refresh", name: "Restart" });
|
||||
mockStart.getMetadata.andReturn({cssclass: "icon-play", name: "Start"});
|
||||
mockPause.getMetadata.andReturn({cssclass: "icon-pause", name: "Pause"});
|
||||
mockStop.getMetadata.andReturn({cssclass: "icon-box", name: "Stop"});
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
|
||||
testModel = {};
|
||||
@ -120,6 +127,7 @@ define(
|
||||
mockWindow.requestAnimationFrame.mostRecentCall.args[0]();
|
||||
expect(controller.sign()).toEqual("");
|
||||
expect(controller.text()).toEqual("");
|
||||
expect(controller.stopButtonText()).toEqual("");
|
||||
});
|
||||
|
||||
it("formats time to display relative to target", function () {
|
||||
@ -144,28 +152,49 @@ define(
|
||||
expect(controller.text()).toEqual("0D 00:00:00");
|
||||
});
|
||||
|
||||
it("shows cssclass & name for the applicable start/restart action", function () {
|
||||
it("shows cssclass & name for the applicable start/pause action", function () {
|
||||
invokeWatch('domainObject', mockDomainObject);
|
||||
expect(controller.buttonCssClass()).toEqual("icon-play");
|
||||
expect(controller.buttonText()).toEqual("Start");
|
||||
|
||||
testModel.timestamp = 12321;
|
||||
testModel.timerState = 'started';
|
||||
invokeWatch('model.modified', 1);
|
||||
expect(controller.buttonCssClass()).toEqual("icon-refresh");
|
||||
expect(controller.buttonText()).toEqual("Restart");
|
||||
expect(controller.buttonCssClass()).toEqual("icon-pause");
|
||||
expect(controller.buttonText()).toEqual("Pause");
|
||||
});
|
||||
|
||||
it("performs correct start/restart action on click", function () {
|
||||
it("shows cssclass & name for the stop action", function () {
|
||||
invokeWatch('domainObject', mockDomainObject);
|
||||
expect(controller.stopButtonCssClass()).toEqual("");
|
||||
expect(controller.stopButtonText()).toEqual("");
|
||||
|
||||
testModel.timestamp = 12321;
|
||||
testModel.timerState = 'started';
|
||||
invokeWatch('model.modified', 1);
|
||||
expect(controller.stopButtonCssClass()).toEqual("icon-box");
|
||||
expect(controller.stopButtonText()).toEqual("Stop");
|
||||
});
|
||||
|
||||
it("performs correct start/pause/stop action on click", function () {
|
||||
//test start
|
||||
invokeWatch('domainObject', mockDomainObject);
|
||||
expect(mockStart.perform).not.toHaveBeenCalled();
|
||||
controller.clickButton();
|
||||
expect(mockStart.perform).toHaveBeenCalled();
|
||||
|
||||
//test pause
|
||||
testModel.timestamp = 12321;
|
||||
testModel.timerState = 'started';
|
||||
invokeWatch('model.modified', 1);
|
||||
expect(mockRestart.perform).not.toHaveBeenCalled();
|
||||
expect(mockPause.perform).not.toHaveBeenCalled();
|
||||
controller.clickButton();
|
||||
expect(mockRestart.perform).toHaveBeenCalled();
|
||||
expect(mockPause.perform).toHaveBeenCalled();
|
||||
|
||||
//test stop
|
||||
expect(mockStop.perform).not.toHaveBeenCalled();
|
||||
controller.clickStopButton();
|
||||
expect(mockStop.perform).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("stops requesting animation frames when destroyed", function () {
|
||||
|
Loading…
x
Reference in New Issue
Block a user