Compare commits

..

104 Commits

Author SHA1 Message Date
a1d1301542 added unsubscribe, subscribeTo methods 2020-05-26 10:35:41 -07:00
aef8589872 Merge branch 'master' of https://github.com/nasa/openmct into joel/plot-test 2020-05-22 13:35:58 -07:00
38f3e60884 added dynamic layout for fixed, local clock 2020-05-22 13:35:47 -07:00
331c086a60 implemented Plotly.relayout to set x-axis correctly for local clock 2020-05-21 16:45:21 -07:00
0890ebfd0f added back if in updateData 2020-05-21 12:57:14 -07:00
1547ea5cf7 small changes 2020-05-21 12:29:04 -07:00
b1551478e4 refactor of refreshData 2020-05-21 12:03:53 -07:00
213c469758 debugging local clock issues 2020-05-21 11:44:32 -07:00
03ac43d306 added some comments 2020-05-20 18:17:29 -07:00
f3de6f2548 Merge branch 'joel/plot-test' of https://github.com/nasa/openmct into joel/plot-test 2020-05-20 15:48:44 -07:00
62dfb7d8f9 added requestHistory 2020-05-20 15:48:01 -07:00
0a33cbeea2 resolve merge conflict 2020-05-20 09:32:59 -07:00
4908d5afb0 Merge branch 'lad-testing' of https://github.com/nasa/openmct into lad-testing
merging in master I believe.
2020-05-19 12:42:55 -07:00
aa4bf5eaf6 updates from PR Review, making new lad set tests pending for the time being #3044 2020-05-19 12:39:31 -07:00
4e4031e700 added listeners and bounds methods 2020-05-18 11:37:24 -07:00
46a20bb76d Merge branch 'master' into lad-testing 2020-05-18 11:03:49 -07:00
1d482f318e working on adding render tests for lad table sets 2020-05-15 15:34:03 -07:00
6826b579a6 WIP... 2020-05-15 15:32:53 -07:00
3d4c721232 removing fdescribe 2020-05-14 13:30:13 -07:00
190d34c939 added composition tests for lad table set as well 2020-05-14 13:22:12 -07:00
47bc0e9793 pushing final version of tests for PR 2020-05-14 10:38:38 -07:00
35115aaa50 WIP: adding bounds functions 2020-05-13 16:32:03 -07:00
b252051c83 add, remove multiple traces, remove hover effects 2020-05-13 11:20:35 -07:00
4ca1181eb6 Merge branch 'lad-bounds-listener' into lad-testing
mergin in other lad changes.
2020-05-13 09:32:31 -07:00
f973f42729 random error fixed for testing, was a system setup issue 2020-05-12 15:05:29 -07:00
4788561631 WIP 2020-05-12 15:04:05 -07:00
e8699d54d5 issue with javascript heap error for tests 2020-05-12 14:19:06 -07:00
14bc49451b removed "existingTimestamp" variable, it is now stored in instance "timestamp" variable 2020-05-12 13:12:53 -07:00
dd2e8c0460 removing console logs for the moment 2020-05-12 11:58:01 -07:00
031753a9a8 still some pending, but all these are successful 2020-05-12 10:23:41 -07:00
8edae5f02c Merge branch 'master' into lad-testing
Merging master
.
2020-05-12 10:09:15 -07:00
7ed3de01b9 commit before merge master 2020-05-12 10:08:01 -07:00
4a1931f594 Merge branch 'lad-bounds-listener' into lad-testing
Merging lad bounds listener updates in for lad testing..
2020-05-11 11:20:31 -07:00
f174dcc2f6 Merge branch 'ladtable-composition-policy' into lad-testing
Merging in new ES6 module style for lad plugin..
2020-05-11 11:18:37 -07:00
0c741c67f8 import RemoveAction 2020-05-11 09:59:41 -07:00
85da5e43b3 moved formatedTimestamp to a computed value to utilize caching 2020-05-08 16:24:58 -07:00
d26e45f636 add code to set Y-axis and plot multiple telemetry types 2020-05-08 13:50:56 -07:00
0bd6814097 fixed case sensitive file name error 2020-05-08 12:13:28 -07:00
4e7410b4bf trying to fix circle ci missing LADTable.vue error 2020-05-08 12:09:04 -07:00
436550adba converted LADTable to es6 module 2020-05-08 11:52:37 -07:00
f6b1be0486 Merge branch 'ladtable-composition-policy' of https://github.com/nasa/openmct into ladtable-composition-policy
forgot to pull first
.
2020-05-07 18:35:37 -07:00
eca12201c7 switching over toe es6 module 2020-05-07 18:35:25 -07:00
68ff69664b added a phew more tests 2020-05-07 16:23:37 -07:00
51fbb9cee6 Merge branch 'master' into joel/plot-test 2020-05-07 14:55:07 -07:00
437156e04c changed mode and type, dropped old data as data extends 2020-05-07 14:45:34 -07:00
d244ee622a rendering a plotly plot from SWG 2020-05-07 13:00:54 -07:00
043d6aa9c3 extend traces on subscribe 2020-05-07 12:23:32 -07:00
ecfab8f7f3 add subscribe 2020-05-07 12:00:39 -07:00
05c38c37aa working historical 2020-05-07 11:37:01 -07:00
ce78925119 wip: added telemetry provider 2020-05-07 10:45:15 -07:00
b30018c315 added mock objects and mock telemetry to testTools 2020-05-06 13:48:17 -07:00
26aca0f433 working on viewProvider 2020-05-06 11:31:17 -07:00
eb5eb7d540 Un-focused test 2020-05-06 10:55:06 -07:00
609a47c62c Fixed failing test 2020-05-06 10:36:15 -07:00
41259bbd40 added hardcoded test plot 2020-05-05 16:00:48 -07:00
580640ff47 basic plotly plugin structure 2020-05-05 12:50:55 -07:00
688a03c8ac added composition, working on table views 2020-05-04 11:09:19 -07:00
4f12f41685 added composition policy testing 2020-05-01 15:20:08 -07:00
a4aec5d492 Merge branch 'master' of https://github.com/nasa/openmct 2020-05-01 10:46:57 -07:00
00b3f3ac0b Merge branch 'master' of https://github.com/nasa/openmct 2020-05-01 09:25:44 -07:00
189882afc8 first "it" in, working on the next 2020-04-30 10:36:44 -07:00
c185f77a15 Merge branch 'master' of https://github.com/nasa/openmct 2020-04-29 16:52:05 -07:00
2b3541a323 Merge branch 'master' into lad-bounds-listener 2020-04-29 12:43:20 -07:00
7c9a140481 plugin spec for lad tables 2020-04-29 11:27:56 -07:00
5e9b313ee9 Merge branch 'ladtable-composition-policy' into lad-testing
merging lad branches for unit testing
.
2020-04-29 10:46:06 -07:00
c64db6c07d Revert "Merge branch 'lad-conductor-response' into lad-testing"
This reverts commit 9e2751acf7, reversing
changes made to 51fb72dc04.

not what I wanted apparently#
2020-04-29 10:45:21 -07:00
9e2751acf7 Merge branch 'lad-conductor-response' into lad-testing
Merging all lad branches for lad unit testing
.
2020-04-29 10:20:34 -07:00
51fb72dc04 updates from PR review 2020-04-28 17:02:04 -07:00
d51052ab46 Merge branch 'master' into ladtable-composition-policy 2020-04-28 16:44:21 -07:00
0dff431f4a Merge branch 'master' of https://github.com/nasa/openmct 2020-04-27 12:02:12 -07:00
f62010fb99 added parsing for timestamps, removed currentData variable as it was not needed, moved tick check to bounds listener 2020-04-24 12:48:34 -07:00
61d238a097 Merge branch 'master' of https://github.com/nasa/openmct 2020-04-23 16:30:01 -07:00
ba4ef43673 linting and removing console logs 2020-04-23 15:50:49 -07:00
f6c16b7483 added a check for lad table sets, child can only be lad table 2020-04-23 15:17:07 -07:00
58e63e649f added LAD Table composition policy 2020-04-23 13:33:32 -07:00
7a04aea90e removing console log 2020-04-17 16:45:24 -07:00
0bb475327c added matadatum with key === name to be ignored as well when selecting value to show 2020-04-17 16:44:18 -07:00
c474b998f0 added a backup if the object does not have a range hint (ex. images) 2020-04-17 16:22:03 -07:00
f9deb80350 Merge branch 'master' of https://github.com/nasa/openmct 2020-04-16 15:01:42 -07:00
a02d421093 added bounds listener, moved history request to function, checking for race conditions 2020-04-16 12:19:20 -07:00
9026099fd2 added bounds listener, moved history request to function, checking for race conditions 2020-04-16 11:51:48 -07:00
295ccea195 cleaned up subscription and bounds listener, added timesystem listener 2020-04-14 12:33:34 -07:00
021d730814 resolve merge conflicts 2020-04-13 09:05:43 -07:00
ae62b15abf Merge branch 'fix-default-output' of github.com:nasa/openmct into fix-default-output 2020-04-10 15:44:42 -07:00
ba41c1a30e fix unit tests 2020-04-10 15:43:48 -07:00
b9a85d9c4d Merge branch 'master' into fix-default-output 2020-04-10 15:34:10 -07:00
80eab8bad1 fix telemetrycriterion and unit testing 2020-04-10 15:26:18 -07:00
b2d8d640ae Merge branch 'master' into fix-default-output 2020-04-10 15:23:10 -07:00
56e6fa66c2 Merge branch 'master' into fix-default-output 2020-04-10 15:13:36 -07:00
9fa4707c82 Merge branch 'master' into fix-default-output 2020-04-10 13:04:14 -07:00
7e2cfa36de AllTelemetryCriterion extends TelemetryCriterion 2020-04-10 12:17:55 -07:00
aaa60a1545 scope function names 2020-04-10 11:28:13 -07:00
717231fed2 use current timesystem to compare latest 2020-04-10 11:20:51 -07:00
7fb2bc9729 tie in requests and eliminate unused code 2020-04-10 10:42:31 -07:00
addeb635e9 refactor all/any telemetry criterion to use new evaluator 2020-04-10 09:48:31 -07:00
608d63a7b0 telemetry criterion stores its own result 2020-04-10 09:00:39 -07:00
10679e5f4f remove commented code 2020-04-10 00:12:55 -07:00
38b8f03b1a linting 2020-04-09 21:03:56 -07:00
779a42c28c remove unused listeners, events, and helpers 2020-04-09 18:14:19 -07:00
80c2504768 get results directly instead of using events 2020-04-09 17:54:47 -07:00
80359e3f16 remove generating timestamp for telemetry data 2020-04-09 16:20:16 -07:00
66aa4f099f Remove unused code 2020-04-09 15:22:35 -07:00
aa6c6cb88b Removes timestamp based evalutation from conditionManager 2020-04-09 15:21:25 -07:00
4e5cc840d7 Ensures that results for a specific datapoint are evaluated atomically. 2020-04-09 12:10:29 -07:00
903 changed files with 7192 additions and 16483 deletions

