mirror of
https://github.com/nasa/openmct.git
synced 2025-03-24 04:55:21 +00:00
365 lines
8.9 KiB
JavaScript
365 lines
8.9 KiB
JavaScript
/*****************************************************************************
|
|
* Open MCT, Copyright (c) 2014-2024, United States Government
|
|
* as represented by the Administrator of the National Aeronautics and Space
|
|
* Administration. All rights reserved.
|
|
*
|
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
* Open MCT includes source code licensed under additional open source
|
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
* this source code distribution or the Licensing information page available
|
|
* at runtime from the About dialog for additional information.
|
|
*****************************************************************************/
|
|
|
|
import { MCT } from 'MCT';
|
|
import { markRaw } from 'vue';
|
|
|
|
let nativeFunctions = [];
|
|
let mockObjects = setMockObjects();
|
|
|
|
const EXAMPLE_ROLE = 'flight';
|
|
const DEFAULT_TIME_OPTIONS = {
|
|
timeSystemKey: 'utc',
|
|
bounds: {
|
|
start: 0,
|
|
end: 1
|
|
}
|
|
};
|
|
|
|
export function createOpenMct(timeSystemOptions = DEFAULT_TIME_OPTIONS) {
|
|
const openmct = markRaw(new MCT());
|
|
openmct.install(openmct.plugins.LocalStorage());
|
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
|
openmct.setAssetPath('/base');
|
|
openmct.user.setActiveRole(EXAMPLE_ROLE);
|
|
|
|
const timeSystemKey = timeSystemOptions.timeSystemKey;
|
|
const start = timeSystemOptions.bounds.start;
|
|
const end = timeSystemOptions.bounds.end;
|
|
|
|
openmct.time.setTimeSystem(timeSystemKey, {
|
|
start,
|
|
end
|
|
});
|
|
|
|
return openmct;
|
|
}
|
|
|
|
export function createMouseEvent(eventName) {
|
|
return new MouseEvent(eventName, {
|
|
bubbles: true,
|
|
cancelable: true,
|
|
view: window
|
|
});
|
|
}
|
|
|
|
export function spyOnBuiltins(functionNames, object = window) {
|
|
functionNames.forEach((functionName) => {
|
|
if (nativeFunctions[functionName]) {
|
|
throw `Builtin spy function already defined for ${functionName}`;
|
|
}
|
|
|
|
nativeFunctions.push({
|
|
functionName,
|
|
object,
|
|
nativeFunction: object[functionName]
|
|
});
|
|
spyOn(object, functionName);
|
|
});
|
|
}
|
|
|
|
export function clearBuiltinSpies() {
|
|
nativeFunctions.forEach(clearBuiltinSpy);
|
|
nativeFunctions = [];
|
|
}
|
|
|
|
export function resetApplicationState(openmct) {
|
|
let promise;
|
|
|
|
clearBuiltinSpies();
|
|
|
|
if (openmct !== undefined) {
|
|
openmct.destroy();
|
|
}
|
|
|
|
if (window.location.hash !== '#' && window.location.hash !== '') {
|
|
promise = new Promise((resolve, reject) => {
|
|
window.addEventListener('hashchange', cleanup);
|
|
window.location.hash = '#';
|
|
|
|
function cleanup() {
|
|
window.removeEventListener('hashchange', cleanup);
|
|
resolve();
|
|
}
|
|
});
|
|
} else {
|
|
promise = Promise.resolve();
|
|
}
|
|
|
|
return promise;
|
|
}
|
|
|
|
// required: key
|
|
// optional: element, keyCode, type
|
|
export function simulateKeyEvent(opts) {
|
|
if (!opts.key) {
|
|
console.warn('simulateKeyEvent needs a key');
|
|
|
|
return;
|
|
}
|
|
|
|
const el = opts.element || document;
|
|
const key = opts.key;
|
|
const keyCode = opts.keyCode || key;
|
|
const type = opts.type || 'keydown';
|
|
const event = new Event(type);
|
|
|
|
event.keyCode = keyCode;
|
|
event.key = key;
|
|
|
|
el.dispatchEvent(event);
|
|
}
|
|
|
|
function clearBuiltinSpy(funcDefinition) {
|
|
funcDefinition.object[funcDefinition.functionName] = funcDefinition.nativeFunction;
|
|
}
|
|
|
|
export function getLatestTelemetry(telemetry = [], opts = {}) {
|
|
let latest = [];
|
|
let timeFormat = opts.timeFormat || 'utc';
|
|
|
|
if (telemetry.length) {
|
|
latest = telemetry.reduce((prev, cur) => {
|
|
return prev[timeFormat] > cur[timeFormat] ? prev : cur;
|
|
});
|
|
}
|
|
|
|
return latest;
|
|
}
|
|
|
|
// EXAMPLE:
|
|
// getMockObjects({
|
|
// name: 'Jamie Telemetry',
|
|
// keys: ['test','other','yeah','sup'],
|
|
// format: 'local',
|
|
// telemetryConfig: {
|
|
// hints: {
|
|
// test: {
|
|
// domain: 1
|
|
// },
|
|
// other: {
|
|
// range: 2
|
|
// }
|
|
// }
|
|
// }
|
|
// })
|
|
export function getMockObjects(opts = {}) {
|
|
opts.type = opts.type || 'default';
|
|
if (opts.objectKeyStrings && !Array.isArray(opts.objectKeyStrings)) {
|
|
throw `"getMockObjects" optional parameter "objectKeyStrings" must be an array of string object keys`;
|
|
}
|
|
|
|
let requestedMocks = {};
|
|
|
|
if (!opts.objectKeyStrings) {
|
|
requestedMocks = copyObj(mockObjects[opts.type]);
|
|
} else {
|
|
opts.objectKeyStrings.forEach((objKey) => {
|
|
if (mockObjects[opts.type] && mockObjects[opts.type][objKey]) {
|
|
requestedMocks[objKey] = copyObj(mockObjects[opts.type][objKey]);
|
|
} else {
|
|
throw `No mock object for object key "${objKey}" of type "${opts.type}"`;
|
|
}
|
|
});
|
|
}
|
|
|
|
// build out custom telemetry mappings if necessary
|
|
if (requestedMocks.telemetry && opts.telemetryConfig) {
|
|
let keys = opts.telemetryConfig.keys;
|
|
let format = opts.telemetryConfig.format || 'utc';
|
|
let hints = opts.telemetryConfig.hints;
|
|
let values;
|
|
|
|
// if utc, keep default
|
|
if (format === 'utc') {
|
|
// save for later if new keys
|
|
if (keys) {
|
|
format = requestedMocks.telemetry.telemetry.values.find((vals) => vals.key === 'utc');
|
|
}
|
|
} else {
|
|
format = {
|
|
key: format,
|
|
name: 'Time',
|
|
format: format === 'local' ? 'local-format' : format,
|
|
hints: {
|
|
domain: 1
|
|
}
|
|
};
|
|
}
|
|
|
|
if (keys) {
|
|
values = keys.map((key) => ({
|
|
key,
|
|
name: key + ' attribute'
|
|
}));
|
|
values.push(format); // add time format back in
|
|
} else {
|
|
values = requestedMocks.telemetry.telemetry.values;
|
|
}
|
|
|
|
if (hints) {
|
|
for (let val of values) {
|
|
if (hints[val.key]) {
|
|
val.hints = hints[val.key];
|
|
}
|
|
}
|
|
}
|
|
|
|
requestedMocks.telemetry.telemetry.values = values;
|
|
}
|
|
|
|
// overwrite any field keys
|
|
if (opts.overwrite) {
|
|
for (let mock in requestedMocks) {
|
|
if (opts.overwrite[mock]) {
|
|
requestedMocks[mock] = Object.assign(requestedMocks[mock], opts.overwrite[mock]);
|
|
}
|
|
}
|
|
}
|
|
|
|
return requestedMocks;
|
|
}
|
|
|
|
// EXAMPLE:
|
|
// getMockTelemetry({
|
|
// name: 'My Telemetry',
|
|
// keys: ['test','other','yeah','sup'],
|
|
// count: 8,
|
|
// format: 'local'
|
|
// })
|
|
export function getMockTelemetry(opts = {}) {
|
|
let count = opts.count || 2;
|
|
let format = opts.format || 'utc';
|
|
let name = opts.name || 'Mock Telemetry Datum';
|
|
let keyCount = 2;
|
|
let keys = false;
|
|
let telemetry = [];
|
|
|
|
if (opts.keys && Array.isArray(opts.keys)) {
|
|
keyCount = opts.keys.length;
|
|
keys = opts.keys;
|
|
} else if (opts.keyCount) {
|
|
keyCount = opts.keyCount;
|
|
}
|
|
|
|
for (let i = 1; i < count + 1; i++) {
|
|
let datum = {
|
|
[format]: i,
|
|
name
|
|
};
|
|
|
|
for (let k = 1; k < keyCount + 1; k++) {
|
|
let key = keys ? keys[k - 1] : 'some-key-' + k;
|
|
let value = keys ? keys[k - 1] + ' value ' + i : 'some value ' + i + '-' + k;
|
|
datum[key] = value;
|
|
}
|
|
|
|
telemetry.push(datum);
|
|
}
|
|
|
|
return telemetry;
|
|
}
|
|
|
|
// used to inject into tests that require a render
|
|
export function renderWhenVisible(func) {
|
|
func();
|
|
return true;
|
|
}
|
|
|
|
// copy objects a bit more easily
|
|
function copyObj(obj) {
|
|
return JSON.parse(JSON.stringify(obj));
|
|
}
|
|
|
|
// add any other necessary types to this mockObjects object
|
|
function setMockObjects() {
|
|
return {
|
|
default: {
|
|
folder: {
|
|
identifier: {
|
|
namespace: '',
|
|
key: 'folder-object'
|
|
},
|
|
name: 'Test Folder Object',
|
|
type: 'folder',
|
|
composition: [],
|
|
location: 'mine'
|
|
},
|
|
ladTable: {
|
|
identifier: {
|
|
namespace: '',
|
|
key: 'lad-object'
|
|
},
|
|
type: 'LadTable',
|
|
composition: []
|
|
},
|
|
ladTableSet: {
|
|
identifier: {
|
|
namespace: '',
|
|
key: 'lad-set-object'
|
|
},
|
|
type: 'LadTableSet',
|
|
composition: []
|
|
},
|
|
telemetry: {
|
|
identifier: {
|
|
namespace: '',
|
|
key: 'telemetry-object'
|
|
},
|
|
type: 'test-telemetry-object',
|
|
name: 'Test Telemetry Object',
|
|
telemetry: {
|
|
values: [
|
|
{
|
|
key: 'name',
|
|
name: 'Name',
|
|
format: 'string'
|
|
},
|
|
{
|
|
key: 'utc',
|
|
name: 'Time',
|
|
format: 'utc',
|
|
hints: {
|
|
domain: 1
|
|
}
|
|
},
|
|
{
|
|
name: 'Some attribute 1',
|
|
key: 'some-key-1',
|
|
hints: {
|
|
range: 1
|
|
}
|
|
},
|
|
{
|
|
name: 'Some attribute 2',
|
|
key: 'some-key-2'
|
|
}
|
|
]
|
|
}
|
|
}
|
|
},
|
|
otherType: {
|
|
example: {}
|
|
}
|
|
};
|
|
}
|