[Inspector] Add check to prevent race condition before setting the scope composition. (#1931)

Fixes #1918
This commit is contained in:
Pegah Sarram 2018-02-28 13:38:00 -08:00 committed by GitHub
parent 0225cbab6a
commit 6145843e86
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 4 deletions

View File

@ -88,11 +88,15 @@ define(
* @private * @private
*/ */
ElementsController.prototype.refreshComposition = function (domainObject) { ElementsController.prototype.refreshComposition = function (domainObject) {
var selectedObjectComposition = domainObject && domainObject.useCapability('composition'); var refreshTracker = {};
this.currentRefresh = refreshTracker;
var selectedObjectComposition = domainObject && domainObject.useCapability('composition');
if (selectedObjectComposition) { if (selectedObjectComposition) {
selectedObjectComposition.then(function (composition) { selectedObjectComposition.then(function (composition) {
if (this.currentRefresh === refreshTracker) {
this.scope.composition = composition; this.scope.composition = composition;
}
}.bind(this)); }.bind(this));
} else { } else {
this.scope.composition = []; this.scope.composition = [];

View File

@ -31,11 +31,34 @@ define(
mockSelection, mockSelection,
mockDomainObject, mockDomainObject,
mockMutationCapability, mockMutationCapability,
mockCompositionCapability,
mockCompositionObjects,
mockComposition,
mockUnlisten, mockUnlisten,
selectable = [], selectable = [],
controller; controller;
function mockPromise(value) {
return {
then: function (thenFunc) {
return mockPromise(thenFunc(value));
}
};
}
function createDomainObject() {
return {
useCapability: function () {
return mockCompositionCapability;
}
};
}
beforeEach(function () { beforeEach(function () {
mockComposition = ["a", "b"];
mockCompositionObjects = mockComposition.map(createDomainObject);
mockCompositionCapability = mockPromise(mockCompositionObjects);
mockUnlisten = jasmine.createSpy('unlisten'); mockUnlisten = jasmine.createSpy('unlisten');
mockMutationCapability = jasmine.createSpyObj("mutationCapability", [ mockMutationCapability = jasmine.createSpyObj("mutationCapability", [
"listen" "listen"
@ -45,7 +68,7 @@ define(
"getCapability", "getCapability",
"useCapability" "useCapability"
]); ]);
mockDomainObject.useCapability.andCallThrough(); mockDomainObject.useCapability.andReturn(mockCompositionCapability);
mockDomainObject.getCapability.andReturn(mockMutationCapability); mockDomainObject.getCapability.andReturn(mockMutationCapability);
mockScope = jasmine.createSpyObj("$scope", ['$on']); mockScope = jasmine.createSpyObj("$scope", ['$on']);
@ -65,7 +88,7 @@ define(
} }
}; };
spyOn(ElementsController.prototype, 'refreshComposition'); spyOn(ElementsController.prototype, 'refreshComposition').andCallThrough();
controller = new ElementsController(mockScope, mockOpenMCT); controller = new ElementsController(mockScope, mockOpenMCT);
}); });
@ -137,6 +160,25 @@ define(
expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation'); expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation');
}); });
it("checks concurrent changes to composition", function () {
var secondMockComposition = ["a", "b", "c"],
secondMockCompositionObjects = secondMockComposition.map(createDomainObject),
firstCompositionCallback,
secondCompositionCallback;
spyOn(mockCompositionCapability, "then").andCallThrough();
controller.refreshComposition(mockDomainObject);
controller.refreshComposition(mockDomainObject);
firstCompositionCallback = mockCompositionCapability.then.calls[0].args[0];
secondCompositionCallback = mockCompositionCapability.then.calls[1].args[0];
secondCompositionCallback(secondMockCompositionObjects);
firstCompositionCallback(mockCompositionObjects);
expect(mockScope.composition).toBe(secondMockCompositionObjects);
});
}); });
} }
); );