View File

@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: circleci/node:13-browsers
- image: circleci/node:8-browsers
environment:
CHROME_BIN: "/usr/bin/google-chrome"
steps:

View File

@ -1,4 +1,3 @@
const LEGACY_FILES = ["platform/**", "example/**"];
module.exports = {
"env": {
"browser": true,
@ -11,8 +10,7 @@ module.exports = {
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended",
"plugin:you-dont-need-lodash-underscore/compatible"
"plugin:vue/recommended"
],
"parser": "vue-eslint-parser",
"parserOptions": {
@ -24,9 +22,6 @@ module.exports = {
}
},
"rules": {
"you-dont-need-lodash-underscore/omit": "off",
"you-dont-need-lodash-underscore/throttle": "off",
"you-dont-need-lodash-underscore/flatten": "off",
"no-bitwise": "error",
"curly": "error",
"eqeqeq": "error",
@ -71,141 +66,6 @@ module.exports = {
],
"dot-notation": "error",
"indent": ["error", 4],
// https://eslint.org/docs/rules/no-case-declarations
"no-case-declarations": "error",
// https://eslint.org/docs/rules/max-classes-per-file
"max-classes-per-file": ["error", 1],
// https://eslint.org/docs/rules/no-eq-null
"no-eq-null": "error",
// https://eslint.org/docs/rules/no-eval
"no-eval": "error",
// https://eslint.org/docs/rules/no-floating-decimal
"no-floating-decimal": "error",
// https://eslint.org/docs/rules/no-implicit-globals
"no-implicit-globals": "error",
// https://eslint.org/docs/rules/no-implied-eval
"no-implied-eval": "error",
// https://eslint.org/docs/rules/no-lone-blocks
"no-lone-blocks": "error",
// https://eslint.org/docs/rules/no-loop-func
"no-loop-func": "error",
// https://eslint.org/docs/rules/no-new-func
"no-new-func": "error",
// https://eslint.org/docs/rules/no-new-wrappers
"no-new-wrappers": "error",
// https://eslint.org/docs/rules/no-octal-escape
"no-octal-escape": "error",
// https://eslint.org/docs/rules/no-proto
"no-proto": "error",
// https://eslint.org/docs/rules/no-return-await
"no-return-await": "error",
// https://eslint.org/docs/rules/no-script-url
"no-script-url": "error",
// https://eslint.org/docs/rules/no-self-compare
"no-self-compare": "error",
// https://eslint.org/docs/rules/no-sequences
"no-sequences": "error",
// https://eslint.org/docs/rules/no-unmodified-loop-condition
"no-unmodified-loop-condition": "error",
// https://eslint.org/docs/rules/no-useless-call
"no-useless-call": "error",
// https://eslint.org/docs/rules/wrap-iife
"wrap-iife": "error",
// https://eslint.org/docs/rules/no-nested-ternary
"no-nested-ternary": "error",
// https://eslint.org/docs/rules/switch-colon-spacing
"switch-colon-spacing": "error",
// https://eslint.org/docs/rules/no-useless-computed-key
"no-useless-computed-key": "error",
// https://eslint.org/docs/rules/rest-spread-spacing
"rest-spread-spacing": ["error"],
// https://eslint.org/docs/rules/no-var
"no-var": "error",
// https://eslint.org/docs/rules/one-var
"one-var": ["error", "never"],
// https://eslint.org/docs/rules/default-case-last
"default-case-last": "error",
// https://eslint.org/docs/rules/default-param-last
"default-param-last": "error",
// https://eslint.org/docs/rules/grouped-accessor-pairs
"grouped-accessor-pairs": "error",
// https://eslint.org/docs/rules/no-constructor-return
"no-constructor-return": "error",
// https://eslint.org/docs/rules/array-callback-return
"array-callback-return": "error",
// https://eslint.org/docs/rules/no-invalid-this
"no-invalid-this": "error", // Believe this one actually surfaces some bugs
// https://eslint.org/docs/rules/func-style
"func-style": ["error", "declaration"],
// https://eslint.org/docs/rules/no-unused-expressions
"no-unused-expressions": "error",
// https://eslint.org/docs/rules/no-useless-concat
"no-useless-concat": "error",
// https://eslint.org/docs/rules/radix
"radix": "error",
// https://eslint.org/docs/rules/require-await
"require-await": "error",
// https://eslint.org/docs/rules/no-alert
"no-alert": "error",
// https://eslint.org/docs/rules/no-useless-constructor
"no-useless-constructor": "error",
// https://eslint.org/docs/rules/no-duplicate-imports
"no-duplicate-imports": "error",
// https://eslint.org/docs/rules/no-implicit-coercion
"no-implicit-coercion": "error",
//https://eslint.org/docs/rules/no-unneeded-ternary
"no-unneeded-ternary": "error",
// https://eslint.org/docs/rules/semi
"semi": ["error", "always"],
// https://eslint.org/docs/rules/no-multi-spaces
"no-multi-spaces": "error",
// https://eslint.org/docs/rules/key-spacing
"key-spacing": ["error", {
"afterColon": true
}],
// https://eslint.org/docs/rules/keyword-spacing
"keyword-spacing": ["error", {
"before": true,
"after": true
}],
// https://eslint.org/docs/rules/comma-spacing
// Also requires one line code fix
"comma-spacing": ["error", {
"after": true
}],
//https://eslint.org/docs/rules/no-whitespace-before-property
"no-whitespace-before-property": "error",
// https://eslint.org/docs/rules/object-curly-newline
"object-curly-newline": ["error", {"consistent": true, "multiline": true}],
// https://eslint.org/docs/rules/object-property-newline
"object-property-newline": "error",
// https://eslint.org/docs/rules/brace-style
"brace-style": "error",
// https://eslint.org/docs/rules/no-multiple-empty-lines
"no-multiple-empty-lines": ["error", {"max": 1}],
// https://eslint.org/docs/rules/operator-linebreak
"operator-linebreak": ["error", "before", {"overrides": {"=": "after"}}],
// https://eslint.org/docs/rules/padding-line-between-statements
"padding-line-between-statements":["error", {
"blankLine": "always",
"prev": "multiline-block-like",
"next": "*"
}, {
"blankLine": "always",
"prev": "*",
"next": "return"
}],
// https://eslint.org/docs/rules/space-infix-ops
"space-infix-ops": "error",
// https://eslint.org/docs/rules/space-unary-ops
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
// https://eslint.org/docs/rules/arrow-spacing
"arrow-spacing": "error",
// https://eslint.org/docs/rules/semi-spacing
"semi-spacing": ["error", {"before": false, "after": true}],
"vue/html-indent": [
"error",
4,
@ -236,24 +96,21 @@ module.exports = {
}
}],
"vue/multiline-html-element-content-newline": "off",
"vue/singleline-html-element-content-newline": "off",
"vue/singleline-html-element-content-newline": "off"
},
"overrides": [
{
"files": LEGACY_FILES,
"files": ["*Spec.js"],
"rules": {
"no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "controller"
"varsIgnorePattern": "controller",
}
],
"no-nested-ternary": "off",
"no-var": "off",
"one-var": "off"
]
}
}
]

3
.gitignore vendored
View File

@ -37,7 +37,4 @@ protractor/logs
# npm-debug log
npm-debug.log
# karma reports
report.*.json
package-lock.json

View File

