Merge branch 'master' into open671
Conflicts: main.js platform/commonUI/edit/src/policies/EditableMovePolicy.js platform/commonUI/general/src/directives/MCTTree.js platform/commonUI/general/src/ui/ToggleView.js platform/core/src/actions/ActionCapability.js platform/core/test/models/CachingModelDecoratorSpec.js platform/core/test/services/InstantiateSpec.js platform/features/events/bundle.js platform/features/events/src/DomainColumn.js platform/features/events/src/EventListController.js platform/features/events/src/EventListPopulator.js platform/features/events/src/RangeColumn.js platform/features/events/src/directives/MCTDataTable.js platform/features/events/src/policies/MessagesViewPolicy.js platform/features/events/test/DomainColumnSpec.js platform/features/events/test/EventListControllerSpec.js platform/features/events/test/EventListPopulatorSpec.js platform/features/events/test/RangeColumnSpec.js platform/features/events/test/policies/MessagesViewPolicySpec.js platform/features/rtevents/bundle.js platform/features/rtevents/src/DomainColumn.js platform/features/rtevents/src/RTEventListController.js platform/features/rtevents/src/RangeColumn.js platform/features/rtevents/src/directives/MCTRTDataTable.js platform/features/rtevents/src/policies/RTMessagesViewPolicy.js platform/features/rtevents/test/DomainColumnSpec.js platform/features/rtevents/test/RTEventListControllerSpec.js platform/features/rtevents/test/RangeColumnSpec.js platform/features/rtevents/test/policies/RTMessagesViewPolicySpec.js platform/features/rtscrolling/bundle.js platform/features/rtscrolling/src/DomainColumn.js platform/features/rtscrolling/src/NameColumn.js platform/features/rtscrolling/src/RTScrollingListController.js platform/features/rtscrolling/src/RangeColumn.js platform/features/scrolling/src/DomainColumn.js platform/features/scrolling/src/RangeColumn.js platform/features/scrolling/src/ScrollingListController.js platform/features/scrolling/src/ScrollingListPopulator.js platform/features/scrolling/test/DomainColumnSpec.js platform/features/scrolling/test/RangeColumnSpec.js platform/features/scrolling/test/ScrollingListControllerSpec.js platform/features/scrolling/test/ScrollingListPopulatorSpec.js platform/features/table/src/directives/MCTTable.js platform/features/table/test/controllers/TelemetryTableControllerSpec.js platform/representation/src/gestures/DropGesture.js platform/telemetry/src/TelemetryFormatter.js test-main.js
This commit is contained in:
@@ -26,6 +26,7 @@ define([
|
||||
"./src/models/StaticModelProvider",
|
||||
"./src/models/RootModelProvider",
|
||||
"./src/models/ModelAggregator",
|
||||
"./src/models/ModelCacheService",
|
||||
"./src/models/PersistedModelProvider",
|
||||
"./src/models/CachingModelDecorator",
|
||||
"./src/models/MissingModelDecorator",
|
||||
@@ -57,6 +58,7 @@ define([
|
||||
StaticModelProvider,
|
||||
RootModelProvider,
|
||||
ModelAggregator,
|
||||
ModelCacheService,
|
||||
PersistedModelProvider,
|
||||
CachingModelDecorator,
|
||||
MissingModelDecorator,
|
||||
@@ -180,7 +182,10 @@ define([
|
||||
{
|
||||
"provides": "modelService",
|
||||
"type": "decorator",
|
||||
"implementation": CachingModelDecorator
|
||||
"implementation": CachingModelDecorator,
|
||||
"depends": [
|
||||
"cacheService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"provides": "modelService",
|
||||
@@ -246,21 +251,22 @@ define([
|
||||
"property": "name",
|
||||
"pattern": "\\S+",
|
||||
"required": true,
|
||||
"cssclass": "l-med"
|
||||
"cssclass": "l-input-lg"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "root",
|
||||
"name": "Root",
|
||||
"glyph": "F"
|
||||
"glyph": "\u0046"
|
||||
},
|
||||
{
|
||||
"key": "folder",
|
||||
"name": "Folder",
|
||||
"glyph": "F",
|
||||
"glyph": "\u0046",
|
||||
"features": "creation",
|
||||
"description": "Useful for storing and organizing domain objects.",
|
||||
"description": "Create folders to organize other objects or links to objects.",
|
||||
"priority": 1000,
|
||||
"model": {
|
||||
"composition": []
|
||||
}
|
||||
@@ -268,11 +274,11 @@ define([
|
||||
{
|
||||
"key": "unknown",
|
||||
"name": "Unknown Type",
|
||||
"glyph": "?"
|
||||
"glyph": "\u003f"
|
||||
},
|
||||
{
|
||||
"name": "Unknown Type",
|
||||
"glyph": "?"
|
||||
"glyph": "\u003f"
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
@@ -317,6 +323,7 @@ define([
|
||||
"key": "persistence",
|
||||
"implementation": PersistenceCapability,
|
||||
"depends": [
|
||||
"cacheService",
|
||||
"persistenceService",
|
||||
"identifierService",
|
||||
"notificationService",
|
||||
@@ -347,11 +354,16 @@ define([
|
||||
"implementation": InstantiationCapability,
|
||||
"depends": [
|
||||
"$injector",
|
||||
"identifierService"
|
||||
"identifierService",
|
||||
"now"
|
||||
]
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key": "cacheService",
|
||||
"implementation": ModelCacheService
|
||||
},
|
||||
{
|
||||
"key": "now",
|
||||
"implementation": Now
|
||||
@@ -382,7 +394,8 @@ define([
|
||||
"implementation": Instantiate,
|
||||
"depends": [
|
||||
"capabilityService",
|
||||
"identifierService"
|
||||
"identifierService",
|
||||
"cacheService"
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
var DISALLOWED_ACTIONS = ["move", "copy", "link", "window", "follow"];
|
||||
var DISALLOWED_ACTIONS = ["copy", "window", "follow"];
|
||||
|
||||
/**
|
||||
* The ActionCapability allows applicable Actions to be retrieved and
|
||||
* performed for specific domain objects, e.g.:
|
||||
|
||||
@@ -33,10 +33,16 @@ define(
|
||||
* @param $injector Angular's `$injector`
|
||||
* @implements {Capability}
|
||||
*/
|
||||
function InstantiationCapability($injector, identifierService, domainObject) {
|
||||
function InstantiationCapability(
|
||||
$injector,
|
||||
identifierService,
|
||||
now,
|
||||
domainObject
|
||||
) {
|
||||
this.$injector = $injector;
|
||||
this.identifierService = identifierService;
|
||||
this.domainObject = domainObject;
|
||||
this.now = now;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,6 +61,8 @@ define(
|
||||
space = parsedId.getDefinedSpace(),
|
||||
id = this.identifierService.generate(space);
|
||||
|
||||
model.modified = this.now();
|
||||
|
||||
// Lazily initialize; instantiate depends on capabilityService,
|
||||
// which depends on all capabilities, including this one.
|
||||
this.instantiateFn = this.instantiateFn ||
|
||||
|
||||
@@ -44,6 +44,7 @@ define(
|
||||
* @implements {Capability}
|
||||
*/
|
||||
function PersistenceCapability(
|
||||
cacheService,
|
||||
persistenceService,
|
||||
identifierService,
|
||||
notificationService,
|
||||
@@ -54,6 +55,7 @@ define(
|
||||
this.modified = domainObject.getModel().modified;
|
||||
|
||||
this.domainObject = domainObject;
|
||||
this.cacheService = cacheService;
|
||||
this.identifierService = identifierService;
|
||||
this.persistenceService = persistenceService;
|
||||
this.notificationService = notificationService;
|
||||
@@ -128,6 +130,7 @@ define(
|
||||
domainObject = this.domainObject,
|
||||
model = domainObject.getModel(),
|
||||
modified = model.modified,
|
||||
cacheService = this.cacheService,
|
||||
persistenceService = this.persistenceService,
|
||||
persistenceFn = model.persisted !== undefined ?
|
||||
this.persistenceService.updateObject :
|
||||
|
||||
@@ -33,9 +33,8 @@ define(
|
||||
* @param {ModelService} modelService this service to decorate
|
||||
* @implements {ModelService}
|
||||
*/
|
||||
function CachingModelDecorator(modelService) {
|
||||
this.cache = {};
|
||||
this.cached = {};
|
||||
function CachingModelDecorator(cacheService, modelService) {
|
||||
this.cacheService = cacheService;
|
||||
this.modelService = modelService;
|
||||
}
|
||||
|
||||
@@ -49,17 +48,16 @@ define(
|
||||
}
|
||||
|
||||
CachingModelDecorator.prototype.getModels = function (ids) {
|
||||
var cache = this.cache,
|
||||
cached = this.cached,
|
||||
var cacheService = this.cacheService,
|
||||
neededIds = ids.filter(function notCached(id) {
|
||||
return !cached[id];
|
||||
return !cacheService.has(id);
|
||||
});
|
||||
|
||||
// Update the cached instance of a model to a new value.
|
||||
// We update in-place to ensure there is only ever one instance
|
||||
// of any given model exposed by the modelService as a whole.
|
||||
function updateModel(id, model) {
|
||||
var oldModel = cache[id];
|
||||
var oldModel = cacheService.get(id);
|
||||
|
||||
// Same object instance is a possibility, so don't copy
|
||||
if (oldModel === model) {
|
||||
@@ -69,7 +67,7 @@ define(
|
||||
// If we'd previously cached an undefined value, or are now
|
||||
// seeing undefined, replace the item in the cache entirely.
|
||||
if (oldModel === undefined || model === undefined) {
|
||||
cache[id] = model;
|
||||
cacheService.put(id, model);
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -89,15 +87,15 @@ define(
|
||||
// Store the provided models in our cache
|
||||
function cacheAll(models) {
|
||||
Object.keys(models).forEach(function (id) {
|
||||
cache[id] = cached[id] ?
|
||||
var model = cacheService.has(id) ?
|
||||
updateModel(id, models[id]) : models[id];
|
||||
cached[id] = true;
|
||||
cacheService.put(id, model);
|
||||
});
|
||||
}
|
||||
|
||||
// Expose the cache (for promise chaining)
|
||||
function giveCache() {
|
||||
return cache;
|
||||
return cacheService.all();
|
||||
}
|
||||
|
||||
// Look up if we have unknown IDs
|
||||
@@ -108,7 +106,7 @@ define(
|
||||
}
|
||||
|
||||
// Otherwise, just expose the cache directly
|
||||
return fastPromise(cache);
|
||||
return fastPromise(cacheService.all());
|
||||
};
|
||||
|
||||
return CachingModelDecorator;
|
||||
|
||||
83
platform/core/src/models/ModelCacheService.js
Normal file
83
platform/core/src/models/ModelCacheService.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Provides a cache for domain object models which exist in memory,
|
||||
* but may or may not exist in backing persistene stores.
|
||||
* @constructor
|
||||
* @memberof platform/core
|
||||
*/
|
||||
function ModelCacheService() {
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Put a domain object model in the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @param {object} model the domain object's model
|
||||
*/
|
||||
ModelCacheService.prototype.put = function (id, model) {
|
||||
this.cache[id] = model;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve a domain object model from the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @returns {object} the domain object's model
|
||||
*/
|
||||
ModelCacheService.prototype.get = function (id) {
|
||||
return this.cache[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a domain object model is in the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
* @returns {boolean} true if present; false if not
|
||||
*/
|
||||
ModelCacheService.prototype.has = function (id) {
|
||||
return this.cache.hasOwnProperty(id);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove a domain object model from the cache.
|
||||
* @param {string} id the domain object's identifier
|
||||
*/
|
||||
ModelCacheService.prototype.remove = function (id) {
|
||||
delete this.cache[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve all cached domain object models. These are given
|
||||
* as an object containing key-value pairs, where keys are
|
||||
* domain object identifiers and values are domain object models.
|
||||
* @returns {object} all domain object models
|
||||
*/
|
||||
ModelCacheService.prototype.all = function () {
|
||||
return this.cache;
|
||||
};
|
||||
|
||||
return ModelCacheService;
|
||||
});
|
||||
@@ -42,10 +42,15 @@ define(
|
||||
* @param {IdentifierService} identifierService service to generate
|
||||
* new identifiers
|
||||
*/
|
||||
function Instantiate(capabilityService, identifierService) {
|
||||
function Instantiate(
|
||||
capabilityService,
|
||||
identifierService,
|
||||
cacheService
|
||||
) {
|
||||
return function (model, id) {
|
||||
var capabilities = capabilityService.getCapabilities(model);
|
||||
id = id || identifierService.generate();
|
||||
cacheService.put(id, model);
|
||||
return new DomainObjectImpl(id, model, capabilities);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ define(
|
||||
mockIdentifierService,
|
||||
mockInstantiate,
|
||||
mockIdentifier,
|
||||
mockNow,
|
||||
mockDomainObject,
|
||||
instantiation;
|
||||
|
||||
@@ -55,9 +56,13 @@ define(
|
||||
mockIdentifierService.parse.andReturn(mockIdentifier);
|
||||
mockIdentifierService.generate.andReturn("some-id");
|
||||
|
||||
mockNow = jasmine.createSpy();
|
||||
mockNow.andReturn(1234321);
|
||||
|
||||
instantiation = new InstantiationCapability(
|
||||
mockInjector,
|
||||
mockIdentifierService,
|
||||
mockNow,
|
||||
mockDomainObject
|
||||
);
|
||||
});
|
||||
@@ -79,7 +84,10 @@ define(
|
||||
expect(instantiation.instantiate(testModel))
|
||||
.toBe(mockDomainObject);
|
||||
expect(mockInstantiate)
|
||||
.toHaveBeenCalledWith(testModel, jasmine.any(String));
|
||||
.toHaveBeenCalledWith({
|
||||
someKey: "some value",
|
||||
modified: mockNow()
|
||||
}, jasmine.any(String));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -34,6 +34,7 @@ define(
|
||||
mockDomainObject,
|
||||
mockIdentifier,
|
||||
mockNofificationService,
|
||||
mockCacheService,
|
||||
mockQ,
|
||||
id = "object id",
|
||||
model,
|
||||
@@ -79,6 +80,10 @@ define(
|
||||
"notificationService",
|
||||
["error"]
|
||||
);
|
||||
mockCacheService = jasmine.createSpyObj(
|
||||
"cacheService",
|
||||
[ "get", "put", "remove", "all" ]
|
||||
);
|
||||
|
||||
mockDomainObject = {
|
||||
getId: function () { return id; },
|
||||
@@ -94,6 +99,7 @@ define(
|
||||
mockIdentifierService.parse.andReturn(mockIdentifier);
|
||||
mockIdentifier.getSpace.andReturn(SPACE);
|
||||
persistence = new PersistenceCapability(
|
||||
mockCacheService,
|
||||
mockPersistenceService,
|
||||
mockIdentifierService,
|
||||
mockNofificationService,
|
||||
@@ -169,6 +175,7 @@ define(
|
||||
expect(mockNofificationService.error).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("unsuccessful persistence", function() {
|
||||
var sadPromise = {
|
||||
then: function(callback){
|
||||
|
||||
@@ -21,8 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/models/CachingModelDecorator"],
|
||||
function (CachingModelDecorator) {
|
||||
[
|
||||
"../../src/models/CachingModelDecorator",
|
||||
"../../src/models/ModelCacheService"
|
||||
],
|
||||
function (CachingModelDecorator, ModelCacheService) {
|
||||
|
||||
describe("The caching model decorator", function () {
|
||||
var mockModelService,
|
||||
@@ -65,7 +68,10 @@ define(
|
||||
b: { someOtherKey: "some other value" }
|
||||
};
|
||||
mockModelService.getModels.andReturn(asPromise(testModels));
|
||||
decorator = new CachingModelDecorator(mockModelService);
|
||||
decorator = new CachingModelDecorator(
|
||||
new ModelCacheService(),
|
||||
mockModelService
|
||||
);
|
||||
});
|
||||
|
||||
it("loads models from its wrapped model service", function () {
|
||||
@@ -148,4 +154,4 @@ define(
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
69
platform/core/test/models/ModelCacheServiceSpec.js
Normal file
69
platform/core/test/models/ModelCacheServiceSpec.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||
|
||||
define(['../../src/models/ModelCacheService'], function (ModelCacheService) {
|
||||
'use strict';
|
||||
describe("ModelCacheService", function () {
|
||||
var testIds,
|
||||
testModels,
|
||||
cacheService;
|
||||
|
||||
beforeEach(function () {
|
||||
testIds = [ 'a', 'b', 'c', 'd' ];
|
||||
testModels = testIds.reduce(function (models, id) {
|
||||
models[id] = { someKey: "some value for " + id };
|
||||
return models;
|
||||
}, {});
|
||||
cacheService = new ModelCacheService();
|
||||
});
|
||||
|
||||
describe("when populated with models", function () {
|
||||
beforeEach(function () {
|
||||
testIds.forEach(function (id) {
|
||||
cacheService.put(id, testModels[id]);
|
||||
});
|
||||
});
|
||||
|
||||
it("indicates that it has these models", function () {
|
||||
testIds.forEach(function (id) {
|
||||
expect(cacheService.has(id)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it("provides all of these models", function () {
|
||||
expect(cacheService.all()).toEqual(testModels);
|
||||
});
|
||||
|
||||
it("allows models to be retrieved", function () {
|
||||
testIds.forEach(function (id) {
|
||||
expect(cacheService.get(id)).toEqual(testModels[id]);
|
||||
});
|
||||
});
|
||||
|
||||
it("allows models to be removed", function () {
|
||||
cacheService.remove('a');
|
||||
expect(cacheService.has('a')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -30,6 +30,7 @@ define(
|
||||
mockIdentifierService,
|
||||
mockCapabilityConstructor,
|
||||
mockCapabilityInstance,
|
||||
mockCacheService,
|
||||
idCounter,
|
||||
testModel,
|
||||
instantiate,
|
||||
@@ -58,11 +59,17 @@ define(
|
||||
"some-id-" + (idCounter += 1);
|
||||
});
|
||||
|
||||
mockCacheService = jasmine.createSpyObj(
|
||||
'cacheService',
|
||||
[ 'get', 'put', 'remove', 'all' ]
|
||||
);
|
||||
|
||||
testModel = { someKey: "some value" };
|
||||
|
||||
instantiate = new Instantiate(
|
||||
mockCapabilityService,
|
||||
mockIdentifierService
|
||||
mockIdentifierService,
|
||||
mockCacheService
|
||||
);
|
||||
domainObject = instantiate(testModel);
|
||||
});
|
||||
@@ -88,6 +95,13 @@ define(
|
||||
expect(instantiate(testModel).getId())
|
||||
.not.toEqual(domainObject.getId());
|
||||
});
|
||||
|
||||
it("caches the instantiated model", function () {
|
||||
expect(mockCacheService.put).toHaveBeenCalledWith(
|
||||
domainObject.getId(),
|
||||
testModel
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user