diff --git a/platform/core/bundle.js b/platform/core/bundle.js index 55879265c7..93b64f5739 100644 --- a/platform/core/bundle.js +++ b/platform/core/bundle.js @@ -24,6 +24,7 @@ define([ "./src/objects/DomainObjectProvider", "./src/capabilities/CoreCapabilityProvider", "./src/models/StaticModelProvider", + "./src/models/RootModelProvider", "./src/models/ModelAggregator", "./src/models/ModelCacheService", "./src/models/PersistedModelProvider", @@ -56,6 +57,7 @@ define([ DomainObjectProvider, CoreCapabilityProvider, StaticModelProvider, + RootModelProvider, ModelAggregator, ModelCacheService, PersistedModelProvider, @@ -150,6 +152,16 @@ define([ "$log" ] }, + { + "provides": "modelService", + "type": "provider", + "implementation": RootModelProvider, + "depends": [ + "roots[]", + "$q", + "$log" + ] + }, { "provides": "modelService", "type": "aggregator", diff --git a/platform/core/src/models/RootModelProvider.js b/platform/core/src/models/RootModelProvider.js new file mode 100644 index 0000000000..205d41e66b --- /dev/null +++ b/platform/core/src/models/RootModelProvider.js @@ -0,0 +1,79 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2016, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +/** + * Module defining RootModelProvider. Created by vwoeltje on 11/7/14. + */ +define( + ['./StaticModelProvider'], + function (StaticModelProvider) { + + /** + * Provides the root object (id = "ROOT"), which is the top-level + * domain object shown when the application is started, from which all + * other domain objects are reached. + * + * The root model provider works as the static model provider, + * except that it aggregates roots[] instead of models[], and + * exposes them all as composition of the root object ROOT, + * whose model is also provided by this service. + * + * @memberof platform/core + * @constructor + * @implements {ModelService} + * @param {Array} roots all `roots[]` extensions + * @param $q Angular's $q, for promises + * @param $log Angular's $log, for logging + */ + function RootModelProvider(roots, $q, $log) { + // Pull out identifiers to used as ROOT's + var ids = roots.map(function (root) { + return root.id; + }); + + // Assign an initial location to root models + roots.forEach(function (root) { + if (!root.model) { + root.model = {}; + } + root.model.location = 'ROOT'; + }); + + this.baseProvider = new StaticModelProvider(roots, $q, $log); + this.rootModel = { + name: "The root object", + type: "root", + composition: ids + }; + } + + RootModelProvider.prototype.getModels = function (ids) { + var rootModel = this.rootModel; + return this.baseProvider.getModels(ids).then(function (models) { + models.ROOT = rootModel; + return models; + }); + }; + + return RootModelProvider; + } +); diff --git a/platform/core/test/models/RootModelProviderSpec.js b/platform/core/test/models/RootModelProviderSpec.js new file mode 100644 index 0000000000..a7e027c4ab --- /dev/null +++ b/platform/core/test/models/RootModelProviderSpec.js @@ -0,0 +1,105 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2016, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +/** + * RootModelProviderSpec. Created by vwoeltje on 11/6/14. + */ +define( + ["../../src/models/RootModelProvider"], + function (RootModelProvider) { + + describe("The root model provider", function () { + var roots = [ + { + "id": "a", + "model": { + "name": "Thing A", + "someProperty": "Some Value A" + } + }, + { + "id": "b", + "model": { + "name": "Thing B", + "someProperty": "Some Value B" + } + } + ], + captured, + mockLog, + mockQ, + provider; + + function mockPromise(value) { + return { + then: function (callback) { + return mockPromise(callback(value)); + } + }; + } + + function capture(value) { + captured = value; + } + + + beforeEach(function () { + mockQ = { when: mockPromise }; + mockLog = jasmine.createSpyObj("$log", ["error", "warn", "info", "debug"]); + provider = new RootModelProvider(roots, mockQ, mockLog); + }); + + it("provides models from extension declarations", function () { + // Verify that we got the promise as the return value + provider.getModels(["a", "b"]).then(capture); + + // Verify that the promise has the desired models + expect(captured.a.name).toEqual("Thing A"); + expect(captured.a.someProperty).toEqual("Some Value A"); + expect(captured.b.name).toEqual("Thing B"); + expect(captured.b.someProperty).toEqual("Some Value B"); + }); + + it("provides models with a location", function () { + provider.getModels(["a", "b"]).then(capture); + expect(captured.a.location).toBe('ROOT'); + expect(captured.b.location).toBe('ROOT'); + }); + + + it("does not provide models which are not in extension declarations", function () { + provider.getModels(["c"]).then(capture); + + // Verify that the promise has the desired models + expect(captured.c).toBeUndefined(); + }); + + it("provides a ROOT object with roots in its composition", function () { + provider.getModels(["ROOT"]).then(capture); + + expect(captured.ROOT).toBeDefined(); + expect(captured.ROOT.composition).toEqual(["a", "b"]); + }); + + }); + } +);