@ -131,104 +131,97 @@ changes.
### Code Standards
JavaScript sources in Open MCT must satisfy the ESLint rules defined in
this repository. This is verified by the command line build.
JavaScript sources in Open MCT must satisfy JSLint under its default
settings. This is verified by the command line build.
#### Code Guidelines
The following guidelines are provided for anyone contributing source code to the Open MCT project:
JavaScript sources in Open MCT should:
1. Write clean code. Heres a good summary - https://github.com/ryanmcdermott/clean-code-javascript.
1. Include JSDoc for any exposed API (e.g. public methods, classes).
1. Include non-JSDoc comments as-needed for explaining private variables,
methods, or algorithms when they are non-obvious. Otherwise code
should be self-documenting.
1. Classes and Vue components should use camel case, first letter capitalized
* Use four spaces for indentation. Tabs should not be used.
* Include JSDoc for any exposed API (e.g. public methods, constructors).
* Include non-JSDoc comments as-needed for explaining private variables,
methods, or algorithms when they are non-obvious.
* Define one public class per script, expressed as a constructor function
returned from an AMD-style module.
* Follow “Java-like” naming conventions. These includes:
* Classes should use camel case, first letter capitalized
(e.g. SomeClassName).
1. Methods, variables, fields, events, and function names should use camelCase,
* Methods, variables, fields, and function names should use camel case,
first letter lower-case (e.g. someVariableName).
1. Source files that export functions should use camelCase, first letter lower-case (eg. testTools.js)
1. Constants (variables or fields which are meant to be declared and
* Constants (variables or fields which are meant to be declared and
initialized statically, and never changed) should use only capital
letters, with underscores between words (e.g. SOME_CONSTANT). They should always be declared as `const`s
1. File names should be the name of the exported class, plus a .js extension
letters, with underscores between words (e.g. SOME_CONSTANT).
* File names should be the name of the exported class, plus a .js extension
(e.g. SomeClassName.js).
1. Avoid anonymous functions, except when functions are short (one or two lines)
and their inclusion makes sense within the flow of the code
(e.g. as arguments to a forEach call). Anonymous functions should always be arrow functions.
1. Named functions are preferred over functions assigned to variables.
eg.
```JavaScript
function renameObject(object, newName) {
Object.name = newName;
}
```
is preferable to
```JavaScript
const rename = (object, newName) => {
Object.name = newName;
}
```
1. Avoid deep nesting (especially of functions), except where necessary
* Avoid anonymous functions, except when functions are short (a few lines)
and/or their inclusion makes sense within the flow of the code
(e.g. as arguments to a forEach call).
* Avoid deep nesting (especially of functions), except where necessary
(e.g. due to closure scope).
1. End with a single new-line character.
1. Always use ES6 `Class`es and inheritence rather than the pre-ES6 prototypal
pattern.
1. Within a given function's scope, do not mix declarations and imperative
* End with a single new-line character.
* Expose public methods by declaring them on the class's prototype.
* Within a given function's scope, do not mix declarations and imperative
code, and present these in the following order:
* First, variable declarations and initialization.
* Secondly, imperative statements.
* Finally, the returned value. A single return statement at the end of the function should be used, except where an early return would improve code clarity.
1. Avoid the use of "magic" values.
eg.
```JavaScript
Const UNAUTHORIZED = 401
if (responseCode === UNAUTHORIZED)
```
is preferable to
```JavaScript
if (responseCode === 401)
```
1. Use the ternary operator only for simple cases such as variable assignment. Nested ternaries should be avoided in all cases.
1. Test specs should reside alongside the source code they test, not in a separate directory.
1. Organize code by feature, not by type.
eg.
```
- telemetryTable
- row
TableRow.js
TableRowCollection.js
TableRow.vue
- column
TableColumn.js
TableColumn.vue
plugin.js
pluginSpec.js
```
is preferable to
```
- telemetryTable
- components
TableRow.vue
TableColumn.vue
- collections
TableRowCollection.js
TableColumn.js
TableRow.js
plugin.js
pluginSpec.js
```
* Second, function declarations.
* Third, imperative statements.
* Finally, the returned value.
Deviations from Open MCT code style guidelines require two-party agreement,
typically from the author of the change and its reviewer.
#### Code Example
```js
/*global define*/
/**
* Bundles should declare themselves as namespaces in whichever source
* file is most like the "main point of entry" to the bundle.
* @namespace some/bundle
*/
define(
['./OtherClass'],
function (OtherClass) {
"use strict";
/**
* A summary of how to use this class goes here.
*
* @constructor
* @memberof some/bundle
*/
function ExampleClass() {
}
// Methods which are not intended for external use should
// not have JSDoc (or should be marked @private)
ExampleClass.prototype.privateMethod = function () {
};
/**
* A summary of this method goes here.
* @param {number} n a parameter
* @returns {number} a return value
*/
ExampleClass.prototype.publicMethod = function (n) {
return n * 2;
}
return ExampleClass;
}
);
```
### Test Standards
Automated testing shall occur whenever changes are merged into the main
development branch and must be confirmed alongside any pull request.
Automated tests are tests which exercise plugins, API, and utility classes.
Tests are subject to code review along with the actual implementation, to
ensure that tests are applicable and useful.
Automated tests are typically unit tests which exercise individual software
components. Tests are subject to code review along with the actual
implementation, to ensure that tests are applicable and useful.
Examples of useful tests:
* Tests which replicate bugs (or their root causes) to verify their
@ -238,26 +231,8 @@ Examples of useful tests:
* Tests which verify expected interactions with other components in the
system.
#### Guidelines
* 100% statement coverage is achievable and desirable.
* Do blackbox testing. Test external behaviors, not internal details. Write tests that describe what your plugin is supposed to do. How it does this doesn't matter, so don't test it.
* Unit test specs for plugins should be defined at the plugin level. Start with one test spec per plugin named pluginSpec.js, and as this test spec grows too big, break it up into multiple test specs that logically group related tests.
* Unit tests for API or for utility functions and classes may be defined at a per-source file level.
* Wherever possible only use and mock public API, builtin functions, and UI in your test specs. Do not directly invoke any private functions. ie. only call or mock functions and objects exposed by openmct.* (eg. openmct.telemetry, openmct.objectView, etc.), and builtin browser functions (fetch, requestAnimationFrame, setTimeout, etc.).
* Where builtin functions have been mocked, be sure to clear them between tests.
* Test at an appropriate level of isolation. Eg.
* If youre testing a view, you do not need to test the whole application UI, you can just fetch the view provider using the public API and render the view into an element that you have created.
* You do not need to test that the view switcher works, there should be separate tests for that.
* You do not need to test that telemetry providers work, you can mock openmct.telemetry.request() to feed test data to the view.
* Use your best judgement when deciding on appropriate scope.
* Automated tests for plugins should start by actually installing the plugin being tested, and then test that installing the plugin adds the desired features and behavior to Open MCT, observing the above rules.
* All variables used in a test spec, including any instances of the Open MCT API should be declared inside of an appropriate block scope (not at the root level of the source file), and should be initialized in the relevant beforeEach block. `beforeEach` is preferable to `beforeAll` to avoid leaking of state between tests.
* A `afterEach` or `afterAll` should be used to do any clean up necessary to prevent leakage of state between test specs. This can happen when functions on `window` are wrapped, or when the URL is changed. [A convenience function](https://github.com/nasa/openmct/blob/master/src/utils/testing.js#L59) is provided for resetting the URL and clearing builtin spies between tests.
* If writing unit tests for legacy Angular code be sure to follow [best practices in order to avoid memory leaks](https://www.thecodecampus.de/blog/avoid-memory-leaks-angularjs-unit-tests/).
#### Examples
* [Example of an automated test spec for an object view plugin](https://github.com/nasa/openmct/blob/master/src/plugins/telemetryTable/pluginSpec.js)
* [Example of an automated test spec for API](https://github.com/nasa/openmct/blob/master/src/api/time/TimeAPISpec.js)
During automated testing, code coverage metrics will be reported. Line
coverage must remain at or above 80%.
### Commit Message Standards

View File

@ -1,6 +1,6 @@
# Open MCT License
Open MCT, Copyright (c) 2014-2020, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.
Open MCT, Copyright (c) 2014-2019, 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.

View File

@ -125,22 +125,3 @@ A release is not closed until both categories have been performed on
the latest snapshot of the software, _and_ no issues labelled as
["blocker" or "critical"](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
remain open.
### Testathons
Testathons can be used as a means of performing per-sprint and per-release testing.
#### Timing
For per-sprint testing, a testathon is typically performed at the beginning of the third week of a sprint, and again later that week to verify any fixes. For per-release testing, a testathon is typically performed prior to any formal testing processes that are applicable to that release.
#### Process
1. Prior to the scheduled testathon, a list will be compiled of all issues that are closed and unverified.
2. For each issue, testers should review the associated PR for testing instructions. See the contributing guide for instructions on [pull requests](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md#merging).
3. As each issue is verified via testing, any team members testing it should leave a comment on that issue indicating that it has been verified fixed.
4. If a bug is found that relates to an issue being tested, notes should be included on the associated issue, and the issue should be reopened. Bug notes should include reproduction steps.
5. For any bugs that are not obviously related to any of the issues under test, a new issue should be created with details about the bug, including reproduction steps. If unsure about whether a bug relates to an issue being tested, just create a new issue.
6. At the end of the testathon, triage will take place, where all tested issues will be reviewed.
7. If verified fixed, an issue will remain closed, and will have the “unverified” label removed.
8. For any bugs found, a severity will be assigned.
9. A second testathon will be scheduled for later in the week that will aim to address all issues identified as blockers, as well as any other issues scoped by the team during triage.
10. Any issues that were not tested will remain "unverified" and will be picked up in the next testathon.

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/EventTelemetryProvider"

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define */
/**
* Module defining EventTelemetry.
@ -43,14 +44,13 @@ define(
};
generatorData.getDomainValue = function (i, domain) {
return i * interval
+ (domain !== 'delta' ? firstObservedTime : 0);
return i * interval +
(domain !== 'delta' ? firstObservedTime : 0);
};
generatorData.getRangeValue = function (i, range) {
var domainDelta = this.getDomainValue(i) - firstObservedTime,
ind = i % messages.length;
return messages[ind] + " - [" + domainDelta.toString() + "]";
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining EventTelemetryProvider. Created by chacskaylo on 06/18/2015.
@ -56,7 +57,6 @@ define(
results.forEach(function (result) {
packaged[result.key] = result.telemetry;
});
// Format as expected (sources -> keys -> telemetry)
return { eventGenerator: packaged };
}

View File

@ -19,6 +19,7 @@
* 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';
@ -75,14 +76,13 @@ define([], function () {
copyRangesToRow(row, i);
rows.push(row);
}
exportService.exportCSV(rows, { headers: headers });
});
};
ExportTelemetryAsCSVAction.appliesTo = function (context) {
return context.domainObject
&& context.domainObject.hasCapability("telemetry");
return context.domainObject &&
context.domainObject.hasCapability("telemetry");
};
return ExportTelemetryAsCSVAction;

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
'./ExportTelemetryAsCSVAction'

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ExampleFormController"

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,window*/
define(
[],
@ -79,7 +80,7 @@ define(
control: "button",
csslass: "icon-save",
click: function () {
console.log("Save");
window.alert("Save");
}
},
{
@ -87,7 +88,7 @@ define(
csslass: "icon-x",
description: "Button B",
click: function () {
console.log("Cancel");
window.alert("Cancel");
}
},
{
@ -96,7 +97,7 @@ define(
description: "Button C",
disabled: true,
click: function () {
console.log("Delete");
window.alert("Delete");
}
}
]
@ -151,22 +152,10 @@ define(
name: "Choose something",
control: "select",
options: [
{
name: "Hats",
value: "hats"
},
{
name: "Bats",
value: "bats"
},
{
name: "Cats",
value: "cats"
},
{
name: "Mats",
value: "mats"
}
{ name: "Hats", value: "hats" },
{ name: "Bats", value: "bats" },
{ name: "Cats", value: "cats" },
{ name: "Mats", value: "mats" }
],
key: "aChoice"
},
@ -175,22 +164,10 @@ define(
control: "select",
required: true,
options: [
{
name: "Hats",
value: "hats"
},
{
name: "Bats",
value: "bats"
},
{
name: "Cats",
value: "cats"
},
{
name: "Mats",
value: "mats"
}
{ name: "Hats", value: "hats" },
{ name: "Bats", value: "bats" },
{ name: "Cats", value: "cats" },
{ name: "Mats", value: "mats" }
],
key: "aRequiredChoice"
}

View File

@ -28,20 +28,9 @@ define([
domain: 2
}
},
// Need to enable "LocalTimeSystem" plugin to make use of this
// {
// key: "local",
// name: "Time",
// format: "local-format",
// source: "utc",
// hints: {
// domain: 3
// }
// },
{
key: "sin",
name: "Sine",
unit: "Hz",
formatString: '%0.2f',
hints: {
range: 1
@ -50,7 +39,6 @@ define([
{
key: "cos",
name: "Cosine",
unit: "deg",
formatString: '%0.2f',
hints: {
range: 2
@ -73,15 +61,6 @@ define([
domain: 1
}
},
{
key: "local",
name: "Time",
format: "utc",
source: "utc",
hints: {
domain: 2
}
},
{
key: "state",
source: "value",
@ -110,18 +89,18 @@ define([
}
]
}
};
}
function GeneratorMetadataProvider() {
}
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
return METADATA_BY_TYPE.hasOwnProperty(domainObject.type);
};
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
return Object.assign(
return _.extend(
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]

View File

@ -62,22 +62,18 @@ define([
var workerRequest = {};
props.forEach(function (prop) {
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) {
workerRequest[prop] = domainObject.telemetry[prop];
}
if (request && Object.prototype.hasOwnProperty.call(request, prop)) {
if (request && request.hasOwnProperty(prop)) {
workerRequest[prop] = request[prop];
}
if (!Object.prototype.hasOwnProperty.call(workerRequest, prop)) {
if (!workerRequest.hasOwnProperty(prop)) {
workerRequest[prop] = REQUEST_DEFAULTS[prop];
}
workerRequest[prop] = Number(workerRequest[prop]);
});
workerRequest.name = domainObject.name;
return workerRequest;
};
@ -85,13 +81,11 @@ define([
var workerRequest = this.makeWorkerRequest(domainObject, request);
workerRequest.start = request.start;
workerRequest.end = request.end;
return this.workerInterface.request(workerRequest);
};
GeneratorProvider.prototype.subscribe = function (domainObject, callback) {
var workerRequest = this.makeWorkerRequest(domainObject, {});
return this.workerInterface.subscribe(workerRequest, callback);
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
@ -77,15 +78,12 @@ define([
if (datum[range] > RED[range]) {
return LIMITS.rh;
}
if (datum[range] < -RED[range]) {
return LIMITS.rl;
}
if (datum[range] > YELLOW[range]) {
return LIMITS.yh;
}
if (datum[range] < -YELLOW[range]) {
return LIMITS.yl;
}

View File

@ -48,7 +48,7 @@ define([
var interval = setInterval(function () {
var now = Date.now();
var datum = pointForTimestamp(now, duration, domainObject.name);
datum.value = String(datum.value);
datum.value += "";
callback(datum);
}, duration);
@ -57,6 +57,7 @@ define([
};
};
StateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) {
return domainObject.type === 'example.state-generator';
};
@ -68,13 +69,11 @@ define([
if (options.strategy === 'latest' || options.size === 1) {
start = end;
}
var data = [];
while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, duration, domainObject.name));
start += duration;
}
return Promise.resolve(data);
};

View File

@ -72,16 +72,13 @@ define([
});
var messageId;
let self = this;
function callback(message) {
if (message.error) {
deferred.reject(message.error);
} else {
deferred.resolve(message.data);
}
delete self.callbacks[messageId];
delete this.callbacks[messageId];
}
messageId = this.dispatch('request', request, callback.bind(this));
@ -104,5 +101,8 @@ define([
}.bind(this);
};
return WorkerInterface;
});

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -20,6 +20,8 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global self*/
(function () {
var FIFTEEN_MINUTES = 15 * 60 * 1000;
@ -69,7 +71,6 @@
});
nextStep += step;
}
return nextStep;
}
@ -86,7 +87,6 @@
if (request.end === undefined) {
request.end = Date.now();
}
if (request.start === undefined) {
request.start = request.end - FIFTEEN_MINUTES;
}
@ -115,7 +115,6 @@
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
});
}
self.postMessage({
id: message.id,
data: data
@ -123,13 +122,13 @@
}
function cos(timestamp, period, amplitude, offset, phase, randomness) {
return amplitude
* Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
return amplitude *
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
}
function sin(timestamp, period, amplitude, offset, phase, randomness) {
return amplitude
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
return amplitude *
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
}
function sendError(error, message) {

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./GeneratorProvider",
@ -55,7 +56,7 @@ define([
initialize: function (object) {
object.telemetry = {
duration: 5
};
}
}
});

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ExampleIdentityService"

View File

@ -19,19 +19,16 @@
* 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";
var DEFAULT_IDENTITY = {
key: "user",
name: "Example User"
},
var DEFAULT_IDENTITY = { key: "user", name: "Example User" },
DIALOG_STRUCTURE = {
name: "Identify Yourself",
sections: [{
rows: [
sections: [{ rows: [
{
name: "User ID",
control: "textfield",
@ -44,10 +41,10 @@ define(
key: "name",
required: true
}
]
}]
]}]
};
/**
* Example implementation of an identity service. This prompts the
* user to enter a name and user ID; in a more realistic
@ -80,14 +77,14 @@ define(
*/
ExampleIdentityProvider.prototype.returnUser = function (user) {
return this.user = user;
};
}
/**
* @private
*/
ExampleIdentityProvider.prototype.returnUndefined = function () {
return undefined;
};
}
return ExampleIdentityProvider;
}

View File

@ -52,7 +52,6 @@ define([
return {
name: name,
utc: Math.floor(timestamp / 5000) * 5000,
local: Math.floor(timestamp / 5000) * 5000,
url: IMAGE_SAMPLES[Math.floor(timestamp / 5000) % IMAGE_SAMPLES.length]
};
}
@ -79,34 +78,34 @@ define([
},
request: function (domainObject, options) {
var start = options.start;
var end = Math.min(options.end, Date.now());
var end = options.end;
var data = [];
while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, domainObject.name));
start += 5000;
}
return Promise.resolve(data);
}
};
var ladProvider = {
supportsRequest: function (domainObject, options) {
return domainObject.type === 'example.imagery'
&& options.strategy === 'latest';
return domainObject.type === 'example.imagery' &&
options.strategy === 'latest';
},
request: function (domainObject, options) {
return Promise.resolve([pointForTimestamp(Date.now(), domainObject.name)]);
}
};
return function install(openmct) {
openmct.types.addType('example.imagery', {
key: 'example.imagery',
name: 'Example Imagery',
cssClass: 'icon-image',
description: 'For development use. Creates example imagery '
+ 'data that mimics a live imagery stream.',
description: 'For development use. Creates example imagery ' +
'data that mimics a live imagery stream.',
creatable: true,
initialize: function (object) {
object.telemetry = {
@ -119,14 +118,6 @@ define([
name: 'Time',
key: 'utc',
format: 'utc',
hints: {
domain: 2
}
},
{
name: 'Local Time',
key: 'local',
format: 'local-format',
hints: {
domain: 1
}
@ -140,7 +131,7 @@ define([
}
}
]
};
}
}
});

View File

@ -19,6 +19,7 @@
* 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";

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/RemsTelemetryServerAdapter",
@ -30,7 +31,6 @@ define([
RemsTelemetryProvider
) {
"use strict";
return {
name:"example/msl",
definition: {

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
function () {
@ -80,7 +81,6 @@ define(
(dictionary.instruments || []).forEach(function (instrument) {
addInstrument(instrument, "msl:curiosity");
});
return models;
}
@ -90,7 +90,6 @@ define(
}
};
}
return RemsTelemetryModelProvider;
}
);

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define */
define (
['./RemsTelemetrySeries'],
function (RemsTelemetrySeries) {
@ -73,7 +74,6 @@ define (
RemsTelemetryProvider.prototype.subscribe = function (callback, requests) {
return function () {};
};
RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) {
return function () {};
};

View File

@ -19,6 +19,7 @@
* 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";
@ -56,7 +57,6 @@ define(
RemsTelemetrySeries.prototype.getPointCount = function () {
return this.data.length;
};
/**
* The domain value at the given index. The Rems telemetry data is
* time ordered, so the domain value is the time stamp of each data

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
/*jslint es5: true */
define(
@ -94,32 +95,28 @@ define(
});
}
});
return data;
}
function fallbackToLocal() {
self.$log.warn("Loading REMS data failed, probably due to"
+ " cross origin policy. Falling back to local data");
self.$log.warn("Loading REMS data failed, probably due to" +
" cross origin policy. Falling back to local data");
return self.$http.get(self.localDataURI);
}
//Filter results to match request parameters
function filterResults(results) {
return results.filter(function (result) {
return result.date >= (request.start || Number.MIN_VALUE)
&& result.date <= (request.end || Number.MAX_VALUE);
return result.date >= (request.start || Number.MIN_VALUE) &&
result.date <= (request.end || Number.MAX_VALUE);
});
}
function packageAndResolve(results) {
return {
id: id,
values: results
};
return {id: id, values: results};
}
return (this.promise = this.promise || this.$http.get(this.REMS_WS_URL))
.catch(fallbackToLocal)
.then(processResponse)

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/DialogLaunchController",

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
@ -90,6 +91,7 @@ define(
}
};
/*
Demonstrates launching an error dialog
*/
@ -130,9 +132,9 @@ define(
var dialog,
model = {
title: "Info Dialog Example",
actionText: "This is an example of a blocking info"
+ " dialog. This dialog can be used to draw the user's"
+ " attention to an event.",
actionText: "This is an example of a blocking info" +
" dialog. This dialog can be used to draw the user's" +
" attention to an event.",
severity: "info",
primaryOption: {
label: "OK",
@ -151,7 +153,6 @@ define(
};
}
return DialogLaunchController;
}
);

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,window*/
define(
[],
@ -41,11 +42,9 @@ define(
DialogLaunchIndicator.prototype.getGlyphClass = function () {
return 'ok';
};
DialogLaunchIndicator.prototype.getText = function () {
return "Launch test dialog";
};
DialogLaunchIndicator.prototype.getDescription = function () {
return "Launch test dialog";
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
@ -47,7 +48,6 @@ define(
"Eros turpis, pulvinar turpis eros eu",
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!"
];
return actionTexts[Math.floor(Math.random()*3)];
}
@ -61,7 +61,6 @@ define(
severity: "error"
});
};
/**
* Launch a new notification with a severity of 'Alert'.
*/
@ -74,6 +73,7 @@ define(
});
};
/**
* Launch a new notification with a progress bar that is updated
* periodically, tracking an ongoing process.
@ -93,10 +93,10 @@ define(
* @param notification
*/
function incrementProgress() {
progress = Math.min(100, Math.floor(progress + Math.random() * 30));
let progressText = ["Estimated time"
+ " remaining:"
+ " about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
progress = Math.min(100, Math.floor(progress + Math.random() * 30))
let progressText = ["Estimated time" +
" remaining:" +
" about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
notification.progress(progress, progressText);
if (progress < 100) {
@ -120,7 +120,6 @@ define(
};
}
return NotificationLaunchController;
}
);

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,window*/
define(
[],
@ -41,11 +42,9 @@ define(
NotificationLaunchIndicator.prototype.getGlyphClass = function () {
return 'ok';
};
NotificationLaunchIndicator.prototype.getText = function () {
return "Launch notification";
};
NotificationLaunchIndicator.prototype.getDescription = function () {
return "Launch notification";
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/BrowserPersistenceProvider"

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
/**
* Stubbed implementation of a persistence provider,
@ -29,6 +30,8 @@ define(
function () {
'use strict';
function BrowserPersistenceProvider($q, SPACE) {
var spaces = SPACE ? [SPACE] : [],
caches = {},
@ -48,7 +51,6 @@ define(
},
listObjects: function (space) {
var cache = caches[space];
return promises.as(
cache ? Object.keys(cache) : null
);
@ -66,7 +68,6 @@ define(
},
readObject: function (space, key) {
var cache = caches[space];
return promises.as(
cache ? cache[key] : null
);

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ExamplePolicy"

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
@ -36,7 +37,6 @@ define(
model = (domainObject && domainObject.getModel()) || {},
name = model.name || "",
metadata = action.getMetadata() || {};
return metadata.key !== 'remove' || name.indexOf('foo') < 0;
}
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/WatchIndicator",

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ScratchPersistenceProvider"

View File

@ -20,6 +20,8 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,window*/
define(
[],
function () {
@ -52,14 +54,13 @@ define(
if (space === 'scratch') {
this.table[key] = JSON.stringify(value);
}
return this.$q.when(space === 'scratch');
};
ScratchPersistenceProvider.prototype.readObject = function (space, key) {
return this.$q.when(
(space === 'scratch' && this.table[key])
? JSON.parse(this.table[key]) : undefined
(space === 'scratch' && this.table[key]) ?
JSON.parse(this.table[key]) : undefined
);
};
@ -67,7 +68,6 @@ define(
if (space === 'scratch') {
delete this.table[key];
}
return this.$q.when(space === 'scratch');
};

View File

@ -7,9 +7,9 @@ export default {
data() {
return {
msg: 'Hello world!'
};
}
};
}
}
</script>
<style>

View File

@ -17,7 +17,6 @@ function SimpleVuePlugin() {
},
view: function (domainObject) {
var vm;
return {
show: function (container) {
vm = new Vue(HelloWorld);
@ -30,7 +29,7 @@ function SimpleVuePlugin() {
}
});
};
}
}
export default SimpleVuePlugin;
export default SimpleVuePlugin

View File

@ -29,104 +29,24 @@ define([
"extensions":
{
"types": [
{
"key": "styleguide.intro",
"name": "Introduction",
"cssClass": "icon-page",
"description": "Introduction and overview to the style guide"
},
{
"key": "styleguide.standards",
"name": "Standards",
"cssClass": "icon-page",
"description": ""
},
{
"key": "styleguide.colors",
"name": "Colors",
"cssClass": "icon-page",
"description": ""
},
{
"key": "styleguide.status",
"name": "status",
"cssClass": "icon-page",
"description": "Limits, telemetry paused, etc."
},
{
"key": "styleguide.glyphs",
"name": "Glyphs",
"cssClass": "icon-page",
"description": "Glyphs overview"
},
{
"key": "styleguide.controls",
"name": "Controls",
"cssClass": "icon-page",
"description": "Buttons, selects, HTML controls"
},
{
"key": "styleguide.input",
"name": "Text Inputs",
"cssClass": "icon-page",
"description": "Various text inputs"
},
{
"key": "styleguide.menus",
"name": "Menus",
"cssClass": "icon-page",
"description": "Context menus, dropdowns"
}
{ "key": "styleguide.intro", "name": "Introduction", "cssClass": "icon-page", "description": "Introduction and overview to the style guide" },
{ "key": "styleguide.standards", "name": "Standards", "cssClass": "icon-page", "description": "" },
{ "key": "styleguide.colors", "name": "Colors", "cssClass": "icon-page", "description": "" },
{ "key": "styleguide.status", "name": "status", "cssClass": "icon-page", "description": "Limits, telemetry paused, etc." },
{ "key": "styleguide.glyphs", "name": "Glyphs", "cssClass": "icon-page", "description": "Glyphs overview" },
{ "key": "styleguide.controls", "name": "Controls", "cssClass": "icon-page", "description": "Buttons, selects, HTML controls" },
{ "key": "styleguide.input", "name": "Text Inputs", "cssClass": "icon-page", "description": "Various text inputs" },
{ "key": "styleguide.menus", "name": "Menus", "cssClass": "icon-page", "description": "Context menus, dropdowns" }
],
"views": [
{
"key": "styleguide.intro",
"type": "styleguide.intro",
"template": introTemplate,
"editable": false
},
{
"key": "styleguide.standards",
"type": "styleguide.standards",
"template": standardsTemplate,
"editable": false
},
{
"key": "styleguide.colors",
"type": "styleguide.colors",
"template": colorsTemplate,
"editable": false
},
{
"key": "styleguide.status",
"type": "styleguide.status",
"template": statusTemplate,
"editable": false
},
{
"key": "styleguide.glyphs",
"type": "styleguide.glyphs",
"template": glyphsTemplate,
"editable": false
},
{
"key": "styleguide.controls",
"type": "styleguide.controls",
"template": controlsTemplate,
"editable": false
},
{
"key": "styleguide.input",
"type": "styleguide.input",
"template": inputTemplate,
"editable": false
},
{
"key": "styleguide.menus",
"type": "styleguide.menus",
"template": menusTemplate,
"editable": false
}
{ "key": "styleguide.intro", "type": "styleguide.intro", "template": introTemplate, "editable": false },
{ "key": "styleguide.standards", "type": "styleguide.standards", "template": standardsTemplate, "editable": false },
{ "key": "styleguide.colors", "type": "styleguide.colors", "template": colorsTemplate, "editable": false },
{ "key": "styleguide.status", "type": "styleguide.status", "template": statusTemplate, "editable": false },
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "template": glyphsTemplate, "editable": false },
{ "key": "styleguide.controls", "type": "styleguide.controls", "template": controlsTemplate, "editable": false },
{ "key": "styleguide.input", "type": "styleguide.input", "template": inputTemplate, "editable": false },
{ "key": "styleguide.menus", "type": "styleguide.menus", "template": menusTemplate, "editable": false }
],
"roots": [
{

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
@ -29,46 +30,14 @@ define(
var pages = {};
// Add pages
pages.intro = {
name: "Introduction",
type: "styleguide.intro",
location: "styleguide:home"
};
pages.standards = {
name: "Standards",
type: "styleguide.standards",
location: "styleguide:home"
};
pages.colors = {
name: "Colors",
type: "styleguide.colors",
location: "styleguide:home"
};
pages.glyphs = {
name: "Glyphs",
type: "styleguide.glyphs",
location: "styleguide:home"
};
pages.status = {
name: "Status Indication",
type: "styleguide.status",
location: "styleguide:home"
};
pages.controls = {
name: "Controls",
type: "styleguide.controls",
location: "styleguide:ui-elements"
};
pages.input = {
name: "Text Inputs",
type: "styleguide.input",
location: "styleguide:ui-elements"
};
pages.menus = {
name: "Menus",
type: "styleguide.menus",
location: "styleguide:ui-elements"
};
pages.intro = { name: "Introduction", type: "styleguide.intro", location: "styleguide:home" };
pages.standards = { name: "Standards", type: "styleguide.standards", location: "styleguide:home" };
pages.colors = { name: "Colors", type: "styleguide.colors", location: "styleguide:home" };
pages.glyphs = { name: "Glyphs", type: "styleguide.glyphs", location: "styleguide:home" };
pages.status = { name: "Status Indication", type: "styleguide.status", location: "styleguide:home" };
pages.controls = { name: "Controls", type: "styleguide.controls", location: "styleguide:ui-elements" };
pages.input = { name: "Text Inputs", type: "styleguide.input", location: "styleguide:ui-elements" };
pages.menus = { name: "Menus", type: "styleguide.menus", location: "styleguide:ui-elements" };
return {
getModels: function () {
@ -77,6 +46,6 @@ define(
};
}
return ExampleStyleGuideModelProvider;
return ExampleStyleGuideModelProvider
}
);

View File

@ -34,8 +34,8 @@
<body>
</body>
<script>
const THIRTY_SECONDS = 30 * 1000;
const THIRTY_MINUTES = THIRTY_SECONDS * 60;
const FIVE_MINUTES = 5 * 60 * 1000;
const THIRTY_MINUTES = 30 * 60 * 1000;
[
'example/eventGenerator'
@ -63,47 +63,15 @@
bounds: {
start: Date.now() - THIRTY_MINUTES,
end: Date.now()
},
// commonly used bounds can be stored in history
// bounds (start and end) can accept either a milliseconds number
// or a callback function returning a milliseconds number
// a function is useful for invoking Date.now() at exact moment of preset selection
presets: [
{
label: 'Last Day',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 24,
end: () => Date.now()
}
},
{
label: 'Last 2 hours',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 2,
end: () => Date.now()
}
},
{
label: 'Last hour',
bounds: {
start: () => Date.now() - 1000 * 60 * 60,
end: () => Date.now()
}
}
],
// maximum recent bounds to retain in conductor history
records: 10,
// maximum duration between start and end bounds
// for utc-based time systems this is in milliseconds
limit: 1000 * 60 * 60 * 24
},
{
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: - THIRTY_MINUTES,
end: THIRTY_SECONDS
end: FIVE_MINUTES
}
}
]
@ -113,10 +81,7 @@
openmct.install(openmct.plugins.LADTable());
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
openmct.install(openmct.plugins.ObjectMigration());
openmct.install(openmct.plugins.ClearData(
['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'],
{indicator: true}
));
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
openmct.start();
</script>
</html>

View File

@ -1,3 +0,0 @@
const testsContext = require.context('.', true, /\/(src|platform)\/.*Spec.js$/);
testsContext.keys().forEach(testsContext);

View File

@ -23,7 +23,7 @@
/*global module,process*/
const devMode = process.env.NODE_ENV !== 'production';
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless'];
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
const coverageEnabled = process.env.COVERAGE === 'true';
const reporters = ['progress', 'html'];
@ -52,16 +52,12 @@ module.exports = (config) => {
basePath: '',
frameworks: ['jasmine'],
files: [
'indexTest.js'
'platform/**/*Spec.js',
'src/**/*Spec.js'
],
port: 9876,
reporters: reporters,
browsers: browsers,
client: {
jasmine: {
random: false
}
},
customLaunchers: {
ChromeDebugging: {
base: 'Chrome',
@ -86,20 +82,19 @@ module.exports = (config) => {
reports: ['html', 'lcovonly', 'text-summary'],
thresholds: {
global: {
lines: 64
lines: 62
}
}
},
preprocessors: {
'indexTest.js': ['webpack', 'sourcemap']
'platform/**/*Spec.js': ['webpack', 'sourcemap'],
'src/**/*Spec.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only',
logLevel: 'warn'
},
concurrency: 1,
singleRun: true,
browserNoActivityTimeout: 400000
singleRun: true
});
};
}

View File

@ -32,6 +32,6 @@ if (document.currentScript) {
const MCT = require('./src/MCT');
const openmct = new MCT();
var openmct = new MCT();
module.exports = openmct;

View File

@ -1,12 +1,14 @@
{
"name": "openmct",
"version": "1.3.0-SNAPSHOT",
"version": "1.0.0-snapshot",
"description": "The Open MCT core platform",
"dependencies": {},
"dependencies": {
"plotly.js-dist": "^1.54.1"
},
"devDependencies": {
"angular": ">=1.8.0",
"angular": "1.7.9",
"angular-route": "1.4.14",
"babel-eslint": "10.0.3",
"babel-eslint": "8.2.6",
"comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2",
@ -22,9 +24,8 @@
"d3-selection": "1.3.x",
"d3-time": "1.0.x",
"d3-time-format": "2.1.x",
"eslint": "7.0.0",
"eslint": "5.2.0",
"eslint-plugin-vue": "^6.0.0",
"eslint-plugin-you-dont-need-lodash-underscore": "^6.10.0",
"eventemitter3": "^1.2.0",
"exports-loader": "^0.7.0",
"express": "^4.13.1",
@ -39,28 +40,27 @@
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0",
"jsdoc": "^3.3.2",
"karma": "5.1.1",
"karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "1.3.0",
"karma-cli": "2.0.0",
"karma-coverage": "2.0.3",
"karma-coverage-istanbul-reporter": "3.0.3",
"karma-html-reporter": "0.2.7",
"karma-jasmine": "3.3.1",
"karma-sourcemap-loader": "0.3.7",
"karma-webpack": "4.0.2",
"karma": "^2.0.3",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.2",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-html-reporter": "^0.2.7",
"karma-jasmine": "^1.1.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.0",
"location-bar": "^3.0.1",
"lodash": "^4.17.12",
"lodash": "^3.10.1",
"markdown-toc": "^0.11.7",
"marked": "^0.3.5",
"mini-css-extract-plugin": "^0.4.1",
"minimist": "^1.2.5",
"minimist": "^1.1.1",
"moment": "2.25.3",
"moment-duration-format": "^2.2.2",
"moment-timezone": "0.5.28",
"node-bourbon": "^4.2.3",
"node-sass": "^4.14.1",
"painterro": "^1.0.35",
"node-sass": "^4.9.2",
"painterro": "^0.2.65",
"printj": "^1.2.1",
"raw-loader": "^0.5.1",
"request": "^2.69.0",
@ -85,10 +85,10 @@
"build:prod": "cross-env NODE_ENV=production webpack",
"build:dev": "webpack",
"build:watch": "webpack --watch",
"test": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run",
"test": "karma start --single-run",
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
"test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run",
"test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run",
"test:coverage": "./scripts/test-coverage.sh",
"test:watch": "karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",

View File

@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* Implements Open MCT's About dialog.
* @namespace platform/commonUI/about

View File

@ -25,20 +25,14 @@ define(
function (AboutController) {
describe("The About controller", function () {
let testVersions;
let mockWindow;
let controller;
var testVersions,
mockWindow,
controller;
beforeEach(function () {
testVersions = [
{
name: "Some name",
value: "1.2.3"
},
{
name: "Some other name",
value: "3.2.1"
}
{ name: "Some name", value: "1.2.3" },
{ name: "Some other name", value: "3.2.1" }
];
mockWindow = jasmine.createSpyObj("$window", ["open"]);
controller = new AboutController(testVersions, mockWindow);
@ -56,6 +50,8 @@ define(
controller.openLicenses();
expect(mockWindow.open).toHaveBeenCalledWith("#/licenses");
});
});
}

View File

@ -46,7 +46,6 @@ define(
NavigateAction.prototype.perform = function () {
if (this.navigationService.shouldNavigate()) {
this.navigationService.setNavigation(this.domainObject, true);
return Promise.resolve({});
}

View File

@ -69,10 +69,8 @@ define(
NavigationService.prototype.setNavigation = function (domainObject, force) {
if (force) {
this.doNavigation(domainObject);
return true;
}
if (this.navigated === domainObject) {
return true;
}
@ -83,7 +81,6 @@ define(
}
this.doNavigation(domainObject);
return true;
};
@ -123,7 +120,6 @@ define(
*/
NavigationService.prototype.shouldNavigate = function () {
var doNotNavigate = this.shouldWarnBeforeNavigate();
return !doNotNavigate || this.$window.confirm(doNotNavigate);
};
@ -139,7 +135,6 @@ define(
*/
NavigationService.prototype.checkBeforeNavigation = function (checkFn) {
this.checks.push(checkFn);
return function removeCheck() {
this.checks = this.checks.filter(function (fn) {
return checkFn !== fn;
@ -177,7 +172,6 @@ define(
if (reasons.length) {
return reasons.join('\n');
}
return false;
};
@ -192,7 +186,6 @@ define(
if (shouldWarnBeforeNavigate) {
return shouldWarnBeforeNavigate;
}
if (this.oldUnload) {
return this.oldUnload.apply(undefined, [].slice.apply(arguments));
}

View File

@ -40,7 +40,6 @@ define([], function () {
function getParent(domainObject) {
var context = domainObject.getCapability('context');
return context.getParent();
}

View File

@ -53,7 +53,6 @@ define([
it("sets navigation if it is allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(true);
return action.perform()
.then(function () {
expect(mockNavigationService.setNavigation)
@ -64,7 +63,6 @@ define([
it("does not set navigation if it is not allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(false);
var onSuccess = jasmine.createSpy('onSuccess');
return action.perform()
.then(onSuccess, function () {
expect(onSuccess).not.toHaveBeenCalled();

View File

@ -79,6 +79,7 @@ define(
navigationService.addListener(callback);
navigationService.removeListener(callback);
navigationService.setNavigation(testObject);
expect(callback).not.toHaveBeenCalled();
});

View File

@ -70,7 +70,6 @@ define([
jasmine.createSpy('throttled-' + mockThrottledFns.length);
mockThrottledFn.and.callFake(fn);
mockThrottledFns.push(mockThrottledFn);
return mockThrottledFn;
});
mockTopic.and.returnValue(mockMutationTopic);
@ -82,7 +81,7 @@ define([
}[c];
});
mockDomainObject.hasCapability.and.callFake(function (c) {
return Boolean(mockDomainObject.getCapability(c));
return !!mockDomainObject.getCapability(c);
});
mockParentObject.getCapability.and.callFake(function (c) {
return {
@ -103,6 +102,7 @@ define([
);
});
it("listens for mutation with a throttled function", function () {
expect(mockMutationTopic.listen)
.toHaveBeenCalledWith(jasmine.any(Function));
@ -129,8 +129,8 @@ define([
});
[false, true].forEach(function (isEditRoot) {
var caseName = isEditRoot
? "that are being edited" : "that are not being edited";
var caseName = isEditRoot ?
"that are being edited" : "that are not being edited";
function itNavigatesAsExpected() {
if (isOrphan && !isEditRoot) {

View File

@ -31,13 +31,13 @@
</mct-form>
</div>
<div class="c-overlay__button-bar">
<button class='c-button c-button--major'
<a class='c-button c-button--major'
ng-class="{ disabled: !createForm.$valid }"
ng-click="ngModel.confirm()">
OK
</button>
<button class='c-button '
</a>
<a class='c-button '
ng-click="ngModel.cancel()">
Cancel
</button>
</a>
</div>

View File

@ -6,12 +6,6 @@
ng-show="ngModel.dialog.messages.length > 1 ||
ngModel.dialog.messages.length == 0">s</span>
</div>
<button
ng-if="ngModel.dialog.topBarButton"
class="c-button c-button--major"
ng-click="ngModel.topBarButton.onClick">
{{ ngModel.topBarButton.label }}
</button>
</div>
<div class="w-messages c-overlay__messages">
<mct-include

View File

@ -31,13 +31,13 @@
</mct-include>
</div>
<div class="c-overlay__button-bar">
<button ng-repeat="option in ngModel.dialog.options"
<a ng-repeat="option in ngModel.dialog.options"
href=''
class="s-button lg"
title="{{option.description}}"
ng-click="ngModel.confirm(option.key)"
ng-class="{ major: $first, subtle: !$first }">
{{option.name}}
</button>
</a>
</div>
</mct-container>

View File

@ -24,7 +24,7 @@
<div class="c-overlay__outer">
<button ng-click="ngModel.cancel()"
ng-if="ngModel.cancel"
class="c-click-icon c-overlay__close-button icon-x"></button>
class="c-click-icon c-overlay__close-button icon-x-in-circle"></button>
<div class="c-overlay__contents" ng-transclude></div>
</div>
</div>

View File

@ -28,6 +28,7 @@ define(
// the a specific template that can be included via mct-include
var TEMPLATE = '<mct-include ng-model="overlay" key="key" ng-class="typeClass"></mct-include>';
/**
* The OverlayService is responsible for pre-pending templates to
* the body of the document, which is useful for displaying templates
@ -52,7 +53,6 @@ define(
this.findBody = function () {
return $document.find('body');
};
this.newScope = function () {
return $rootScope.$new();
};

View File

@ -129,8 +129,8 @@ define(
);
});
it("invokes the overlay service with the correct parameters when"
+ " a blocking dialog is requested", function () {
it("invokes the overlay service with the correct parameters when" +
" a blocking dialog is requested", function () {
var dialogModel = {};
expect(dialogService.showBlockingMessage(dialogModel)).not.toBe(false);
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(

View File

@ -48,7 +48,7 @@ define(
mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockTimeout = function (callback) {
callback();
};
}
mockDocument.find.and.returnValue(mockBody);
mockCompile.and.returnValue(mockTemplate);

View File

@ -56,7 +56,6 @@ define(
//navigate back to parent because nothing to show.
return domainObject.getCapability("location").getOriginal().then(function (original) {
parent = original.getCapability("context").getParent();
return parent.getCapability("action").perform("navigate");
});
}
@ -79,10 +78,9 @@ define(
*/
CancelAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined
&& domainObject.hasCapability('editor')
&& domainObject.getCapability('editor').isEditContextRoot();
return domainObject !== undefined &&
domainObject.hasCapability('editor') &&
domainObject.getCapability('editor').isEditContextRoot();
};
return CancelAction;

View File

@ -91,9 +91,9 @@ define(
// Only allow editing of types that support it and are not already
// being edited
return type && type.hasFeature('creation')
&& domainObject.hasCapability('editor')
&& !domainObject.getCapability('editor').isEditContextRoot();
return type && type.hasFeature('creation') &&
domainObject.hasCapability('editor') &&
!domainObject.getCapability('editor').isEditContextRoot();
};
return EditAction;

View File

@ -24,6 +24,7 @@ define(
[],
function () {
/**
* Add one domain object to another's composition.
* @constructor
@ -41,9 +42,8 @@ define(
// Link these objects
function doLink() {
var composition = self.domainObject
&& self.domainObject.getCapability('composition');
var composition = self.domainObject &&
self.domainObject.getCapability('composition');
return composition && composition.add(self.selectedObject);
}

View File

@ -81,15 +81,10 @@ define(
* context.
*/
PropertiesAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject,
type = domainObject && domainObject.getCapability('type'),
creatable = type && type.hasFeature('creation');
if (domainObject && domainObject.model && domainObject.model.locked) {
return false;
}
// Only allow creatable types to be edited
return domainObject && creatable;
};
@ -99,3 +94,4 @@ define(
);

View File

@ -51,7 +51,6 @@ define(
// Property definition is same as form row definition
var row = JSON.parse(JSON.stringify(property.getDefinition()));
row.key = index;
return row;
}).filter(function (row) {
// Only show properties which are editable

View File

@ -86,11 +86,10 @@ define(
*/
SaveAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined
&& domainObject.hasCapability('editor')
&& domainObject.getCapability('editor').isEditContextRoot()
&& domainObject.getModel().persisted !== undefined;
return domainObject !== undefined &&
domainObject.hasCapability('editor') &&
domainObject.getCapability('editor').isEditContextRoot() &&
domainObject.getModel().persisted !== undefined;
};
return SaveAction;

View File

@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'../creation/CreateWizard',
'./SaveInProgressDialog'
@ -49,7 +50,6 @@ function (
this.injectObjectService = function () {
this.objectService = $injector.get("objectService");
};
this.dialogService = dialogService;
this.copyService = copyService;
this.notificationService = notificationService;
@ -75,10 +75,15 @@ function (
if (!this.objectService) {
this.injectObjectService();
}
return this.objectService;
};
function resolveWith(object) {
return function () {
return object;
};
}
/**
* Save changes and conclude editing.
*
@ -96,6 +101,7 @@ function (
SaveAsAction.prototype.save = function () {
var self = this,
domainObject = this.domainObject,
copyService = this.copyService,
dialog = new SaveInProgressDialog(this.dialogService),
toUndirty = [];
@ -112,13 +118,11 @@ function (
function showBlockingDialog(object) {
dialog.show();
return object;
}
function hideBlockingDialog(object) {
dialog.hide();
return object;
}
@ -132,22 +136,18 @@ function (
return fetchObject(object.getModel().location);
}
function saveObject(parent) {
return self.openmct.editor.save().then(() => {
// Force mutation for search indexing
return parent;
});
function allowClone(objectToClone) {
var allowed =
(objectToClone.getId() === domainObject.getId()) ||
objectToClone.getCapability('location').isOriginal();
if (allowed) {
toUndirty.push(objectToClone);
}
return allowed;
}
function addSavedObjectToParent(parent) {
return parent.getCapability("composition")
.add(domainObject)
.then(function (addedObject) {
return parent.getCapability("persistence").persist()
.then(function () {
return addedObject;
});
});
function cloneIntoParent(parent) {
return copyService.perform(domainObject, parent, allowClone);
}
function undirty(object) {
@ -156,22 +156,30 @@ function (
function undirtyOriginals(object) {
return Promise.all(toUndirty.map(undirty))
.then(() => {
return object;
});
.then(resolveWith(object));
}
function indexForSearch(addedObject) {
addedObject.useCapability('mutation', (model) => {
function saveAfterClone(clonedObject) {
return this.openmct.editor.save().then(() => {
// Force mutation for search indexing
return clonedObject;
})
}
function finishEditing(clonedObject) {
return fetchObject(clonedObject.getId())
}
function indexForSearch(savedObject) {
savedObject.useCapability('mutation', (model) => {
return model;
});
return addedObject;
return savedObject;
}
function onSuccess(object) {
self.notificationService.info("Save Succeeded");
return object;
}
@ -180,7 +188,6 @@ function (
if (reason !== "user canceled") {
self.notificationService.error("Save Failed");
}
throw reason;
}
@ -188,18 +195,17 @@ function (
.then(doWizardSave)
.then(showBlockingDialog)
.then(getParent)
.then(saveObject)
.then(addSavedObjectToParent)
.then(cloneIntoParent)
.then(undirtyOriginals)
.then((addedObject) => {
return fetchObject(addedObject.getId());
})
.then(saveAfterClone)
.then(finishEditing)
.then(indexForSearch)
.then(hideBlockingDialog)
.then(onSuccess)
.catch(onFailure);
};
/**
* Check if this action is applicable in a given context.
* This will ensure that a domain object is present in the context,
@ -208,11 +214,10 @@ function (
*/
SaveAsAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject;
return domainObject !== undefined
&& domainObject.hasCapability('editor')
&& domainObject.getCapability('editor').isEditContextRoot()
&& domainObject.getModel().persisted === undefined;
return domainObject !== undefined &&
domainObject.hasCapability('editor') &&
domainObject.getCapability('editor').isEditContextRoot() &&
domainObject.getModel().persisted === undefined;
};
return SaveAsAction;

View File

@ -83,7 +83,6 @@ define(
*/
EditorCapability.prototype.save = function () {
console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.');
return Promise.resolve();
};
@ -96,7 +95,6 @@ define(
*/
EditorCapability.prototype.finish = function () {
console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.');
return Promise.resolve();
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
['./TransactionalPersistenceCapability'],
@ -55,10 +56,9 @@ define(
capabilities.persistence = function (domainObject) {
var original =
(typeof persistenceCapability === 'function')
? persistenceCapability(domainObject)
: persistenceCapability;
(typeof persistenceCapability === 'function') ?
persistenceCapability(domainObject) :
persistenceCapability;
return new TransactionalPersistenceCapability(
self.$q,
self.transactionService,
@ -66,7 +66,6 @@ define(
domainObject
);
};
return capabilities;
};

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
@ -63,7 +64,6 @@ define(
wrappedPersistence.persist.bind(wrappedPersistence),
wrappedPersistence.refresh.bind(wrappedPersistence)
);
//Need to return a promise from this function
return this.$q.when(true);
} else {
@ -74,7 +74,6 @@ define(
TransactionalPersistenceCapability.prototype.refresh = function () {
this.transactionManager
.clearTransactionsFor(this.domainObject.getId());
return this.persistenceCapability.refresh();
};

View File

@ -48,9 +48,9 @@ define(
// Maintain all "conclude-editing" and "save" actions in the
// present context.
function updateActions() {
$scope.saveActions = $scope.action
? $scope.action.getActions(SAVE_ACTION_CONTEXT)
: [];
$scope.saveActions = $scope.action ?
$scope.action.getActions(SAVE_ACTION_CONTEXT) :
[];
$scope.saveActionsAsMenuOptions = $scope.saveActions.map(actionToMenuOption);
@ -58,9 +58,9 @@ define(
clickedAction.perform();
};
$scope.otherEditActions = $scope.action
? $scope.action.getActions(OTHERS_ACTION_CONTEXT)
: [];
$scope.otherEditActions = $scope.action ?
$scope.action.getActions(OTHERS_ACTION_CONTEXT) :
[];
// Required because Angular does not allow 'bind'
// in expressions.

View File

@ -30,11 +30,11 @@ define(
function cancelEditing(domainObject) {
var navigatedObject = domainObject,
editorCapability = navigatedObject
&& navigatedObject.getCapability("editor");
editorCapability = navigatedObject &&
navigatedObject.getCapability("editor");
return editorCapability
&& editorCapability.finish();
return editorCapability &&
editorCapability.finish();
}
/**

View File

@ -35,8 +35,8 @@ define(
// Update root object based on represented object
function updateRoot(domainObject) {
var root = self.rootDomainObject,
context = domainObject
&& domainObject.getCapability('context'),
context = domainObject &&
domainObject.getCapability('context'),
newRoot = context && context.getTrueRoot(),
oldId = root && root.getId(),
newId = newRoot && newRoot.getId();
@ -51,7 +51,6 @@ define(
// Update root when represented object changes
$scope.$watch('domainObject', updateRoot);
}
/**
* Get the root-level domain object, as reported by the
* represented domain object.

View File

@ -104,6 +104,7 @@ define(
// We will disable this.
};
/**
* Metadata associated with a Create action.
* @typedef {ActionMetadata} CreateActionMetadata

View File

@ -38,9 +38,9 @@ define(
function CreateMenuController($scope) {
// Update the set of Create actions
function refreshActions() {
$scope.createActions = $scope.action
? $scope.action.getActions('create')
: [];
$scope.createActions = $scope.action ?
$scope.action.getActions('create') :
[];
}
// Listen for new instances of the represented object's

View File

@ -56,11 +56,10 @@ define(
*/
CreateWizard.prototype.getFormStructure = function (includeLocation) {
var sections = [],
domainObject = this.domainObject,
self = this;
domainObject = this.domainObject;
function validateLocation(parent) {
return parent && self.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
return parent && this.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
}
sections.push({
@ -115,7 +114,6 @@ define(
this.domainObject.useCapability("mutation", function () {
return formModel;
});
return this.domainObject;
};

View File

@ -73,13 +73,12 @@ define(
// as a child contained by that parent.
function addToComposition() {
var compositionCapability = parent.getCapability('composition'),
addResult = compositionCapability
&& compositionCapability.add(newObject);
addResult = compositionCapability &&
compositionCapability.add(newObject);
return self.$q.when(addResult).then(function (result) {
if (!result) {
self.$log.error("Could not modify " + parent.getId());
return undefined;
}
@ -93,7 +92,6 @@ define(
// what space to create the new object's model in.
if (!persistence || !newObjectPersistence) {
self.$log.warn(NON_PERSISTENT_WARNING);
return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
}
@ -101,6 +99,8 @@ define(
return newObjectPersistence.persist().then(addToComposition);
};
return CreationService;
}
);

View File

@ -38,8 +38,8 @@ define(
// * treeModel: The model for the embedded tree representation,
// used for bi-directional object selection.
function setLocatingObject(domainObject, priorObject) {
var context = domainObject
&& domainObject.getCapability("context"),
var context = domainObject &&
domainObject.getCapability("context"),
contextRoot = context && context.getRoot();
if (contextRoot && contextRoot !== $scope.rootObject) {
@ -65,12 +65,11 @@ define(
$scope.ngModel[$scope.field] = domainObject;
// Restrict which locations can be selected
if (domainObject
&& $scope.structure
&& $scope.structure.validate) {
if (domainObject &&
$scope.structure &&
$scope.structure.validate) {
if (!$scope.structure.validate(domainObject)) {
setLocatingObject(priorObject, undefined);
return;
}
}
@ -79,7 +78,7 @@ define(
if ($scope.ngModelController) {
$scope.ngModelController.$setValidity(
'composition',
Boolean($scope.treeModel.selectedObject)
!!$scope.treeModel.selectedObject
);
}
}

View File

@ -21,7 +21,7 @@
*****************************************************************************/
define(
['objectUtils'],
['../../../../../src/api/objects/object-utils'],
function (objectUtils) {
/**
@ -36,6 +36,8 @@ define(
}
EditPersistableObjectsPolicy.prototype.allow = function (action, context) {
var identifier;
var provider;
var domainObject = context.domainObject;
var key = action.getMetadata().key;
var category = (context || {}).category;
@ -44,9 +46,9 @@ define(
// is also invoked during the create process which should be allowed,
// because it may be saved elsewhere
if ((key === 'edit' && category === 'view-control') || key === 'properties') {
let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId());
return this.openmct.objects.isPersistable(newStyleObject);
identifier = objectUtils.parseKeyString(domainObject.getId());
provider = this.openmct.objects.getProvider(identifier);
return provider.save !== undefined;
}
return true;

View File

@ -74,7 +74,6 @@ define(
model.configuration = model.configuration || {};
model.configuration[this.key] = configuration;
}
domainObject.useCapability('mutation', function () {
return model;
});

View File

@ -41,7 +41,6 @@ define(['./Transaction'], function (Transaction) {
Transaction.prototype.commit.bind(this),
Transaction.prototype.cancel.bind(this)
);
return Promise.resolve(true);
};

View File

@ -41,12 +41,8 @@ define([], function () {
* pair of callbacks from the transaction
*/
Transaction.prototype.add = function (commit, cancel) {
var callback = {
commit: commit,
cancel: cancel
};
var callback = { commit: commit, cancel: cancel };
this.callbacks.push(callback);
return function () {
this.callbacks = this.callbacks.filter(function (c) {
return c !== callback;
@ -95,5 +91,6 @@ define([], function () {
};
});
return Transaction;
});

View File

@ -50,7 +50,7 @@ define([], function () {
* @returns {boolean} true if callbacks have been added
*/
TransactionManager.prototype.isScheduled = function (id) {
return Boolean(this.clearTransactionFns[id]);
return !!this.clearTransactionFns[id];
};
/**
@ -77,7 +77,6 @@ define([], function () {
return promiseFn().then(nextFn);
};
}
/**
* Clear any existing persistence calls for object with given ID. This ensures only the most recent persistence
* call is executed. This should prevent stale objects being persisted and overwriting fresh ones.

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
['./Transaction', './NestedTransaction'],
function (Transaction, NestedTransaction) {
@ -47,9 +48,9 @@ define(
* #cancel} are called
*/
TransactionService.prototype.startTransaction = function () {
var transaction = this.isActive()
? new NestedTransaction(this.transactions[0])
: new Transaction(this.$log);
var transaction = this.isActive() ?
new NestedTransaction(this.transactions[0]) :
new Transaction(this.$log);
this.transactions.push(transaction);
};
@ -98,16 +99,13 @@ define(
if (!transaction) {
return Promise.reject();
}
if (!this.isActive()) {
return transaction.commit()
.then(function (r) {
this.cacheService.flush();
return r;
}.bind(this));
}
return transaction.commit();
};
@ -121,7 +119,6 @@ define(
*/
TransactionService.prototype.cancel = function () {
var transaction = this.transactions.pop();
return transaction ? transaction.cancel() : Promise.reject();
};

View File

@ -102,7 +102,7 @@ define(
});
mockDomainObject.hasCapability.and.callFake(function (name) {
return Boolean(capabilities[name]);
return !!capabilities[name];
});
capabilities.editor.finish.and.returnValue(mockPromise(true));
@ -123,8 +123,8 @@ define(
expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
});
it("invokes the editor capability's cancel functionality when"
+ " performed", function () {
it("invokes the editor capability's cancel functionality when" +
" performed", function () {
mockDomainObject.getModel.and.returnValue({persisted: 1});
//Return true from navigate action
capabilities.action.perform.and.returnValue(mockPromise(true));

View File

@ -93,6 +93,7 @@ define(
action = new EditAndComposeAction(actionContext);
});
it("adds to the parent's composition when performed", function () {
action.perform();
expect(mockComposition.add)
@ -105,8 +106,8 @@ define(
expect(mockEditAction.perform).toHaveBeenCalled();
});
it("Does not enable edit mode for objects that do not have an"
+ " edit action", function () {
it("Does not enable edit mode for objects that do not have an" +
" edit action", function () {
mockActionCapability.getActions.and.returnValue([]);
action.perform();
expect(mockEditAction.perform).not.toHaveBeenCalled();

View File

@ -64,10 +64,7 @@ define(
return true;
}
};
context = {
someKey: "some value",
domainObject: object
};
context = { someKey: "some value", domainObject: object };
dialogService = {
getUserInput: function () {
return mockPromise(input);

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/
define(
["../../src/actions/SaveAction"],
@ -137,7 +138,6 @@ define(
it("notifies if saving succeeded", function () {
var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.resolve());
return action.perform().then(mockCallback).then(function () {
expect(mockNotificationService.info).toHaveBeenCalled();
expect(mockNotificationService.error).not.toHaveBeenCalled();
@ -147,7 +147,6 @@ define(
it("notifies if saving failed", function () {
var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.reject("some failure reason"));
return action.perform().then(mockCallback).then(function () {
expect(mockNotificationService.error).toHaveBeenCalled();
expect(mockNotificationService.info).not.toHaveBeenCalled();

View File

@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/
define(
["../../src/actions/SaveAndStopEditingAction"],
@ -96,6 +97,7 @@ define(
action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext);
});
it("only applies to domain object with an editor capability", function () {
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine,spyOn*/
define(
["../../src/actions/SaveAsAction"],
@ -41,8 +42,8 @@ define(
function noop() {}
function mockPromise(value) {
return (value || {}).then ? value
: {
return (value || {}).then ? value :
{
then: function (callback) {
return mockPromise(callback(value));
},
@ -66,10 +67,7 @@ define(
mockDomainObject.getCapability.and.callFake(function (capability) {
return capabilities[capability];
});
mockDomainObject.getModel.and.returnValue({
location: 'a',
persisted: undefined
});
mockDomainObject.getModel.and.returnValue({location: 'a', persisted: undefined});
mockDomainObject.getId.and.returnValue(0);
mockClonedObject = jasmine.createSpyObj(
@ -170,8 +168,8 @@ define(
expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
});
it("only applies to domain object that has not already been"
+ " persisted", function () {
it("only applies to domain object that has not already been" +
" persisted", function () {
expect(SaveAsAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");

View File

@ -118,8 +118,8 @@ define(
expect(capability.isEditContextRoot()).toBe(true);
});
it("inEditingContext returns true if parent object is being"
+ " edited", function () {
it("inEditingContext returns true if parent object is being" +
" edited", function () {
mockStatusCapability.get.and.returnValue(false);
mockParentStatus.get.and.returnValue(false);
expect(capability.inEditContext()).toBe(false);
@ -179,8 +179,8 @@ define(
capability.edit();
capability.finish();
});
it("returns true if the object has been modified since it"
+ " was last persisted", function () {
it("returns true if the object has been modified since it" +
" was last persisted", function () {
mockTransactionService.size.and.returnValue(0);
expect(capability.dirty()).toBe(false);
mockTransactionService.size.and.returnValue(1);

View File

@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@ -19,6 +19,7 @@
* 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*/
define(
[
@ -75,15 +76,15 @@ define(
);
});
it("if no transaction is active, passes through to persistence"
+ " provider", function () {
it("if no transaction is active, passes through to persistence" +
" provider", function () {
mockTransactionManager.isActive.and.returnValue(false);
capability.persist();
expect(mockPersistence.persist).toHaveBeenCalled();
});
it("if transaction is active, persist and cancel calls are"
+ " queued", function () {
it("if transaction is active, persist and cancel calls are" +
" queued", function () {
mockTransactionManager.isActive.and.returnValue(true);
capability.persist();
expect(mockTransactionManager.addToTransaction).toHaveBeenCalled();

Some files were not shown because too many files have changed in this diff Show More