Compare commits
	
		
			18 Commits
		
	
	
		
			sprint-2.0
			...
			expect-cou
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 584fe66d6f | ||
|   | e784242379 | ||
|   | da8dbf25bf | ||
|   | a5571eec05 | ||
|   | 19802ce2cc | ||
|   | e83735a927 | ||
|   | c9a47a411a | ||
|   | a6e55fd493 | ||
|   | 76f35a0bcd | ||
|   | b6930ef7cd | ||
|   | 57b9cbd42f | ||
|   | 17901147ef | ||
|   | 58b8f90682 | ||
|   | d06cbc8975 | ||
|   | 553b18587c | ||
|   | 590dc74e45 | ||
|   | 3557ed4b4c | ||
|   | 41cc52d50a | 
| @@ -41,11 +41,6 @@ define([ | ||||
|                             "$scope" | ||||
|                         ] | ||||
|                     } | ||||
|                 ], | ||||
|                 "routes": [ | ||||
|                     { | ||||
|                         "templateUrl": "templates/exampleForm.html" | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -96,5 +96,9 @@ define([ | ||||
|         return this.workerInterface.subscribe(workerRequest, callback); | ||||
|     }; | ||||
|  | ||||
|     GeneratorProvider.prototype.destroy = function () { | ||||
|         this.workerInterface.destroy(); | ||||
|     }; | ||||
|  | ||||
|     return GeneratorProvider; | ||||
| }); | ||||
|   | ||||
| @@ -40,6 +40,11 @@ define([ | ||||
|         this.callbacks = {}; | ||||
|     } | ||||
|  | ||||
|     WorkerInterface.prototype.destroy = function () { | ||||
|         delete this.worker.onmessage; | ||||
|         this.worker.terminate(); | ||||
|     }; | ||||
|  | ||||
|     WorkerInterface.prototype.onMessage = function (message) { | ||||
|         message = message.data; | ||||
|         var callback = this.callbacks[message.id]; | ||||
|   | ||||
| @@ -146,7 +146,11 @@ define([ | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         openmct.telemetry.addProvider(new GeneratorProvider()); | ||||
|         const generatorProvider = new GeneratorProvider(); | ||||
|         openmct.once('destroy', () => { | ||||
|             generatorProvider.destroy(); | ||||
|         }); | ||||
|         openmct.telemetry.addProvider(generatorProvider); | ||||
|         openmct.telemetry.addProvider(new GeneratorMetadataProvider()); | ||||
|         openmct.telemetry.addProvider(new SinewaveLimitProvider()); | ||||
|     }; | ||||
|   | ||||
							
								
								
									
										33
									
								
								indexTest.js
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								indexTest.js
									
									
									
									
									
								
							| @@ -1,3 +1,36 @@ | ||||
|  | ||||
| const jasmineIt = window.it; | ||||
| const specIdsToExpectCount = new Map(); | ||||
| const failures = []; | ||||
|  | ||||
| window.it = function (name, specFunction) { | ||||
|     const expectRE = /expect\(/g; | ||||
|     const expectCount = (specFunction.toString().match(expectRE) || []).length; | ||||
|     const spec = jasmineIt(name, specFunction); | ||||
|  | ||||
|     specIdsToExpectCount.set(spec.id, expectCount); | ||||
|  | ||||
|     return spec; | ||||
| }; | ||||
|  | ||||
| const testsContext = require.context('.', true, /\/(src|platform)\/.*Spec.js$/); | ||||
|  | ||||
| jasmine.getEnv().addReporter({ | ||||
|     specDone(spec) { | ||||
|         const totalExpectsRun = (spec.failedExpectations || []).length + (spec.passedExpectations || []).length; | ||||
|         const totalExpectsDefined = specIdsToExpectCount.get(spec.id); | ||||
|  | ||||
|         if (totalExpectsRun < totalExpectsDefined) { | ||||
|             failures.push(`Executed ${totalExpectsRun} but ${totalExpectsDefined} were defined for spec ${spec.fullName}`); | ||||
|         } | ||||
|  | ||||
|     }, | ||||
|     jasmineDone() { | ||||
|         window.it = jasmineIt; | ||||
|         failures.forEach(failure => { | ||||
|             console.error(failure); | ||||
|         }); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| testsContext.keys().forEach(testsContext); | ||||
|   | ||||
| @@ -164,16 +164,6 @@ define([ | ||||
|                         "license": "license-apache", | ||||
|                         "link": "http://logging.apache.org/log4net/license.html" | ||||
|                     } | ||||
|                 ], | ||||
|                 "routes": [ | ||||
|                     { | ||||
|                         "when": "/licenses", | ||||
|                         "template": licensesTemplate | ||||
|                     }, | ||||
|                     { | ||||
|                         "when": "/licenses-md", | ||||
|                         "template": licensesExportMdTemplate | ||||
|                     } | ||||
|                 ] | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -50,8 +50,6 @@ define([ | ||||
|         name: "platform/commonUI/browse", | ||||
|         definition: { | ||||
|             "extensions": { | ||||
|                 "routes": [ | ||||
|                 ], | ||||
|                 "constants": [ | ||||
|                     { | ||||
|                         "key": "DEFAULT_PATH", | ||||
|   | ||||
| @@ -39,9 +39,6 @@ define( | ||||
|             this.callbacks = []; | ||||
|             this.checks = []; | ||||
|             this.$window = $window; | ||||
|  | ||||
|             this.oldUnload = $window.onbeforeunload; | ||||
|             $window.onbeforeunload = this.onBeforeUnload.bind(this); | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|   | ||||
| @@ -1,249 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../../src/actions/SaveAsAction"], | ||||
|     function (SaveAsAction) { | ||||
|  | ||||
|         xdescribe("The Save As action", function () { | ||||
|             var mockDomainObject, | ||||
|                 mockClonedObject, | ||||
|                 mockEditorCapability, | ||||
|                 mockActionCapability, | ||||
|                 mockObjectService, | ||||
|                 mockDialogService, | ||||
|                 mockCopyService, | ||||
|                 mockNotificationService, | ||||
|                 mockParent, | ||||
|                 actionContext, | ||||
|                 capabilities = {}, | ||||
|                 action; | ||||
|  | ||||
|             function noop() {} | ||||
|  | ||||
|             function mockPromise(value) { | ||||
|                 return (value || {}).then ? value | ||||
|                     : { | ||||
|                         then: function (callback) { | ||||
|                             return mockPromise(callback(value)); | ||||
|                         }, | ||||
|                         catch: function (callback) { | ||||
|                             return mockPromise(callback(value)); | ||||
|                         } | ||||
|                     }; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     [ | ||||
|                         "getCapability", | ||||
|                         "hasCapability", | ||||
|                         "getModel", | ||||
|                         "getId" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockDomainObject.hasCapability.and.returnValue(true); | ||||
|                 mockDomainObject.getCapability.and.callFake(function (capability) { | ||||
|                     return capabilities[capability]; | ||||
|                 }); | ||||
|                 mockDomainObject.getModel.and.returnValue({ | ||||
|                     location: 'a', | ||||
|                     persisted: undefined | ||||
|                 }); | ||||
|                 mockDomainObject.getId.and.returnValue(0); | ||||
|  | ||||
|                 mockClonedObject = jasmine.createSpyObj( | ||||
|                     "clonedObject", | ||||
|                     [ | ||||
|                         "getId" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockClonedObject.getId.and.returnValue(1); | ||||
|  | ||||
|                 mockParent = jasmine.createSpyObj( | ||||
|                     "parentObject", | ||||
|                     [ | ||||
|                         "getCapability", | ||||
|                         "hasCapability", | ||||
|                         "getModel" | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|                 mockEditorCapability = jasmine.createSpyObj( | ||||
|                     "editor", | ||||
|                     ["save", "finish", "isEditContextRoot"] | ||||
|                 ); | ||||
|                 mockEditorCapability.save.and.returnValue(mockPromise(true)); | ||||
|                 mockEditorCapability.finish.and.returnValue(mockPromise(true)); | ||||
|                 mockEditorCapability.isEditContextRoot.and.returnValue(true); | ||||
|                 capabilities.editor = mockEditorCapability; | ||||
|  | ||||
|                 mockActionCapability = jasmine.createSpyObj( | ||||
|                     "action", | ||||
|                     ["perform"] | ||||
|                 ); | ||||
|                 capabilities.action = mockActionCapability; | ||||
|  | ||||
|                 mockObjectService = jasmine.createSpyObj( | ||||
|                     "objectService", | ||||
|                     ["getObjects"] | ||||
|                 ); | ||||
|                 mockObjectService.getObjects.and.returnValue(mockPromise({'a': mockParent})); | ||||
|  | ||||
|                 mockDialogService = jasmine.createSpyObj( | ||||
|                     "dialogService", | ||||
|                     [ | ||||
|                         "getUserInput", | ||||
|                         "showBlockingMessage" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockDialogService.getUserInput.and.returnValue(mockPromise(undefined)); | ||||
|  | ||||
|                 mockCopyService = jasmine.createSpyObj( | ||||
|                     "copyService", | ||||
|                     [ | ||||
|                         "perform" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockCopyService.perform.and.returnValue(mockPromise(mockClonedObject)); | ||||
|  | ||||
|                 mockNotificationService = jasmine.createSpyObj( | ||||
|                     "notificationService", | ||||
|                     [ | ||||
|                         "info", | ||||
|                         "error" | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|                 actionContext = { | ||||
|                     domainObject: mockDomainObject | ||||
|                 }; | ||||
|  | ||||
|                 action = new SaveAsAction( | ||||
|                     undefined, | ||||
|                     undefined, | ||||
|                     mockDialogService, | ||||
|                     mockCopyService, | ||||
|                     mockNotificationService, | ||||
|                     actionContext); | ||||
|  | ||||
|                 spyOn(action, "getObjectService"); | ||||
|                 action.getObjectService.and.returnValue(mockObjectService); | ||||
|  | ||||
|                 spyOn(action, "createWizard"); | ||||
|                 action.createWizard.and.returnValue({ | ||||
|                     getFormStructure: noop, | ||||
|                     getInitialFormValue: noop, | ||||
|                     populateObjectFromInput: function () { | ||||
|                         return mockDomainObject; | ||||
|                     } | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             it("only applies to domain object with an editor capability", function () { | ||||
|                 expect(SaveAsAction.appliesTo(actionContext)).toBe(true); | ||||
|                 expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); | ||||
|  | ||||
|                 mockDomainObject.hasCapability.and.returnValue(false); | ||||
|                 mockDomainObject.getCapability.and.returnValue(undefined); | ||||
|                 expect(SaveAsAction.appliesTo(actionContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|             it("only applies to domain object that has not already been" | ||||
|                 + " persisted", function () { | ||||
|                 expect(SaveAsAction.appliesTo(actionContext)).toBe(true); | ||||
|                 expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); | ||||
|  | ||||
|                 mockDomainObject.getModel.and.returnValue({persisted: 0}); | ||||
|                 expect(SaveAsAction.appliesTo(actionContext)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|             it("uses the editor capability to save the object", function () { | ||||
|                 mockEditorCapability.save.and.returnValue(Promise.resolve()); | ||||
|  | ||||
|                 return action.perform().then(function () { | ||||
|                     expect(mockEditorCapability.save).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("uses the editor capability to finish editing the object", function () { | ||||
|                 return action.perform().then(function () { | ||||
|                     expect(mockEditorCapability.finish.calls.count()).toBeGreaterThan(0); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("returns to browse after save", function () { | ||||
|                 spyOn(action, "save"); | ||||
|                 action.save.and.returnValue(mockPromise(mockDomainObject)); | ||||
|                 action.perform(); | ||||
|                 expect(mockActionCapability.perform).toHaveBeenCalledWith( | ||||
|                     "navigate" | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("prompts the user for object details", function () { | ||||
|                 action.perform(); | ||||
|                 expect(mockDialogService.getUserInput).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             describe("in order to keep the user in the loop", function () { | ||||
|                 var mockDialogHandle; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]); | ||||
|                     mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle); | ||||
|                 }); | ||||
|  | ||||
|                 it("shows a blocking dialog indicating that saving is in progress", function () { | ||||
|                     mockEditorCapability.save.and.returnValue(new Promise(function () {})); | ||||
|                     action.perform(); | ||||
|                     expect(mockDialogService.showBlockingMessage).toHaveBeenCalled(); | ||||
|                     expect(mockDialogHandle.dismiss).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|                 it("hides the blocking dialog after saving finishes", function () { | ||||
|                     return action.perform().then(function () { | ||||
|                         expect(mockDialogService.showBlockingMessage).toHaveBeenCalled(); | ||||
|                         expect(mockDialogHandle.dismiss).toHaveBeenCalled(); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("notifies if saving succeeded", function () { | ||||
|                     return action.perform().then(function () { | ||||
|                         expect(mockNotificationService.info).toHaveBeenCalled(); | ||||
|                         expect(mockNotificationService.error).not.toHaveBeenCalled(); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("notifies if saving failed", function () { | ||||
|                     mockCopyService.perform.and.returnValue(Promise.reject("some failure reason")); | ||||
|                     action.perform().then(function () { | ||||
|                         expect(mockNotificationService.error).toHaveBeenCalled(); | ||||
|                         expect(mockNotificationService.info).not.toHaveBeenCalled(); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,192 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../../src/capabilities/EditorCapability"], | ||||
|     function (EditorCapability) { | ||||
|  | ||||
|         xdescribe("The editor capability", function () { | ||||
|             var mockDomainObject, | ||||
|                 capabilities, | ||||
|                 mockParentObject, | ||||
|                 mockTransactionService, | ||||
|                 mockStatusCapability, | ||||
|                 mockParentStatus, | ||||
|                 mockContextCapability, | ||||
|                 capability; | ||||
|  | ||||
|             function fastPromise(val) { | ||||
|                 return { | ||||
|                     then: function (callback) { | ||||
|                         return callback(val); | ||||
|                     } | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     ["getId", "getModel", "hasCapability", "getCapability", "useCapability"] | ||||
|                 ); | ||||
|                 mockParentObject = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     ["getId", "getModel", "hasCapability", "getCapability", "useCapability"] | ||||
|                 ); | ||||
|                 mockTransactionService = jasmine.createSpyObj( | ||||
|                     "transactionService", | ||||
|                     [ | ||||
|                         "startTransaction", | ||||
|                         "size", | ||||
|                         "commit", | ||||
|                         "cancel" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockTransactionService.commit.and.returnValue(fastPromise()); | ||||
|                 mockTransactionService.cancel.and.returnValue(fastPromise()); | ||||
|                 mockTransactionService.isActive = jasmine.createSpy('isActive'); | ||||
|  | ||||
|                 mockStatusCapability = jasmine.createSpyObj( | ||||
|                     "statusCapability", | ||||
|                     ["get", "set"] | ||||
|                 ); | ||||
|                 mockParentStatus = jasmine.createSpyObj( | ||||
|                     "statusCapability", | ||||
|                     ["get", "set"] | ||||
|                 ); | ||||
|                 mockContextCapability = jasmine.createSpyObj( | ||||
|                     "contextCapability", | ||||
|                     ["getParent"] | ||||
|                 ); | ||||
|                 mockContextCapability.getParent.and.returnValue(mockParentObject); | ||||
|  | ||||
|                 capabilities = { | ||||
|                     context: mockContextCapability, | ||||
|                     status: mockStatusCapability | ||||
|                 }; | ||||
|  | ||||
|                 mockDomainObject.hasCapability.and.callFake(function (name) { | ||||
|                     return capabilities[name] !== undefined; | ||||
|                 }); | ||||
|  | ||||
|                 mockDomainObject.getCapability.and.callFake(function (name) { | ||||
|                     return capabilities[name]; | ||||
|                 }); | ||||
|  | ||||
|                 mockParentObject.getCapability.and.returnValue(mockParentStatus); | ||||
|                 mockParentObject.hasCapability.and.returnValue(false); | ||||
|  | ||||
|                 capability = new EditorCapability( | ||||
|                     mockTransactionService, | ||||
|                     mockDomainObject | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("starts a transaction when edit is invoked", function () { | ||||
|                 capability.edit(); | ||||
|                 expect(mockTransactionService.startTransaction).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("sets editing status on object", function () { | ||||
|                 capability.edit(); | ||||
|                 expect(mockStatusCapability.set).toHaveBeenCalledWith("editing", true); | ||||
|             }); | ||||
|  | ||||
|             it("uses editing status to determine editing context root", function () { | ||||
|                 capability.edit(); | ||||
|                 mockStatusCapability.get.and.returnValue(false); | ||||
|                 expect(capability.isEditContextRoot()).toBe(false); | ||||
|                 mockStatusCapability.get.and.returnValue(true); | ||||
|                 expect(capability.isEditContextRoot()).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             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); | ||||
|                 mockParentStatus.get.and.returnValue(true); | ||||
|                 expect(capability.inEditContext()).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             describe("save", function () { | ||||
|                 beforeEach(function () { | ||||
|                     capability.edit(); | ||||
|                     capability.save(); | ||||
|                 }); | ||||
|                 it("commits the transaction", function () { | ||||
|                     expect(mockTransactionService.commit).toHaveBeenCalled(); | ||||
|                 }); | ||||
|                 it("begins a new transaction", function () { | ||||
|                     expect(mockTransactionService.startTransaction).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("finish", function () { | ||||
|                 beforeEach(function () { | ||||
|                     mockTransactionService.isActive.and.returnValue(true); | ||||
|                     capability.edit(); | ||||
|                     capability.finish(); | ||||
|                 }); | ||||
|                 it("cancels the transaction", function () { | ||||
|                     expect(mockTransactionService.cancel).toHaveBeenCalled(); | ||||
|                 }); | ||||
|                 it("resets the edit state", function () { | ||||
|                     expect(mockStatusCapability.set).toHaveBeenCalledWith('editing', false); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("finish", function () { | ||||
|                 beforeEach(function () { | ||||
|                     mockTransactionService.isActive.and.returnValue(false); | ||||
|                     capability.edit(); | ||||
|                 }); | ||||
|  | ||||
|                 it("does not cancel transaction when transaction is not active", function () { | ||||
|                     capability.finish(); | ||||
|                     expect(mockTransactionService.cancel).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|                 it("returns a promise", function () { | ||||
|                     expect(capability.finish() instanceof Promise).toBe(true); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             describe("dirty", function () { | ||||
|                 var model = {}; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     mockDomainObject.getModel.and.returnValue(model); | ||||
|                     capability.edit(); | ||||
|                     capability.finish(); | ||||
|                 }); | ||||
|                 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); | ||||
|                     expect(capability.dirty()).toBe(true); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,186 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * MCTRepresentationSpec. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/creation/CreateAction"], | ||||
|     function (CreateAction) { | ||||
|  | ||||
|         xdescribe("The create action", function () { | ||||
|             var mockType, | ||||
|                 mockParent, | ||||
|                 mockContext, | ||||
|                 mockDomainObject, | ||||
|                 capabilities = {}, | ||||
|                 mockEditAction, | ||||
|                 action; | ||||
|  | ||||
|             function mockPromise(value) { | ||||
|                 return { | ||||
|                     then: function (callback) { | ||||
|                         return mockPromise(callback(value)); | ||||
|                     } | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockType = jasmine.createSpyObj( | ||||
|                     "type", | ||||
|                     [ | ||||
|                         "getKey", | ||||
|                         "getGlyph", | ||||
|                         "getCssClass", | ||||
|                         "getName", | ||||
|                         "getDescription", | ||||
|                         "getProperties", | ||||
|                         "getInitialModel" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockParent = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     [ | ||||
|                         "getId", | ||||
|                         "getModel", | ||||
|                         "getCapability", | ||||
|                         "useCapability" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     [ | ||||
|                         "getId", | ||||
|                         "getModel", | ||||
|                         "getCapability", | ||||
|                         "hasCapability", | ||||
|                         "useCapability" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockDomainObject.hasCapability.and.callFake(function (name) { | ||||
|                     return Boolean(capabilities[name]); | ||||
|                 }); | ||||
|                 mockDomainObject.getCapability.and.callFake(function (name) { | ||||
|                     return capabilities[name]; | ||||
|                 }); | ||||
|  | ||||
|                 capabilities.action = jasmine.createSpyObj( | ||||
|                     "actionCapability", | ||||
|                     [ | ||||
|                         "getActions", | ||||
|                         "perform" | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|                 capabilities.editor = jasmine.createSpyObj( | ||||
|                     "editorCapability", | ||||
|                     [ | ||||
|                         "edit", | ||||
|                         "save", | ||||
|                         "finish" | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|                 mockEditAction = jasmine.createSpyObj( | ||||
|                     "editAction", | ||||
|                     [ | ||||
|                         "perform" | ||||
|                     ] | ||||
|                 ); | ||||
|  | ||||
|                 mockContext = { | ||||
|                     domainObject: mockParent | ||||
|                 }; | ||||
|                 mockParent.useCapability.and.returnValue(mockDomainObject); | ||||
|  | ||||
|                 mockType.getKey.and.returnValue("test"); | ||||
|                 mockType.getCssClass.and.returnValue("icon-telemetry"); | ||||
|                 mockType.getDescription.and.returnValue("a test type"); | ||||
|                 mockType.getName.and.returnValue("Test"); | ||||
|                 mockType.getProperties.and.returnValue([]); | ||||
|                 mockType.getInitialModel.and.returnValue({}); | ||||
|  | ||||
|                 action = new CreateAction( | ||||
|                     mockType, | ||||
|                     mockParent, | ||||
|                     mockContext | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("exposes type-appropriate metadata", function () { | ||||
|                 var metadata = action.getMetadata(); | ||||
|  | ||||
|                 expect(metadata.name).toEqual("Test"); | ||||
|                 expect(metadata.description).toEqual("a test type"); | ||||
|                 expect(metadata.cssClass).toEqual("icon-telemetry"); | ||||
|             }); | ||||
|  | ||||
|             describe("the perform function", function () { | ||||
|                 var promise = jasmine.createSpyObj("promise", ["then"]); | ||||
|                 beforeEach(function () { | ||||
|                     capabilities.action.getActions.and.returnValue([mockEditAction]); | ||||
|                 }); | ||||
|  | ||||
|                 it("uses the instantiation capability when performed", function () { | ||||
|                     action.perform(); | ||||
|                     expect(mockParent.useCapability).toHaveBeenCalledWith("instantiation", jasmine.any(Object)); | ||||
|                 }); | ||||
|  | ||||
|                 it("uses the edit action if available", function () { | ||||
|                     action.perform(); | ||||
|                     expect(mockEditAction.perform).toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|                 it("uses the save-as action if object does not have an edit action" | ||||
|                     + " available", function () { | ||||
|                     capabilities.action.getActions.and.returnValue([]); | ||||
|                     capabilities.action.perform.and.returnValue(mockPromise(undefined)); | ||||
|                     capabilities.editor.save.and.returnValue(promise); | ||||
|                     action.perform(); | ||||
|                     expect(capabilities.action.perform).toHaveBeenCalledWith("save-as"); | ||||
|                 }); | ||||
|  | ||||
|                 describe("uses to editor capability", function () { | ||||
|                     beforeEach(function () { | ||||
|                         capabilities.action.getActions.and.returnValue([]); | ||||
|                         capabilities.action.perform.and.returnValue(promise); | ||||
|                         capabilities.editor.save.and.returnValue(promise); | ||||
|                     }); | ||||
|  | ||||
|                     it("to save the edit if user saves dialog", function () { | ||||
|                         action.perform(); | ||||
|                         expect(promise.then).toHaveBeenCalled(); | ||||
|                         promise.then.calls.mostRecent().args[0](); | ||||
|                         expect(capabilities.editor.save).toHaveBeenCalled(); | ||||
|                     }); | ||||
|  | ||||
|                     it("to finish the edit if user cancels dialog", function () { | ||||
|                         action.perform(); | ||||
|                         promise.then.calls.mostRecent().args[1](); | ||||
|                         expect(capabilities.editor.finish).toHaveBeenCalled(); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,197 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, 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. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| /** | ||||
|  * MCTRepresentationSpec. Created by vwoeltje on 11/6/14. | ||||
|  */ | ||||
| define( | ||||
|     ["../../src/creation/CreateWizard"], | ||||
|     function (CreateWizard) { | ||||
|  | ||||
|         xdescribe("The create wizard", function () { | ||||
|             var mockType, | ||||
|                 mockParent, | ||||
|                 mockProperties, | ||||
|                 mockPolicyService, | ||||
|                 testModel, | ||||
|                 mockDomainObject, | ||||
|                 wizard; | ||||
|  | ||||
|             function createMockProperty(name) { | ||||
|                 var mockProperty = jasmine.createSpyObj( | ||||
|                     "property" + name, | ||||
|                     ["getDefinition", "getValue", "setValue"] | ||||
|                 ); | ||||
|                 mockProperty.getDefinition.and.returnValue({ | ||||
|                     control: "textfield" | ||||
|                 }); | ||||
|                 mockProperty.getValue.and.returnValue(name); | ||||
|  | ||||
|                 return mockProperty; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockType = jasmine.createSpyObj( | ||||
|                     "type", | ||||
|                     [ | ||||
|                         "getKey", | ||||
|                         "getGlyph", | ||||
|                         "getCssClass", | ||||
|                         "getName", | ||||
|                         "getDescription", | ||||
|                         "getProperties", | ||||
|                         "getInitialModel" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockParent = jasmine.createSpyObj( | ||||
|                     "domainObject", | ||||
|                     [ | ||||
|                         "getId", | ||||
|                         "getModel", | ||||
|                         "getCapability" | ||||
|                     ] | ||||
|                 ); | ||||
|                 mockProperties = ["A", "B", "C"].map(createMockProperty); | ||||
|                 mockPolicyService = jasmine.createSpyObj('policyService', ['allow']); | ||||
|  | ||||
|                 testModel = { someKey: "some value" }; | ||||
|  | ||||
|                 mockType.getKey.and.returnValue("test"); | ||||
|                 mockType.getCssClass.and.returnValue("icon-telemetry"); | ||||
|                 mockType.getDescription.and.returnValue("a test type"); | ||||
|                 mockType.getName.and.returnValue("Test"); | ||||
|                 mockType.getInitialModel.and.returnValue(testModel); | ||||
|                 mockType.getProperties.and.returnValue(mockProperties); | ||||
|  | ||||
|                 mockDomainObject = jasmine.createSpyObj( | ||||
|                     'domainObject', | ||||
|                     ['getCapability', 'useCapability', 'getModel'] | ||||
|                 ); | ||||
|  | ||||
|                 //Mocking the getCapability('type') call | ||||
|                 mockDomainObject.getCapability.and.returnValue(mockType); | ||||
|                 mockDomainObject.useCapability.and.returnValue(); | ||||
|                 mockDomainObject.getModel.and.returnValue(testModel); | ||||
|  | ||||
|                 wizard = new CreateWizard( | ||||
|                     mockDomainObject, | ||||
|                     mockParent, | ||||
|                     mockPolicyService | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("creates a form model with a Properties section", function () { | ||||
|                 expect(wizard.getFormStructure().sections[0].name) | ||||
|                     .toEqual("Properties"); | ||||
|             }); | ||||
|  | ||||
|             it("adds one row per defined type property", function () { | ||||
|                 // Three properties were defined in the mock type | ||||
|                 expect(wizard.getFormStructure().sections[0].rows.length) | ||||
|                     .toEqual(3); | ||||
|             }); | ||||
|  | ||||
|             it("interprets form data using type-defined properties", function () { | ||||
|                 // Use key names from mock properties | ||||
|                 wizard.createModel([ | ||||
|                     "field 0", | ||||
|                     "field 1", | ||||
|                     "field 2" | ||||
|                 ]); | ||||
|  | ||||
|                 // Should have gotten a setValue call | ||||
|                 mockProperties.forEach(function (mockProperty, i) { | ||||
|                     expect(mockProperty.setValue).toHaveBeenCalledWith( | ||||
|                         { | ||||
|                             someKey: "some value", | ||||
|                             type: 'test' | ||||
|                         }, | ||||
|                         "field " + i | ||||
|                     ); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("looks up initial values from properties", function () { | ||||
|                 var initialValue = wizard.getInitialFormValue(); | ||||
|  | ||||
|                 expect(initialValue[0]).toEqual("A"); | ||||
|                 expect(initialValue[1]).toEqual("B"); | ||||
|                 expect(initialValue[2]).toEqual("C"); | ||||
|  | ||||
|                 // Verify that expected argument was passed | ||||
|                 mockProperties.forEach(function (mockProperty) { | ||||
|                     expect(mockProperty.getValue) | ||||
|                         .toHaveBeenCalledWith(testModel); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("populates the model on the associated object", function () { | ||||
|                 var formValue = { | ||||
|                         "A": "ValueA", | ||||
|                         "B": "ValueB", | ||||
|                         "C": "ValueC" | ||||
|                     }, | ||||
|                     compareModel = wizard.createModel(formValue); | ||||
|                 //populateObjectFromInput adds a .location attribute that is not added by createModel. | ||||
|                 compareModel.location = undefined; | ||||
|                 wizard.populateObjectFromInput(formValue); | ||||
|                 expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function)); | ||||
|                 expect(mockDomainObject.useCapability.calls.mostRecent().args[1]()).toEqual(compareModel); | ||||
|             }); | ||||
|  | ||||
|             it("validates selection types using policy", function () { | ||||
|                 var mockDomainObj = jasmine.createSpyObj( | ||||
|                         'domainObject', | ||||
|                         ['getCapability'] | ||||
|                     ), | ||||
|                     mockOtherType = jasmine.createSpyObj( | ||||
|                         'otherType', | ||||
|                         ['getKey'] | ||||
|                     ), | ||||
|  | ||||
|                     //Create a form structure with location | ||||
|                     structure = wizard.getFormStructure(true), | ||||
|                     sections = structure.sections, | ||||
|                     rows = structure.sections[sections.length - 1].rows, | ||||
|                     locationRow = rows[rows.length - 1]; | ||||
|  | ||||
|                 mockDomainObj.getCapability.and.returnValue(mockOtherType); | ||||
|                 locationRow.validate(mockDomainObj); | ||||
|  | ||||
|                 // Should check policy to see if the user-selected location | ||||
|                 // can actually contain objects of this type | ||||
|                 expect(mockPolicyService.allow).toHaveBeenCalledWith( | ||||
|                     'composition', | ||||
|                     mockDomainObj, | ||||
|                     mockDomainObject | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("creates a form model without a location if not requested", function () { | ||||
|                 expect(wizard.getFormStructure(false).sections.some(function (section) { | ||||
|                     return section.name === 'Location'; | ||||
|                 })).toEqual(false); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -1,290 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     '../../src/ui/TreeView', | ||||
|     'zepto' | ||||
| ], function (TreeView, $) { | ||||
|  | ||||
|     xdescribe("TreeView", function () { | ||||
|         var mockGestureService, | ||||
|             mockGestureHandle, | ||||
|             mockDomainObject, | ||||
|             mockMutation, | ||||
|             mockUnlisten, | ||||
|             testCapabilities, | ||||
|             treeView; | ||||
|  | ||||
|         function makeMockDomainObject(id, model, capabilities) { | ||||
|             var mockDomainObj = jasmine.createSpyObj( | ||||
|                 'domainObject-' + id, | ||||
|                 [ | ||||
|                     'getId', | ||||
|                     'getModel', | ||||
|                     'getCapability', | ||||
|                     'hasCapability', | ||||
|                     'useCapability' | ||||
|                 ] | ||||
|             ); | ||||
|             mockDomainObj.getId.and.returnValue(id); | ||||
|             mockDomainObj.getModel.and.returnValue(model); | ||||
|             mockDomainObj.hasCapability.and.callFake(function (c) { | ||||
|                 return Boolean(capabilities[c]); | ||||
|             }); | ||||
|             mockDomainObj.getCapability.and.callFake(function (c) { | ||||
|                 return capabilities[c]; | ||||
|             }); | ||||
|             mockDomainObj.useCapability.and.callFake(function (c) { | ||||
|                 return capabilities[c] && capabilities[c].invoke(); | ||||
|             }); | ||||
|  | ||||
|             return mockDomainObj; | ||||
|         } | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             mockGestureService = jasmine.createSpyObj( | ||||
|                 'gestureService', | ||||
|                 ['attachGestures'] | ||||
|             ); | ||||
|  | ||||
|             mockGestureHandle = jasmine.createSpyObj('gestures', ['destroy']); | ||||
|  | ||||
|             mockGestureService.attachGestures.and.returnValue(mockGestureHandle); | ||||
|  | ||||
|             mockMutation = jasmine.createSpyObj('mutation', ['listen']); | ||||
|             mockUnlisten = jasmine.createSpy('unlisten'); | ||||
|             mockMutation.listen.and.returnValue(mockUnlisten); | ||||
|  | ||||
|             testCapabilities = { mutation: mockMutation }; | ||||
|  | ||||
|             mockDomainObject = | ||||
|                 makeMockDomainObject('parent', {}, testCapabilities); | ||||
|  | ||||
|             treeView = new TreeView(mockGestureService); | ||||
|         }); | ||||
|  | ||||
|         describe("elements", function () { | ||||
|             var elements; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 elements = treeView.elements(); | ||||
|             }); | ||||
|  | ||||
|             it("is an unordered list", function () { | ||||
|                 expect(elements[0].tagName.toLowerCase()) | ||||
|                     .toEqual('ul'); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         describe("model", function () { | ||||
|             var mockComposition; | ||||
|  | ||||
|             function makeGenericCapabilities() { | ||||
|                 var mockStatus = | ||||
|                         jasmine.createSpyObj('status', ['listen', 'list']); | ||||
|  | ||||
|                 mockStatus.list.and.returnValue([]); | ||||
|  | ||||
|                 return { | ||||
|                     context: jasmine.createSpyObj('context', ['getPath']), | ||||
|                     type: jasmine.createSpyObj('type', ['getCssClass']), | ||||
|                     location: jasmine.createSpyObj('location', ['isLink']), | ||||
|                     mutation: jasmine.createSpyObj('mutation', ['listen']), | ||||
|                     status: mockStatus | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockComposition = ['a', 'b', 'c'].map(function (id) { | ||||
|                     var testCaps = makeGenericCapabilities(), | ||||
|                         mockChild = | ||||
|                             makeMockDomainObject(id, {}, testCaps); | ||||
|  | ||||
|                     testCaps.context.getPath | ||||
|                         .and.returnValue([mockDomainObject, mockChild]); | ||||
|  | ||||
|                     return mockChild; | ||||
|                 }); | ||||
|  | ||||
|                 testCapabilities.composition = | ||||
|                     jasmine.createSpyObj('composition', ['invoke']); | ||||
|                 testCapabilities.composition.invoke | ||||
|                     .and.returnValue(Promise.resolve(mockComposition)); | ||||
|  | ||||
|                 treeView.model(mockDomainObject); | ||||
|  | ||||
|                 return testCapabilities.composition.invoke(); | ||||
|             }); | ||||
|  | ||||
|             it("adds one node per composition element", function () { | ||||
|                 expect(treeView.elements()[0].childElementCount) | ||||
|                     .toEqual(mockComposition.length); | ||||
|             }); | ||||
|  | ||||
|             it("listens for mutation", function () { | ||||
|                 expect(testCapabilities.mutation.listen) | ||||
|                     .toHaveBeenCalledWith(jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             describe("when mutation occurs", function () { | ||||
|                 beforeEach(function () { | ||||
|                     mockComposition.pop(); | ||||
|                     testCapabilities.mutation.listen | ||||
|                         .calls.mostRecent().args[0](mockDomainObject.getModel()); | ||||
|  | ||||
|                     return testCapabilities.composition.invoke(); | ||||
|                 }); | ||||
|  | ||||
|                 it("continues to show one node per composition element", function () { | ||||
|                     expect(treeView.elements()[0].childElementCount) | ||||
|                         .toEqual(mockComposition.length); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("when replaced with a non-compositional domain object", function () { | ||||
|                 beforeEach(function () { | ||||
|                     delete testCapabilities.composition; | ||||
|                     treeView.model(mockDomainObject); | ||||
|                 }); | ||||
|  | ||||
|                 it("stops listening for mutation", function () { | ||||
|                     expect(mockUnlisten).toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|                 it("removes all tree nodes", function () { | ||||
|                     expect(treeView.elements()[0].childElementCount) | ||||
|                         .toEqual(0); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("when selection state changes", function () { | ||||
|                 var selectionIndex = 1; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     treeView.value(mockComposition[selectionIndex]); | ||||
|                 }); | ||||
|  | ||||
|                 it("communicates selection state to an appropriate node", function () { | ||||
|                     var selected = $(treeView.elements()[0]).find('.selected'); | ||||
|                     expect(selected.length).toEqual(1); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("when a context-less object is selected", function () { | ||||
|                 beforeEach(function () { | ||||
|                     var testCaps = makeGenericCapabilities(), | ||||
|                         mockDomainObj = | ||||
|                             makeMockDomainObject('xyz', {}, testCaps); | ||||
|                     delete testCaps.context; | ||||
|                     treeView.value(mockDomainObj); | ||||
|                 }); | ||||
|  | ||||
|                 it("clears all selection state", function () { | ||||
|                     var selected = $(treeView.elements()[0]).find('.selected'); | ||||
|                     expect(selected.length).toEqual(0); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("when children contain children", function () { | ||||
|                 beforeEach(function () { | ||||
|                     var newCapabilities = makeGenericCapabilities(), | ||||
|                         gcCapabilities = makeGenericCapabilities(), | ||||
|                         mockNewChild = | ||||
|                             makeMockDomainObject('d', {}, newCapabilities), | ||||
|                         mockGrandchild = | ||||
|                             makeMockDomainObject('gc', {}, gcCapabilities); | ||||
|  | ||||
|                     newCapabilities.composition = | ||||
|                         jasmine.createSpyObj('composition', ['invoke']); | ||||
|                     newCapabilities.composition.invoke | ||||
|                         .and.returnValue(Promise.resolve([mockGrandchild])); | ||||
|                     mockComposition.push(mockNewChild); | ||||
|  | ||||
|                     newCapabilities.context.getPath.and.returnValue([ | ||||
|                         mockDomainObject, | ||||
|                         mockNewChild | ||||
|                     ]); | ||||
|                     gcCapabilities.context.getPath.and.returnValue([ | ||||
|                         mockDomainObject, | ||||
|                         mockNewChild, | ||||
|                         mockGrandchild | ||||
|                     ]); | ||||
|  | ||||
|                     testCapabilities.mutation.listen | ||||
|                         .calls.mostRecent().args[0](mockDomainObject); | ||||
|  | ||||
|                     return testCapabilities.composition.invoke().then(function () { | ||||
|                         treeView.value(mockGrandchild); | ||||
|  | ||||
|                         return newCapabilities.composition.invoke(); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("creates inner trees", function () { | ||||
|                     expect($(treeView.elements()[0]).find('ul').length) | ||||
|                         .toEqual(1); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("when status changes", function () { | ||||
|                 var testStatuses; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     var mockStatus = mockComposition[1].getCapability('status'); | ||||
|  | ||||
|                     testStatuses = ['foo']; | ||||
|  | ||||
|                     mockStatus.list.and.returnValue(testStatuses); | ||||
|                     mockStatus.listen.calls.mostRecent().args[0](testStatuses); | ||||
|                 }); | ||||
|  | ||||
|                 it("reflects the status change in the tree", function () { | ||||
|                     expect($(treeView.elements()).find('.s-status-foo').length) | ||||
|                         .toEqual(1); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         describe("observe", function () { | ||||
|             var mockCallback, | ||||
|                 unobserve; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockCallback = jasmine.createSpy('callback'); | ||||
|                 unobserve = treeView.observe(mockCallback); | ||||
|             }); | ||||
|  | ||||
|             it("notifies listeners when value is changed", function () { | ||||
|                 treeView.value(mockDomainObject, {some: event}); | ||||
|                 expect(mockCallback) | ||||
|                     .toHaveBeenCalledWith(mockDomainObject, {some: event}); | ||||
|             }); | ||||
|  | ||||
|             it("does not notify listeners when deactivated", function () { | ||||
|                 unobserve(); | ||||
|                 treeView.value(mockDomainObject); | ||||
|                 expect(mockCallback).not.toHaveBeenCalled(); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
| @@ -1,95 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2021, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ["../src/ComposeActionPolicy"], | ||||
|     function (ComposeActionPolicy) { | ||||
|         xdescribe("The compose action policy", function () { | ||||
|             var mockInjector, | ||||
|                 mockPolicyService, | ||||
|                 mockTypes, | ||||
|                 mockDomainObjects, | ||||
|                 mockAction, | ||||
|                 testContext, | ||||
|                 policy; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockInjector = jasmine.createSpyObj('$injector', ['get']); | ||||
|                 mockPolicyService = jasmine.createSpyObj( | ||||
|                     'policyService', | ||||
|                     ['allow'] | ||||
|                 ); | ||||
|                 mockTypes = ['a', 'b'].map(function (type) { | ||||
|                     var mockType = jasmine.createSpyObj('type-' + type, ['getKey']); | ||||
|                     mockType.getKey.and.returnValue(type); | ||||
|  | ||||
|                     return mockType; | ||||
|                 }); | ||||
|                 mockDomainObjects = ['a', 'b'].map(function (id, index) { | ||||
|                     var mockDomainObject = jasmine.createSpyObj( | ||||
|                         'domainObject-' + id, | ||||
|                         ['getId', 'getCapability'] | ||||
|                     ); | ||||
|                     mockDomainObject.getId.and.returnValue(id); | ||||
|                     mockDomainObject.getCapability.and.callFake(function (c) { | ||||
|                         return c === 'type' && mockTypes[index]; | ||||
|                     }); | ||||
|  | ||||
|                     return mockDomainObject; | ||||
|                 }); | ||||
|                 mockAction = jasmine.createSpyObj('action', ['getMetadata']); | ||||
|  | ||||
|                 testContext = { | ||||
|                     key: 'compose', | ||||
|                     domainObject: mockDomainObjects[0], | ||||
|                     selectedObject: mockDomainObjects[1] | ||||
|                 }; | ||||
|  | ||||
|                 mockAction.getMetadata.and.returnValue(testContext); | ||||
|                 mockInjector.get.and.callFake(function (service) { | ||||
|                     return service === 'policyService' && mockPolicyService; | ||||
|                 }); | ||||
|  | ||||
|                 policy = new ComposeActionPolicy(mockInjector); | ||||
|             }); | ||||
|  | ||||
|             it("defers to composition policy", function () { | ||||
|                 mockPolicyService.allow.and.returnValue(false); | ||||
|                 expect(policy.allow(mockAction, testContext)).toBeFalsy(); | ||||
|                 mockPolicyService.allow.and.returnValue(true); | ||||
|                 expect(policy.allow(mockAction, testContext)).toBeTruthy(); | ||||
|  | ||||
|                 expect(mockPolicyService.allow).toHaveBeenCalledWith( | ||||
|                     'composition', | ||||
|                     mockDomainObjects[0], | ||||
|                     mockDomainObjects[1] | ||||
|                 ); | ||||
|             }); | ||||
|  | ||||
|             it("allows actions other than compose", function () { | ||||
|                 testContext.key = 'somethingElse'; | ||||
|                 mockPolicyService.allow.and.returnValue(false); | ||||
|                 expect(policy.allow(mockAction, testContext)).toBeTruthy(); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -89,7 +89,8 @@ define([ | ||||
|                         "implementation": TickerService, | ||||
|                         "depends": [ | ||||
|                             "$timeout", | ||||
|                             "now" | ||||
|                             "now", | ||||
|                             "$rootScope" | ||||
|                         ] | ||||
|                     }, | ||||
|                     { | ||||
|   | ||||
| @@ -32,8 +32,13 @@ define( | ||||
|          * @param $timeout Angular's $timeout | ||||
|          * @param {Function} now function to provide the current time in ms | ||||
|          */ | ||||
|         function TickerService($timeout, now) { | ||||
|         function TickerService($timeout, now, $rootScope) { | ||||
|             var self = this; | ||||
|             var timeoutId; | ||||
|  | ||||
|             $rootScope.$on('$destroy', function () { | ||||
|                 $timeout.cancel(timeoutId); | ||||
|             }); | ||||
|  | ||||
|             function tick() { | ||||
|                 var timestamp = now(), | ||||
| @@ -48,7 +53,7 @@ define( | ||||
|                 } | ||||
|  | ||||
|                 // Try to update at exactly the next second | ||||
|                 $timeout(tick, 1000 - millis, true); | ||||
|                 timeoutId = $timeout(tick, 1000 - millis, true); | ||||
|             } | ||||
|  | ||||
|             tick(); | ||||
|   | ||||
| @@ -30,16 +30,18 @@ define( | ||||
|             var mockTimeout, | ||||
|                 mockNow, | ||||
|                 mockCallback, | ||||
|                 tickerService; | ||||
|                 tickerService, | ||||
|                 mockRootScope; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockTimeout = jasmine.createSpy('$timeout'); | ||||
|                 mockNow = jasmine.createSpy('now'); | ||||
|                 mockCallback = jasmine.createSpy('callback'); | ||||
|                 mockRootScope = jasmine.createSpyObj('rootScope', ['$on']); | ||||
|  | ||||
|                 mockNow.and.returnValue(TEST_TIMESTAMP); | ||||
|  | ||||
|                 tickerService = new TickerService(mockTimeout, mockNow); | ||||
|                 tickerService = new TickerService(mockTimeout, mockNow, mockRootScope); | ||||
|             }); | ||||
|  | ||||
|             it("notifies listeners of clock ticks", function () { | ||||
|   | ||||
| @@ -58,7 +58,7 @@ define([ | ||||
|     ) { | ||||
|         var $http = this.$http, | ||||
|             $log = this.$log, | ||||
|             app = angular.module(Constants.MODULE_NAME, ["ngRoute"]), | ||||
|             app = angular.module(Constants.MODULE_NAME, []), | ||||
|             loader = new BundleLoader($http, $log, openmct.legacyRegistry), | ||||
|             resolver = new BundleResolver( | ||||
|                 new ExtensionResolver( | ||||
|   | ||||
| @@ -28,8 +28,7 @@ | ||||
| define( | ||||
|     [ | ||||
|         './FrameworkLayer', | ||||
|         'angular', | ||||
|         'angular-route' | ||||
|         'angular' | ||||
|     ], | ||||
|     function ( | ||||
|         FrameworkLayer, | ||||
|   | ||||
| @@ -138,34 +138,6 @@ define( | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Custom registration function for extensions of category "route" | ||||
|         function registerRoute(extension) { | ||||
|             var app = this.app, | ||||
|                 $log = this.$log, | ||||
|                 route = Object.create(extension); | ||||
|  | ||||
|             // Adjust path for bundle | ||||
|             if (route.templateUrl) { | ||||
|                 route.templateUrl = [ | ||||
|                     route.bundle.path, | ||||
|                     route.bundle.resources, | ||||
|                     route.templateUrl | ||||
|                 ].join(Constants.SEPARATOR); | ||||
|             } | ||||
|  | ||||
|             // Log the registration | ||||
|             $log.info("Registering route: " + (route.key || route.when)); | ||||
|  | ||||
|             // Register the route with Angular | ||||
|             app.config(['$routeProvider', function ($routeProvider) { | ||||
|                 if (route.when) { | ||||
|                     $routeProvider.when(route.when, route); | ||||
|                 } else { | ||||
|                     $routeProvider.otherwise(route); | ||||
|                 } | ||||
|             }]); | ||||
|         } | ||||
|  | ||||
|         // Handle service compositing | ||||
|         function registerComponents(components) { | ||||
|             var app = this.app, | ||||
| @@ -194,13 +166,6 @@ define( | ||||
|         CustomRegistrars.prototype.constants = | ||||
|             mapUpon(registerConstant); | ||||
|  | ||||
|         /** | ||||
|          * Register Angular routes. | ||||
|          * @param {Array} extensions the resolved extensions | ||||
|          */ | ||||
|         CustomRegistrars.prototype.routes = | ||||
|             mapUpon(registerRoute); | ||||
|  | ||||
|         /** | ||||
|          * Register Angular directives. | ||||
|          * @param {Array} extensions the resolved extensions | ||||
|   | ||||
| @@ -57,7 +57,6 @@ define( | ||||
|                 expect(customRegistrars.directives).toBeTruthy(); | ||||
|                 expect(customRegistrars.controllers).toBeTruthy(); | ||||
|                 expect(customRegistrars.services).toBeTruthy(); | ||||
|                 expect(customRegistrars.routes).toBeTruthy(); | ||||
|                 expect(customRegistrars.constants).toBeTruthy(); | ||||
|                 expect(customRegistrars.runs).toBeTruthy(); | ||||
|             }); | ||||
| @@ -139,47 +138,6 @@ define( | ||||
|                 expect(mockLog.warn.calls.count()).toEqual(0); | ||||
|             }); | ||||
|  | ||||
|             it("allows routes to be registered", function () { | ||||
|                 var mockRouteProvider = jasmine.createSpyObj( | ||||
|                         "$routeProvider", | ||||
|                         ["when", "otherwise"] | ||||
|                     ), | ||||
|                     bundle = { | ||||
|                         path: "test/bundle", | ||||
|                         resources: "res" | ||||
|                     }, | ||||
|                     routes = [ | ||||
|                         { | ||||
|                             when: "foo", | ||||
|                             templateUrl: "templates/test.html", | ||||
|                             bundle: bundle | ||||
|                         }, | ||||
|                         { | ||||
|                             templateUrl: "templates/default.html", | ||||
|                             bundle: bundle | ||||
|                         } | ||||
|                     ]; | ||||
|  | ||||
|                 customRegistrars.routes(routes); | ||||
|  | ||||
|                 // Give it the route provider based on its config call | ||||
|                 mockApp.config.calls.all().forEach(function (call) { | ||||
|                     // Invoke the provided callback | ||||
|                     call.args[0][1](mockRouteProvider); | ||||
|                 }); | ||||
|  | ||||
|                 // The "when" clause should have been mapped to the when method... | ||||
|                 expect(mockRouteProvider.when).toHaveBeenCalled(); | ||||
|                 expect(mockRouteProvider.when.calls.mostRecent().args[0]).toEqual("foo"); | ||||
|                 expect(mockRouteProvider.when.calls.mostRecent().args[1].templateUrl) | ||||
|                     .toEqual("test/bundle/res/templates/test.html"); | ||||
|  | ||||
|                 // ...while the other should have been treated as a default route | ||||
|                 expect(mockRouteProvider.otherwise).toHaveBeenCalled(); | ||||
|                 expect(mockRouteProvider.otherwise.calls.mostRecent().args[0].templateUrl) | ||||
|                     .toEqual("test/bundle/res/templates/default.html"); | ||||
|             }); | ||||
|  | ||||
|             it("accepts components for service compositing", function () { | ||||
|                 // Most relevant code will be exercised in service compositor spec | ||||
|                 expect(customRegistrars.components).toBeTruthy(); | ||||
|   | ||||
| @@ -110,8 +110,15 @@ define([ | ||||
|             worker = workerService.run('bareBonesSearchWorker'); | ||||
|         } | ||||
|  | ||||
|         worker.addEventListener('message', function (messageEvent) { | ||||
|         function handleWorkerMessage(messageEvent) { | ||||
|             provider.onWorkerMessage(messageEvent); | ||||
|         } | ||||
|  | ||||
|         worker.addEventListener('message', handleWorkerMessage); | ||||
|  | ||||
|         this.openmct.once('destroy', () => { | ||||
|             worker.removeEventListener('message', handleWorkerMessage); | ||||
|             worker.terminate(); | ||||
|         }); | ||||
|  | ||||
|         return worker; | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/MCT.js
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/MCT.js
									
									
									
									
									
								
							| @@ -31,7 +31,6 @@ define([ | ||||
|     'objectUtils', | ||||
|     './plugins/plugins', | ||||
|     './adapter/indicators/legacy-indicators-plugin', | ||||
|     './plugins/buildInfo/plugin', | ||||
|     './ui/registries/ViewRegistry', | ||||
|     './plugins/imagery/plugin', | ||||
|     './ui/registries/InspectorViewRegistry', | ||||
| @@ -40,6 +39,7 @@ define([ | ||||
|     './ui/router/Browse', | ||||
|     '../platform/framework/src/Main', | ||||
|     './ui/layout/Layout.vue', | ||||
|     './ui/inspector/styles/StylesManager', | ||||
|     '../platform/core/src/objects/DomainObjectImpl', | ||||
|     '../platform/core/src/capabilities/ContextualDomainObject', | ||||
|     './ui/preview/plugin', | ||||
| @@ -60,7 +60,6 @@ define([ | ||||
|     objectUtils, | ||||
|     plugins, | ||||
|     LegacyIndicatorsPlugin, | ||||
|     buildInfoPlugin, | ||||
|     ViewRegistry, | ||||
|     ImageryPlugin, | ||||
|     InspectorViewRegistry, | ||||
| @@ -69,6 +68,7 @@ define([ | ||||
|     Browse, | ||||
|     Main, | ||||
|     Layout, | ||||
|     stylesManager, | ||||
|     DomainObjectImpl, | ||||
|     ContextualDomainObject, | ||||
|     PreviewPlugin, | ||||
| @@ -123,6 +123,7 @@ define([ | ||||
|         }; | ||||
|  | ||||
|         this.destroy = this.destroy.bind(this); | ||||
|  | ||||
|         /** | ||||
|          * Tracks current selection state of the application. | ||||
|          * @private | ||||
| @@ -376,6 +377,7 @@ define([ | ||||
|      *        MCT; if undefined, MCT will be run in the body of the document | ||||
|      */ | ||||
|     MCT.prototype.start = function (domElement = document.body, isHeadlessMode = false) { | ||||
|  | ||||
|         if (this.types.get('layout') === undefined) { | ||||
|             this.install(this.plugins.DisplayLayout({ | ||||
|                 showAsView: ['summary-widget'] | ||||
| @@ -434,6 +436,9 @@ define([ | ||||
|                     domElement.appendChild(appLayout.$mount().$el); | ||||
|  | ||||
|                     this.layout = appLayout.$refs.layout; | ||||
|                     this.once('destroy', () => { | ||||
|                         appLayout.$destroy(); | ||||
|                     }); | ||||
|                     Browse(this); | ||||
|                 } | ||||
|  | ||||
| @@ -462,9 +467,40 @@ define([ | ||||
|     }; | ||||
|  | ||||
|     MCT.prototype.destroy = function () { | ||||
|         if (this._destroyed === true) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         window.removeEventListener('beforeunload', this.destroy); | ||||
|  | ||||
|         this.emit('destroy'); | ||||
|         this.router.destroy(); | ||||
|         this.removeAllListeners(); | ||||
|  | ||||
|         if (this.$injector) { | ||||
|             this.$injector.get('$rootScope').$destroy(); | ||||
|             this.$injector = null; | ||||
|         } | ||||
|  | ||||
|         if (this.$angular) { | ||||
|             this.$angular.element(this.element).off().removeData(); | ||||
|             this.$angular.element(this.element).empty(); | ||||
|             this.$angular = null; | ||||
|         } | ||||
|  | ||||
|         this.overlays.destroy(); | ||||
|  | ||||
|         if (this.element) { | ||||
|             this.element.remove(); | ||||
|         } | ||||
|  | ||||
|         stylesManager.default.removeAllListeners(); | ||||
|  | ||||
|         window.angular = null; | ||||
|         window.openmct = null; | ||||
|  | ||||
|         Object.keys(require.cache).forEach(key => delete require.cache[key]); | ||||
|  | ||||
|         this._destroyed = true; | ||||
|     }; | ||||
|  | ||||
|     MCT.prototype.plugins = plugins; | ||||
|   | ||||
| @@ -32,6 +32,10 @@ define([ | ||||
|     // cannot be injected. | ||||
|     function AlternateCompositionInitializer(openmct) { | ||||
|         AlternateCompositionCapability.appliesTo = function (model, id) { | ||||
|             openmct.once('destroy', () => { | ||||
|                 delete AlternateCompositionCapability.appliesTo; | ||||
|             }); | ||||
|  | ||||
|             model = objectUtils.toNewFormat(model, id || ''); | ||||
|  | ||||
|             return Boolean(openmct.composition.get(model)); | ||||
|   | ||||
| @@ -28,6 +28,10 @@ export default class Editor extends EventEmitter { | ||||
|         super(); | ||||
|         this.editing = false; | ||||
|         this.openmct = openmct; | ||||
|  | ||||
|         openmct.once('destroy', () => { | ||||
|             this.removeAllListeners(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -44,7 +44,15 @@ describe('The ActionCollection', () => { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         openmct.$injector.get.and.returnValue(mockIdentifierService); | ||||
|         openmct.$injector.get.and.callFake((key) => { | ||||
|             return { | ||||
|                 'identifierService': mockIdentifierService, | ||||
|                 '$rootScope': { | ||||
|                     '$destroy': () => {} | ||||
|                 } | ||||
|             }[key]; | ||||
|         }); | ||||
|  | ||||
|         mockObjectPath = [ | ||||
|             { | ||||
|                 name: 'mock folder', | ||||
|   | ||||
| @@ -17,11 +17,7 @@ class OverlayAPI { | ||||
|  | ||||
|         this.dismissLastOverlay = this.dismissLastOverlay.bind(this); | ||||
|  | ||||
|         document.addEventListener('keyup', (event) => { | ||||
|             if (event.key === 'Escape') { | ||||
|                 this.dismissLastOverlay(); | ||||
|             } | ||||
|         }); | ||||
|         document.addEventListener('keyup', this.dismissLastOverlay); | ||||
|  | ||||
|     } | ||||
|  | ||||
| @@ -49,10 +45,12 @@ class OverlayAPI { | ||||
|     /** | ||||
|      * private | ||||
|      */ | ||||
|     dismissLastOverlay() { | ||||
|         let lastOverlay = this.activeOverlays[this.activeOverlays.length - 1]; | ||||
|         if (lastOverlay && lastOverlay.dismissable) { | ||||
|             lastOverlay.dismiss(); | ||||
|     dismissLastOverlay(event) { | ||||
|         if (event.key === 'Escape') { | ||||
|             let lastOverlay = this.activeOverlays[this.activeOverlays.length - 1]; | ||||
|             if (lastOverlay && lastOverlay.dismissable) { | ||||
|                 lastOverlay.dismiss(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -60,7 +58,7 @@ class OverlayAPI { | ||||
|      * A description of option properties that can be passed into the overlay | ||||
|      * @typedef options | ||||
|         * @property {object} element DOMElement that is to be inserted/shown on the overlay | ||||
|         * @property {string} size preferred size of the overlay (large, small, fit) | ||||
|         * @property {string} size prefered size of the overlay (large, small, fit) | ||||
|         * @property {array} buttons optional button objects with label and callback properties | ||||
|         * @property {function} onDestroy callback to be called when overlay is destroyed | ||||
|         * @property {boolean} dismissable allow user to dismiss overlay by using esc, and clicking away | ||||
| @@ -129,6 +127,10 @@ class OverlayAPI { | ||||
|         return progressDialog; | ||||
|     } | ||||
|  | ||||
|     destroy() { | ||||
|         document.removeEventListener('keyup', this.dismissLastOverlay); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| export default OverlayAPI; | ||||
|   | ||||
| @@ -32,6 +32,10 @@ export default class StatusAPI extends EventEmitter { | ||||
|         this.get = this.get.bind(this); | ||||
|         this.set = this.set.bind(this); | ||||
|         this.observe = this.observe.bind(this); | ||||
|  | ||||
|         openmct.once('destroy', () => { | ||||
|             this.removeAllListeners(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     get(identifier) { | ||||
|   | ||||
| @@ -97,7 +97,7 @@ describe('Telemetry API', function () { | ||||
|             expect(telemetryProvider.subscribe).not.toHaveBeenCalled(); | ||||
|             expect(unsubscribe).toEqual(jasmine.any(Function)); | ||||
|  | ||||
|             telemetryAPI.request(domainObject).then((response) => { | ||||
|             return telemetryAPI.request(domainObject).then((response) => { | ||||
|                 expect(telemetryProvider.supportsRequest) | ||||
|                     .toHaveBeenCalledWith(domainObject, jasmine.any(Object)); | ||||
|                 expect(telemetryProvider.request).not.toHaveBeenCalled(); | ||||
|   | ||||
| @@ -75,7 +75,16 @@ describe("the plugin", () => { | ||||
|  | ||||
|             mockDialogService.getUserInput.and.returnValue(mockPromise); | ||||
|  | ||||
|             spyOn(openmct.$injector, 'get').and.returnValue(mockDialogService); | ||||
|             spyOn(openmct.$injector, 'get'); | ||||
|             openmct.$injector.get.and.callFake((key) => { | ||||
|                 return { | ||||
|                     'dialogService': mockDialogService, | ||||
|                     '$rootScope': { | ||||
|                         '$destroy': () => {} | ||||
|                     } | ||||
|                 }[key]; | ||||
|             }); | ||||
|  | ||||
|             spyOn(compositionAPI, 'get').and.returnValue(mockComposition); | ||||
|             spyOn(openmct.objects, 'save').and.returnValue(Promise.resolve(true)); | ||||
|  | ||||
|   | ||||
| @@ -117,6 +117,10 @@ export default function NotebookPlugin() { | ||||
|             key: 'notebook-snapshot-indicator' | ||||
|         }; | ||||
|  | ||||
|         openmct.once('destroy', () => { | ||||
|             snapshotContainer.destroy(); | ||||
|         }); | ||||
|  | ||||
|         openmct.indicators.add(indicator); | ||||
|  | ||||
|         openmct.objectViews.addProvider({ | ||||
|   | ||||
| @@ -80,4 +80,8 @@ export default class SnapshotContainer extends EventEmitter { | ||||
|  | ||||
|         return this.saveSnapshots(updatedSnapshots); | ||||
|     } | ||||
|  | ||||
|     destroy() { | ||||
|         delete SnapshotContainer.instance; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -22,95 +22,109 @@ | ||||
| import * as NotebookEntries from './notebook-entries'; | ||||
| import { createOpenMct, resetApplicationState } from 'utils/testing'; | ||||
|  | ||||
| const notebookStorage = { | ||||
|     name: 'notebook', | ||||
|     identifier: { | ||||
|         namespace: '', | ||||
|         key: 'test-notebook' | ||||
|     }, | ||||
|     defaultSectionId: '03a79b6a-971c-4e56-9892-ec536332c3f0', | ||||
|     defaultPageId: '8b548fd9-2b8a-4b02-93a9-4138e22eba00' | ||||
| }; | ||||
|  | ||||
| const notebookEntries = { | ||||
|     '03a79b6a-971c-4e56-9892-ec536332c3f0': { | ||||
|         '8b548fd9-2b8a-4b02-93a9-4138e22eba00': [] | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const notebookDomainObject = { | ||||
|     identifier: { | ||||
|         key: 'notebook', | ||||
|         namespace: '' | ||||
|     }, | ||||
|     type: 'notebook', | ||||
|     configuration: { | ||||
|         defaultSort: 'oldest', | ||||
|         entries: notebookEntries, | ||||
|         pageTitle: 'Page', | ||||
|         sections: [], | ||||
|         sectionTitle: 'Section', | ||||
|         type: 'General' | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const selectedSection = { | ||||
|     id: '03a79b6a-971c-4e56-9892-ec536332c3f0', | ||||
|     isDefault: false, | ||||
|     isSelected: true, | ||||
|     name: 'Day 1', | ||||
|     pages: [ | ||||
|         { | ||||
|             id: '54deb3d5-8267-4be4-95e9-3579ed8c082d', | ||||
|             isDefault: false, | ||||
|             isSelected: false, | ||||
|             name: 'Shift 1', | ||||
|             pageTitle: 'Page' | ||||
|         }, | ||||
|         { | ||||
|             id: '2ea41c78-8e60-4657-a350-53f1a1fa3021', | ||||
|             isDefault: false, | ||||
|             isSelected: false, | ||||
|             name: 'Shift 2', | ||||
|             pageTitle: 'Page' | ||||
|         }, | ||||
|         { | ||||
|             id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00', | ||||
|             isDefault: false, | ||||
|             isSelected: true, | ||||
|             name: 'Unnamed Page', | ||||
|             pageTitle: 'Page' | ||||
|         } | ||||
|     ], | ||||
|     sectionTitle: 'Section' | ||||
| }; | ||||
|  | ||||
| const selectedPage = { | ||||
|     id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00', | ||||
|     isDefault: false, | ||||
|     isSelected: true, | ||||
|     name: 'Unnamed Page', | ||||
|     pageTitle: 'Page' | ||||
| }; | ||||
| let notebookStorage; | ||||
| let notebookEntries; | ||||
| let notebookDomainObject; | ||||
| let selectedSection; | ||||
| let selectedPage; | ||||
|  | ||||
| let openmct; | ||||
| let mockIdentifierService; | ||||
|  | ||||
| describe('Notebook Entries:', () => { | ||||
|     beforeEach(() => { | ||||
|         notebookStorage = { | ||||
|             name: 'notebook', | ||||
|             identifier: { | ||||
|                 namespace: '', | ||||
|                 key: 'test-notebook' | ||||
|             }, | ||||
|             defaultSectionId: '03a79b6a-971c-4e56-9892-ec536332c3f0', | ||||
|             defaultPageId: '8b548fd9-2b8a-4b02-93a9-4138e22eba00' | ||||
|         }; | ||||
|  | ||||
|         notebookEntries = { | ||||
|             '03a79b6a-971c-4e56-9892-ec536332c3f0': { | ||||
|                 '8b548fd9-2b8a-4b02-93a9-4138e22eba00': [] | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         notebookDomainObject = { | ||||
|             identifier: { | ||||
|                 key: 'notebook', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             type: 'notebook', | ||||
|             configuration: { | ||||
|                 defaultSort: 'oldest', | ||||
|                 entries: notebookEntries, | ||||
|                 pageTitle: 'Page', | ||||
|                 sections: [], | ||||
|                 sectionTitle: 'Section', | ||||
|                 type: 'General' | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         selectedSection = { | ||||
|             id: '03a79b6a-971c-4e56-9892-ec536332c3f0', | ||||
|             isDefault: false, | ||||
|             isSelected: true, | ||||
|             name: 'Day 1', | ||||
|             pages: [ | ||||
|                 { | ||||
|                     id: '54deb3d5-8267-4be4-95e9-3579ed8c082d', | ||||
|                     isDefault: false, | ||||
|                     isSelected: false, | ||||
|                     name: 'Shift 1', | ||||
|                     pageTitle: 'Page' | ||||
|                 }, | ||||
|                 { | ||||
|                     id: '2ea41c78-8e60-4657-a350-53f1a1fa3021', | ||||
|                     isDefault: false, | ||||
|                     isSelected: false, | ||||
|                     name: 'Shift 2', | ||||
|                     pageTitle: 'Page' | ||||
|                 }, | ||||
|                 { | ||||
|                     id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00', | ||||
|                     isDefault: false, | ||||
|                     isSelected: true, | ||||
|                     name: 'Unnamed Page', | ||||
|                     pageTitle: 'Page' | ||||
|                 } | ||||
|             ], | ||||
|             sectionTitle: 'Section' | ||||
|         }; | ||||
|  | ||||
|         selectedPage = { | ||||
|             id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00', | ||||
|             isDefault: false, | ||||
|             isSelected: true, | ||||
|             name: 'Unnamed Page', | ||||
|             pageTitle: 'Page' | ||||
|         }; | ||||
|  | ||||
|         openmct = createOpenMct(); | ||||
|         openmct.$injector = jasmine.createSpyObj('$injector', ['get']); | ||||
|         mockIdentifierService = jasmine.createSpyObj( | ||||
|             'identifierService', | ||||
|             ['parse'] | ||||
|         ); | ||||
|         openmct.$injector.get.and.callFake((key) => { | ||||
|             return { | ||||
|                 'identifierService': mockIdentifierService, | ||||
|                 '$rootScope': { | ||||
|                     '$destroy': () => {} | ||||
|                 } | ||||
|             }[key]; | ||||
|         }); | ||||
|  | ||||
|         mockIdentifierService.parse.and.returnValue({ | ||||
|             getSpace: () => { | ||||
|                 return ''; | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         openmct.$injector.get.and.returnValue(mockIdentifierService); | ||||
|         openmct.types.addType('notebook', { | ||||
|             creatable: true | ||||
|         }); | ||||
|   | ||||
| @@ -23,51 +23,55 @@ | ||||
| import * as NotebookStorage from './notebook-storage'; | ||||
| import { createOpenMct, resetApplicationState } from 'utils/testing'; | ||||
|  | ||||
| const notebookSection = { | ||||
|     id: 'temp-section', | ||||
|     isDefault: false, | ||||
|     isSelected: true, | ||||
|     name: 'section', | ||||
|     pages: [ | ||||
|         { | ||||
|             id: 'temp-page', | ||||
|             isDefault: false, | ||||
|             isSelected: true, | ||||
|             name: 'page', | ||||
|             pageTitle: 'Page' | ||||
|         } | ||||
|     ], | ||||
|     sectionTitle: 'Section' | ||||
| }; | ||||
|  | ||||
| const domainObject = { | ||||
|     name: 'notebook', | ||||
|     identifier: { | ||||
|         namespace: '', | ||||
|         key: 'test-notebook' | ||||
|     }, | ||||
|     configuration: { | ||||
|         sections: [ | ||||
|             notebookSection | ||||
|         ] | ||||
|     } | ||||
| }; | ||||
|  | ||||
| const notebookStorage = { | ||||
|     name: 'notebook', | ||||
|     identifier: { | ||||
|         namespace: '', | ||||
|         key: 'test-notebook' | ||||
|     }, | ||||
|     defaultSectionId: 'temp-section', | ||||
|     defaultPageId: 'temp-page' | ||||
| }; | ||||
| let notebookSection; | ||||
| let domainObject; | ||||
| let notebookStorage; | ||||
|  | ||||
| let openmct; | ||||
| let mockIdentifierService; | ||||
|  | ||||
| describe('Notebook Storage:', () => { | ||||
|     beforeEach(() => { | ||||
|         notebookSection = { | ||||
|             id: 'temp-section', | ||||
|             isDefault: false, | ||||
|             isSelected: true, | ||||
|             name: 'section', | ||||
|             pages: [ | ||||
|                 { | ||||
|                     id: 'temp-page', | ||||
|                     isDefault: false, | ||||
|                     isSelected: true, | ||||
|                     name: 'page', | ||||
|                     pageTitle: 'Page' | ||||
|                 } | ||||
|             ], | ||||
|             sectionTitle: 'Section' | ||||
|         }; | ||||
|  | ||||
|         domainObject = { | ||||
|             name: 'notebook', | ||||
|             identifier: { | ||||
|                 namespace: '', | ||||
|                 key: 'test-notebook' | ||||
|             }, | ||||
|             configuration: { | ||||
|                 sections: [ | ||||
|                     notebookSection | ||||
|                 ] | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         notebookStorage = { | ||||
|             name: 'notebook', | ||||
|             identifier: { | ||||
|                 namespace: '', | ||||
|                 key: 'test-notebook' | ||||
|             }, | ||||
|             defaultSectionId: 'temp-section', | ||||
|             defaultPageId: 'temp-page' | ||||
|         }; | ||||
|  | ||||
|         openmct = createOpenMct(); | ||||
|         openmct.$injector = jasmine.createSpyObj('$injector', ['get']); | ||||
|         mockIdentifierService = jasmine.createSpyObj( | ||||
| @@ -80,7 +84,15 @@ describe('Notebook Storage:', () => { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         openmct.$injector.get.and.returnValue(mockIdentifierService); | ||||
|         openmct.$injector.get.and.callFake((key) => { | ||||
|             return { | ||||
|                 'identifierService': mockIdentifierService, | ||||
|                 '$rootScope': { | ||||
|                     '$destroy': () => {} | ||||
|                 } | ||||
|             }[key]; | ||||
|         }); | ||||
|  | ||||
|         window.localStorage.setItem('notebook-storage', null); | ||||
|         openmct.objects.addProvider('', jasmine.createSpyObj('mockNotebookProvider', [ | ||||
|             'create', | ||||
|   | ||||
| @@ -29,13 +29,8 @@ describe('the plugin', function () { | ||||
|     let element; | ||||
|     let child; | ||||
|     let openmct; | ||||
|     let appHolder; | ||||
|  | ||||
|     beforeEach((done) => { | ||||
|         appHolder = document.createElement('div'); | ||||
|         appHolder.style.width = '640px'; | ||||
|         appHolder.style.height = '480px'; | ||||
|  | ||||
|         openmct = createOpenMct(); | ||||
|         openmct.install(new PlanPlugin()); | ||||
|  | ||||
| @@ -50,7 +45,7 @@ describe('the plugin', function () { | ||||
|         element.appendChild(child); | ||||
|  | ||||
|         openmct.on('start', done); | ||||
|         openmct.start(appHolder); | ||||
|         openmct.start(element); | ||||
|     }); | ||||
|  | ||||
|     afterEach(() => { | ||||
| @@ -99,6 +94,7 @@ describe('the plugin', function () { | ||||
|             } | ||||
|         ]; | ||||
|         let planView; | ||||
|         let view; | ||||
|  | ||||
|         beforeEach(() => { | ||||
|             openmct.time.timeSystem('utc', { | ||||
| @@ -139,12 +135,16 @@ describe('the plugin', function () { | ||||
|  | ||||
|             const applicableViews = openmct.objectViews.get(planDomainObject, []); | ||||
|             planView = applicableViews.find((viewProvider) => viewProvider.key === 'plan.view'); | ||||
|             let view = planView.view(planDomainObject, mockObjectPath); | ||||
|             view = planView.view(planDomainObject, mockObjectPath); | ||||
|             view.show(child, true); | ||||
|  | ||||
|             return Vue.nextTick(); | ||||
|         }); | ||||
|  | ||||
|         afterEach(() => { | ||||
|             view.destroy(); | ||||
|         }); | ||||
|  | ||||
|         it('loads activities into the view', () => { | ||||
|             const svgEls = element.querySelectorAll('.c-plan__contents svg'); | ||||
|             expect(svgEls.length).toEqual(1); | ||||
|   | ||||
| @@ -98,7 +98,10 @@ export default { | ||||
|  | ||||
|         //Respond to changes in conductor | ||||
|         this.openmct.time.on("timeSystem", this.setViewFromTimeSystem); | ||||
|         setInterval(this.resize, RESIZE_POLL_INTERVAL); | ||||
|         this.resizeTimer = setInterval(this.resize, RESIZE_POLL_INTERVAL); | ||||
|     }, | ||||
|     destroyed() { | ||||
|         clearInterval(this.resizeTimer); | ||||
|     }, | ||||
|     methods: { | ||||
|         setAxisDimensions() { | ||||
|   | ||||
| @@ -38,6 +38,10 @@ define( | ||||
|  | ||||
|             this.openmct = openmct; | ||||
|             this.selected = []; | ||||
|  | ||||
|             this.openmct.once('destroy', () => { | ||||
|                 this.removeAllListeners(); | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         Selection.prototype = Object.create(EventEmitter.prototype); | ||||
|   | ||||
| @@ -54,6 +54,9 @@ describe("the inspector", () => { | ||||
|     }); | ||||
|  | ||||
|     afterEach(() => { | ||||
|         stylesViewComponent.$destroy(); | ||||
|         savedStylesViewComponent.$destroy(); | ||||
|  | ||||
|         return resetApplicationState(openmct); | ||||
|     }); | ||||
|  | ||||
| @@ -77,7 +80,7 @@ describe("the inspector", () => { | ||||
|         expect(savedStylesViewComponent.$children[0].$children.length).toBe(0); | ||||
|         stylesViewComponent.$children[0].saveStyle(mockStyle); | ||||
|  | ||||
|         stylesViewComponent.$nextTick().then(() => { | ||||
|         return stylesViewComponent.$nextTick().then(() => { | ||||
|             expect(savedStylesViewComponent.$children[0].$children.length).toBe(1); | ||||
|         }); | ||||
|     }); | ||||
| @@ -91,7 +94,7 @@ describe("the inspector", () => { | ||||
|  | ||||
|         stylesViewComponent.$children[0].saveStyle(mockStyle); | ||||
|  | ||||
|         stylesViewComponent.$nextTick().then(() => { | ||||
|         return stylesViewComponent.$nextTick().then(() => { | ||||
|             const styleSelectorComponent = savedStylesViewComponent.$children[0].$children[0]; | ||||
|  | ||||
|             styleSelectorComponent.selectStyle(); | ||||
| @@ -147,7 +150,7 @@ describe("the inspector", () => { | ||||
|         stylesViewComponent = createViewComponent(StylesView, selection, openmct); | ||||
|         savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); | ||||
|  | ||||
|         stylesViewComponent.$nextTick().then(() => { | ||||
|         return stylesViewComponent.$nextTick().then(() => { | ||||
|             const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; | ||||
|             const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex]; | ||||
|             const saveStyleButtonIndex = styleEditorComponent.$children.length - 1; | ||||
| @@ -168,7 +171,7 @@ describe("the inspector", () => { | ||||
|         stylesViewComponent = createViewComponent(StylesView, selection, openmct); | ||||
|         savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); | ||||
|  | ||||
|         stylesViewComponent.$nextTick().then(() => { | ||||
|         return stylesViewComponent.$nextTick().then(() => { | ||||
|             const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; | ||||
|             const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex]; | ||||
|             const saveStyleButtonIndex = styleEditorComponent.$children.length - 1; | ||||
| @@ -185,7 +188,7 @@ describe("the inspector", () => { | ||||
|         stylesViewComponent = createViewComponent(StylesView, selection, openmct); | ||||
|         savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct); | ||||
|  | ||||
|         stylesViewComponent.$nextTick().then(() => { | ||||
|         return stylesViewComponent.$nextTick().then(() => { | ||||
|             const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1; | ||||
|             const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex]; | ||||
|             const saveStyleButtonIndex = styleEditorComponent.$children.length - 1; | ||||
|   | ||||
| @@ -134,7 +134,7 @@ export default { | ||||
|         actionCollection: { | ||||
|             type: Object, | ||||
|             default: () => { | ||||
|                 return {}; | ||||
|                 return undefined; | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
| @@ -233,6 +233,7 @@ export default { | ||||
|     }, | ||||
|     mounted: function () { | ||||
|         document.addEventListener('click', this.closeViewAndSaveMenu); | ||||
|  | ||||
|         this.promptUserbeforeNavigatingAway = this.promptUserbeforeNavigatingAway.bind(this); | ||||
|         window.addEventListener('beforeunload', this.promptUserbeforeNavigatingAway); | ||||
|  | ||||
|   | ||||
| @@ -49,6 +49,10 @@ class ApplicationRouter extends EventEmitter { | ||||
|         this.routes = []; | ||||
|         this.started = false; | ||||
|  | ||||
|         openmct.once('destroy', () => { | ||||
|             this.destroy(); | ||||
|         }); | ||||
|  | ||||
|         this.setHash = _.debounce(this.setHash.bind(this), 300); | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user