mirror of
https://github.com/nasa/openmct.git
synced 2025-06-14 13:18:15 +00:00
[Location] Use parent id as location
Use the parent id as the location for a model. This greatly reduces the recursive work that must be done during move operations to keep the location accurate. Additionally, the locationService now implements a method `persistLocation` which can be used to persist the current object location as it's original location.
This commit is contained in:
@ -121,25 +121,8 @@ define(
|
|||||||
|
|
||||||
// Store the location of an object relative to it's parent.
|
// Store the location of an object relative to it's parent.
|
||||||
function addLocationToModel(modelId, model, parent) {
|
function addLocationToModel(modelId, model, parent) {
|
||||||
var context = parent.getCapability("context"),
|
model.location = parent.getId();
|
||||||
pathObjects,
|
|
||||||
pathIds;
|
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
$log.warn('No parent context, location will not be set.');
|
|
||||||
return model;
|
|
||||||
}
|
|
||||||
|
|
||||||
pathObjects = context.getPath();
|
|
||||||
if (!pathObjects || !pathObjects.length) {
|
|
||||||
pathObjects = [];
|
|
||||||
}
|
|
||||||
pathIds = pathObjects.map(function (object) {
|
|
||||||
return object.getId();
|
|
||||||
});
|
|
||||||
pathIds.push(modelId);
|
|
||||||
|
|
||||||
model.location = pathIds.join('/');
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,21 +103,13 @@ define(
|
|||||||
mockPromise(true)
|
mockPromise(true)
|
||||||
);
|
);
|
||||||
|
|
||||||
mockContextCapability.getPath.andReturn([
|
|
||||||
{
|
|
||||||
getId: function () { return 'root'; }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
getId: function () { return 'parent'; }
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
|
|
||||||
mockParentObject.getCapability.andCallFake(function (key) {
|
mockParentObject.getCapability.andCallFake(function (key) {
|
||||||
return mockCapabilities[key];
|
return mockCapabilities[key];
|
||||||
});
|
});
|
||||||
mockParentObject.useCapability.andCallFake(function (key, value) {
|
mockParentObject.useCapability.andCallFake(function (key, value) {
|
||||||
return mockCapabilities[key].invoke(value);
|
return mockCapabilities[key].invoke(value);
|
||||||
});
|
});
|
||||||
|
mockParentObject.getId.andReturn('parentId');
|
||||||
|
|
||||||
mockPersistenceCapability.persist.andReturn(
|
mockPersistenceCapability.persist.andReturn(
|
||||||
mockPromise(true)
|
mockPromise(true)
|
||||||
@ -215,8 +207,7 @@ define(
|
|||||||
model,
|
model,
|
||||||
mockParentObject
|
mockParentObject
|
||||||
);
|
);
|
||||||
expect(model.location).toBeDefined();
|
expect(model.location).toBe('parentId');
|
||||||
expect(model.location.indexOf('root/parent')).toBe(0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -9,6 +9,23 @@ define(
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persist the current location of the current domain object as it's
|
||||||
|
* primary location. Returns a promise.
|
||||||
|
*/
|
||||||
|
LocationCapability.prototype.persistLocation = function () {
|
||||||
|
return this.domainObject.useCapability(
|
||||||
|
'mutation',
|
||||||
|
function (model) {
|
||||||
|
model.location = this.getLocation();
|
||||||
|
}.bind(this)
|
||||||
|
).then(function () {
|
||||||
|
return this.domainObject
|
||||||
|
.getCapability('persistence')
|
||||||
|
.persist();
|
||||||
|
}.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the current location of the current domain object. Only
|
* Return the current location of the current domain object. Only
|
||||||
* valid for domain objects that have a context capability.
|
* valid for domain objects that have a context capability.
|
||||||
@ -19,19 +36,10 @@ define(
|
|||||||
pathIds;
|
pathIds;
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
return this.domainObject.getId();
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
pathObjects = context.getPath();
|
return context.getParent().getId();
|
||||||
if (!pathObjects) {
|
|
||||||
pathObjects = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
pathIds = pathObjects.map(function (object) {
|
|
||||||
return object.getId();
|
|
||||||
});
|
|
||||||
|
|
||||||
return pathIds.join('/');
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -64,17 +72,6 @@ define(
|
|||||||
return new LocationCapability(domainObject);
|
return new LocationCapability(domainObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if the LocationCapability can apply to a given
|
|
||||||
* domainObject, otherwise return false.
|
|
||||||
*/
|
|
||||||
createLocationCapability.appliesTo = function (domainObject) {
|
|
||||||
// if (!domainObject.hasCapability) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// return domainObject.hasCapability('context');
|
|
||||||
};
|
|
||||||
|
|
||||||
return createLocationCapability;
|
return createLocationCapability;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -32,153 +32,6 @@ define(
|
|||||||
*/
|
*/
|
||||||
function MoveService(policyService, linkService, $q) {
|
function MoveService(policyService, linkService, $q) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a promise for a childSelector for a given object which
|
|
||||||
* returns all original children in that given object.
|
|
||||||
*/
|
|
||||||
function getOriginalsInObject(object) {
|
|
||||||
var originalChildren = {};
|
|
||||||
return getOriginalChildren(object)
|
|
||||||
.then(function recurseChildren(children) {
|
|
||||||
var promises = [];
|
|
||||||
children.children.forEach(function(child) {
|
|
||||||
promises.push(getOriginalsInObject(child));
|
|
||||||
originalChildren[child.getId()] = {};
|
|
||||||
});
|
|
||||||
return $q.all(promises);
|
|
||||||
}).then(function prepareResponse(childResponses) {
|
|
||||||
childResponses.forEach(function(childResp) {
|
|
||||||
Object.keys(childResp).forEach(function(childId) {
|
|
||||||
originalChildren[childId] = childResp[childId];
|
|
||||||
});
|
|
||||||
});
|
|
||||||
var childSelector = {};
|
|
||||||
childSelector[object.getId()] = originalChildren;
|
|
||||||
return childSelector;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the original children in an object. Returns a promise for an object
|
|
||||||
* with a single key (the object's key), the value of which is an array
|
|
||||||
* of original children in that object.
|
|
||||||
*/
|
|
||||||
function getOriginalChildren(object) {
|
|
||||||
if (!object.hasCapability('composition')) {
|
|
||||||
return $q.when({
|
|
||||||
objectId: object.getId(),
|
|
||||||
children: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return object.useCapability('composition')
|
|
||||||
.then(function filterToOriginal(children) {
|
|
||||||
return children.filter(function(child) {
|
|
||||||
if (child.hasCapability('location')) {
|
|
||||||
return child.getCapability('location')
|
|
||||||
.isOriginal();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.then(function returnAsObject(children) {
|
|
||||||
return {
|
|
||||||
objectId: object.getId(),
|
|
||||||
children: children
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Persist an instance of an object as the original location of
|
|
||||||
* that object.
|
|
||||||
*/
|
|
||||||
function saveAsOriginal(newOriginal) {
|
|
||||||
return newOriginal.useCapability(
|
|
||||||
'mutation',
|
|
||||||
function (model) {
|
|
||||||
model.location = newOriginal
|
|
||||||
.getCapability('location')
|
|
||||||
.getLocation();
|
|
||||||
}
|
|
||||||
).then(function() {
|
|
||||||
return newOriginal
|
|
||||||
.getCapability('persistence')
|
|
||||||
.persist();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* childrenSelector is an object where keys are childIds and values
|
|
||||||
* are childSelector objects. Returns all children in the object
|
|
||||||
* which have a key in the childSelector, plus all children from
|
|
||||||
* recursive childSelection.
|
|
||||||
*/
|
|
||||||
function getMatchingChildrenFromObject(object, childrenSelector) {
|
|
||||||
var selected = [];
|
|
||||||
if (!object.hasCapability('composition')) {
|
|
||||||
return $q.when(selected);
|
|
||||||
}
|
|
||||||
return object.useCapability('composition')
|
|
||||||
.then(function selectChildren(children) {
|
|
||||||
var promises = [];
|
|
||||||
children.forEach(function (child) {
|
|
||||||
if (!childrenSelector[child.getId()]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
selected.push(child);
|
|
||||||
promises.push(getMatchingChildrenFromObject(
|
|
||||||
child,
|
|
||||||
childrenSelector[child.getId()]
|
|
||||||
));
|
|
||||||
});
|
|
||||||
|
|
||||||
return $q.all(promises)
|
|
||||||
.then(function reduceResults (results) {
|
|
||||||
return results.reduce(function(memo, result) {
|
|
||||||
return memo.concat(result);
|
|
||||||
}, selected);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uses the original object to determine which objects are originals,
|
|
||||||
* and then returns a function which, when given the same object in the
|
|
||||||
* new context, will update the location of all originals in the leaf
|
|
||||||
* to match the new context.
|
|
||||||
*/
|
|
||||||
function updateOriginalLocation(object) {
|
|
||||||
var oldLocationCapability = object.getCapability('location');
|
|
||||||
if (!oldLocationCapability.isOriginal()) {
|
|
||||||
return function (objectInNewContext) {
|
|
||||||
return objectInNewContext;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return function setOriginalLocation(objectInNewContext) {
|
|
||||||
return saveAsOriginal(objectInNewContext)
|
|
||||||
.then(function () {
|
|
||||||
if (!object.hasCapability('composition')) {
|
|
||||||
return objectInNewContext;
|
|
||||||
}
|
|
||||||
getOriginalsInObject(object)
|
|
||||||
.then(function(childSelector) {
|
|
||||||
return getMatchingChildrenFromObject(
|
|
||||||
objectInNewContext,
|
|
||||||
childSelector[object.getId()]
|
|
||||||
);
|
|
||||||
}).then(function(originalChildren) {
|
|
||||||
return $q.all(
|
|
||||||
originalChildren.map(saveAsOriginal)
|
|
||||||
);
|
|
||||||
}).then(function() {
|
|
||||||
return objectInNewContext;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
* Returns `true` if `object` can be moved into
|
* Returns `true` if `object` can be moved into
|
||||||
@ -216,7 +69,16 @@ define(
|
|||||||
perform: function (object, parentObject) {
|
perform: function (object, parentObject) {
|
||||||
return linkService
|
return linkService
|
||||||
.perform(object, parentObject)
|
.perform(object, parentObject)
|
||||||
.then(updateOriginalLocation(object))
|
.then(function (objectInNewContext) {
|
||||||
|
if (!object.hasCapability('location')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (object.getCapability('location').isOriginal()) {
|
||||||
|
return objectInNewContext
|
||||||
|
.getCapability('location')
|
||||||
|
.persistLocation();
|
||||||
|
}
|
||||||
|
})
|
||||||
.then(function () {
|
.then(function () {
|
||||||
return object
|
return object
|
||||||
.getCapability('action')
|
.getCapability('action')
|
||||||
|
@ -3,66 +3,90 @@
|
|||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
'../../src/capabilities/LocationCapability',
|
'../../src/capabilities/LocationCapability',
|
||||||
'../DomainObjectFactory'
|
'../DomainObjectFactory',
|
||||||
|
'../ControlledPromise'
|
||||||
],
|
],
|
||||||
function (LocationCapability, domainObjectFactory) {
|
function (LocationCapability, domainObjectFactory, ControlledPromise) {
|
||||||
|
|
||||||
describe("LocationCapability", function () {
|
describe("LocationCapability", function () {
|
||||||
|
|
||||||
|
|
||||||
// xit("applies to objects with a context capability", function () {
|
|
||||||
// var domainObject = domainObjectFactory({
|
|
||||||
// capabilities: {
|
|
||||||
// context: true
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// expect(LocationCapability.appliesTo(domainObject)).toBe(true);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// xit("does not apply to objects without context capability", function () {
|
|
||||||
// var domainObject = domainObjectFactory();
|
|
||||||
// expect(LocationCapability.appliesTo(domainObject)).toBe(false);
|
|
||||||
// });
|
|
||||||
|
|
||||||
describe("instantiated with domain object", function () {
|
describe("instantiated with domain object", function () {
|
||||||
var locationCapability,
|
var locationCapability,
|
||||||
|
persistencePromise,
|
||||||
|
mutationPromise,
|
||||||
domainObject;
|
domainObject;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
domainObject = domainObjectFactory({
|
domainObject = domainObjectFactory({
|
||||||
capabilities: {
|
capabilities: {
|
||||||
context: {
|
context: {
|
||||||
getPath: function() {
|
getParent: function() {
|
||||||
return [
|
return domainObjectFactory({id: 'root'});
|
||||||
domainObjectFactory({id: 'root'}),
|
|
||||||
domainObjectFactory({id: 'parent'}),
|
|
||||||
domainObjectFactory({id: 'me'})
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
persistence: jasmine.createSpyObj(
|
||||||
|
'persistenceCapability',
|
||||||
|
['persist']
|
||||||
|
),
|
||||||
|
mutation: jasmine.createSpyObj(
|
||||||
|
'mutationCapability',
|
||||||
|
['invoke']
|
||||||
|
)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
persistencePromise = new ControlledPromise();
|
||||||
|
domainObject.capabilities.persistence.persist.andReturn(
|
||||||
|
persistencePromise
|
||||||
|
);
|
||||||
|
|
||||||
|
mutationPromise = new ControlledPromise();
|
||||||
|
domainObject.capabilities.mutation.invoke.andCallFake(
|
||||||
|
function (mutator) {
|
||||||
|
return mutationPromise.then(function () {
|
||||||
|
mutator(domainObject.model);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
locationCapability = new LocationCapability(domainObject);
|
locationCapability = new LocationCapability(domainObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns location", function () {
|
it("returns location", function () {
|
||||||
expect(locationCapability.getLocation())
|
expect(locationCapability.getLocation())
|
||||||
.toBe('root/parent/me');
|
.toBe('root');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("knows when the object is an original", function () {
|
it("knows when the object is an original", function () {
|
||||||
domainObject.model.location = 'root/parent/me';
|
domainObject.model.location = 'root';
|
||||||
expect(locationCapability.isOriginal()).toBe(true);
|
expect(locationCapability.isOriginal()).toBe(true);
|
||||||
expect(locationCapability.isLink()).toBe(false);
|
expect(locationCapability.isLink()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("knows when the object is a link.", function () {
|
it("knows when the object is a link.", function () {
|
||||||
domainObject.model.location = 'root/another/location/me';
|
domainObject.model.location = 'different-root';
|
||||||
expect(locationCapability.isLink()).toBe(true);
|
expect(locationCapability.isLink()).toBe(true);
|
||||||
expect(locationCapability.isOriginal()).toBe(false);
|
expect(locationCapability.isOriginal()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("can persist location", function () {
|
||||||
|
var persistResult = locationCapability.persistLocation(),
|
||||||
|
whenComplete = jasmine.createSpy('whenComplete');
|
||||||
|
|
||||||
|
persistResult.then(whenComplete);
|
||||||
|
|
||||||
|
expect(domainObject.model.location).not.toBeDefined();
|
||||||
|
mutationPromise.resolve();
|
||||||
|
expect(domainObject.model.location).toBe('root');
|
||||||
|
|
||||||
|
expect(whenComplete).not.toHaveBeenCalled();
|
||||||
|
expect(domainObject.capabilities.persistence.persist)
|
||||||
|
.toHaveBeenCalled();
|
||||||
|
|
||||||
|
persistencePromise.resolve();
|
||||||
|
expect(whenComplete).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -149,9 +149,7 @@ define(
|
|||||||
newParent,
|
newParent,
|
||||||
actionCapability,
|
actionCapability,
|
||||||
locationCapability,
|
locationCapability,
|
||||||
persistenceCapability,
|
locationPromise,
|
||||||
persistencePromise,
|
|
||||||
mutationPromise,
|
|
||||||
moveResult;
|
moveResult;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
@ -164,35 +162,18 @@ define(
|
|||||||
'locationCapability',
|
'locationCapability',
|
||||||
[
|
[
|
||||||
'isOriginal',
|
'isOriginal',
|
||||||
'getLocation'
|
'persistLocation'
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
persistenceCapability = jasmine.createSpyObj(
|
locationPromise = new ControlledPromise();
|
||||||
'persistenceCapability',
|
locationCapability.persistLocation.andReturn(locationPromise);
|
||||||
['persist']
|
|
||||||
);
|
|
||||||
|
|
||||||
persistencePromise = new ControlledPromise();
|
|
||||||
persistenceCapability.persist.andReturn(persistencePromise);
|
|
||||||
|
|
||||||
mutationPromise = new ControlledPromise();
|
|
||||||
|
|
||||||
object = domainObjectFactory({
|
object = domainObjectFactory({
|
||||||
name: 'object',
|
name: 'object',
|
||||||
capabilities: {
|
capabilities: {
|
||||||
action: actionCapability,
|
action: actionCapability,
|
||||||
mutation: {
|
|
||||||
invoke: function (mutator) {
|
|
||||||
mutator(object.model);
|
|
||||||
return mutationPromise;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
persistence: persistenceCapability,
|
|
||||||
location: locationCapability
|
location: locationCapability
|
||||||
},
|
|
||||||
model: {
|
|
||||||
location: 'otherThing'
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -211,134 +192,48 @@ define(
|
|||||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("removes object when link is completed", function () {
|
|
||||||
linkService.perform.mostRecentCall.promise.resolve();
|
|
||||||
expect(object.getCapability)
|
|
||||||
.toHaveBeenCalledWith('action');
|
|
||||||
expect(actionCapability.perform)
|
|
||||||
.toHaveBeenCalledWith('remove');
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("when moving an original", function () {
|
describe("when moving an original", function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
locationCapability.isOriginal.andReturn(true);
|
locationCapability.isOriginal.andReturn(true);
|
||||||
locationCapability.getLocation.andReturn('newParent');
|
|
||||||
linkService.perform.mostRecentCall.promise.resolve();
|
linkService.perform.mostRecentCall.promise.resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("updates location", function () {
|
it("updates location", function () {
|
||||||
expect(object.model.location).toBe('newParent');
|
expect(locationCapability.persistLocation)
|
||||||
});
|
|
||||||
it("persists new model when mutation completes", function() {
|
|
||||||
mutationPromise.resolve();
|
|
||||||
expect(persistenceCapability.persist)
|
|
||||||
.toHaveBeenCalled();
|
.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("after location update", function () {
|
||||||
|
beforeEach(function () {
|
||||||
|
locationPromise.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes object from parent", function () {
|
||||||
|
expect(actionCapability.perform)
|
||||||
|
.toHaveBeenCalledWith('remove');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("when moving a link", function () {
|
describe("when moving a link", function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
locationCapability.isOriginal.andReturn(false);
|
locationCapability.isOriginal.andReturn(false);
|
||||||
locationCapability.getLocation.andReturn('newParent');
|
|
||||||
linkService.perform.mostRecentCall.promise.resolve();
|
linkService.perform.mostRecentCall.promise.resolve();
|
||||||
});
|
});
|
||||||
it("does not modify location", function() {
|
|
||||||
expect(object.model.location).toBe('otherThing');
|
it("does not update location", function () {
|
||||||
});
|
expect(locationCapability.persistLocation)
|
||||||
it("does not call persistence", function() {
|
|
||||||
expect(persistenceCapability.persist)
|
|
||||||
.not
|
.not
|
||||||
.toHaveBeenCalled();
|
.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("when moving an object with children", function() {
|
it("removes object from parent", function () {
|
||||||
|
expect(actionCapability.perform)
|
||||||
var children;
|
.toHaveBeenCalledWith('remove');
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
|
|
||||||
var instantMutator = function (index) {
|
|
||||||
return {
|
|
||||||
invoke: function (mutator) {
|
|
||||||
mutator(children[index].model);
|
|
||||||
return {
|
|
||||||
then: function(callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
children = [
|
|
||||||
domainObjectFactory({
|
|
||||||
id: 'childa',
|
|
||||||
capabilities: {
|
|
||||||
location: jasmine.createSpyObj(
|
|
||||||
'childalocation',
|
|
||||||
['isOriginal', 'getLocation']
|
|
||||||
),
|
|
||||||
mutation: instantMutator(0)
|
|
||||||
},
|
|
||||||
model: {
|
|
||||||
location: 'childa-old-location'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
domainObjectFactory({
|
|
||||||
id: 'childb',
|
|
||||||
capabilities: {
|
|
||||||
location: jasmine.createSpyObj(
|
|
||||||
'childblocation',
|
|
||||||
['isOriginal', 'getLocation']
|
|
||||||
),
|
|
||||||
mutation: instantMutator(1)
|
|
||||||
},
|
|
||||||
model: {
|
|
||||||
location: 'childb-old-location'
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
domainObjectFactory({
|
|
||||||
id: 'childc',
|
|
||||||
capabilities: {
|
|
||||||
location: jasmine.createSpyObj(
|
|
||||||
'childclocation',
|
|
||||||
['isOriginal', 'getLocation']
|
|
||||||
),
|
|
||||||
mutation: instantMutator(2)
|
|
||||||
},
|
|
||||||
model: {
|
|
||||||
location: 'childc-old-location'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
];
|
|
||||||
|
|
||||||
children[0].capabilities.location.isOriginal.andReturn(true);
|
|
||||||
children[0].capabilities.location.getLocation.andReturn('childalocation');
|
|
||||||
children[1].capabilities.location.isOriginal.andReturn(true);
|
|
||||||
children[1].capabilities.location.getLocation.andReturn('childblocation');
|
|
||||||
children[2].capabilities.location.isOriginal.andReturn(false);
|
|
||||||
children[2].capabilities.location.getLocation.andReturn('childclocation');
|
|
||||||
|
|
||||||
object.capabilities.composition = {
|
|
||||||
invoke: function () {
|
|
||||||
return {
|
|
||||||
then: function (callback) {
|
|
||||||
callback(children);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
linkService.perform.mostRecentCall.promise.resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it("recursively updates the location of originals", function () {
|
|
||||||
expect(children[0].model.location).toBe('childalocation');
|
|
||||||
expect(children[1].model.location).toBe('childblocation');
|
|
||||||
expect(children[2].model.location).toBe('childc-old-location');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user