mirror of
https://github.com/nasa/openmct.git
synced 2025-06-17 22:58:14 +00:00
[Plugins] Bring over timeline, clock plugins
WTD-1239
This commit is contained in:
@ -0,0 +1,229 @@
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,window,afterEach*/
|
||||
|
||||
define(
|
||||
['../../src/controllers/TimelineController'],
|
||||
function (TimelineController) {
|
||||
'use strict';
|
||||
|
||||
var DOMAIN_OBJECT_METHODS = [
|
||||
'getModel',
|
||||
'getId',
|
||||
'useCapability',
|
||||
'hasCapability',
|
||||
'getCapability'
|
||||
];
|
||||
|
||||
describe("The timeline controller", function () {
|
||||
var mockScope,
|
||||
mockQ,
|
||||
mockLoader,
|
||||
mockDomainObject,
|
||||
mockSpan,
|
||||
testModels,
|
||||
testConfiguration,
|
||||
controller;
|
||||
|
||||
function asPromise(v) {
|
||||
return (v || {}).then ? v : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(v));
|
||||
},
|
||||
testValue: v
|
||||
};
|
||||
}
|
||||
|
||||
function allPromises(promises) {
|
||||
return asPromise(promises.map(function (p) {
|
||||
return (p || {}).then ? p.testValue : p;
|
||||
}));
|
||||
}
|
||||
|
||||
function subgraph(domainObject, objects) {
|
||||
function lookupSubgraph(id) {
|
||||
return subgraph(objects[id], objects);
|
||||
}
|
||||
return {
|
||||
domainObject: domainObject,
|
||||
composition: (domainObject.getModel().composition || [])
|
||||
.map(lookupSubgraph)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
var mockA, mockB, mockUtilization, mockPromise, mockGraph, testCapabilities;
|
||||
|
||||
function getCapability(c) {
|
||||
return testCapabilities[c];
|
||||
}
|
||||
|
||||
function useCapability(c) {
|
||||
return c === 'timespan' ? asPromise(mockSpan) :
|
||||
c === 'graph' ? asPromise({ abc: mockGraph, xyz: mockGraph }) :
|
||||
undefined;
|
||||
}
|
||||
|
||||
testModels = {
|
||||
a: { modified: 40, composition: ['b'] },
|
||||
b: { modified: 2 }
|
||||
};
|
||||
|
||||
testConfiguration = {};
|
||||
|
||||
mockQ = jasmine.createSpyObj('$q', ['when', 'all']);
|
||||
mockA = jasmine.createSpyObj('a', DOMAIN_OBJECT_METHODS);
|
||||
mockB = jasmine.createSpyObj('b', DOMAIN_OBJECT_METHODS);
|
||||
mockSpan = jasmine.createSpyObj('span', ['getStart', 'getEnd']);
|
||||
mockUtilization = jasmine.createSpyObj('utilization', ['resources', 'utilization']);
|
||||
mockGraph = jasmine.createSpyObj('graph', ['getPointCount']);
|
||||
mockPromise = jasmine.createSpyObj('promise', ['then']);
|
||||
|
||||
mockScope = jasmine.createSpyObj(
|
||||
"$scope",
|
||||
[ '$watch', '$on' ]
|
||||
);
|
||||
mockLoader = jasmine.createSpyObj('objectLoader', ['load']);
|
||||
mockDomainObject = mockA;
|
||||
|
||||
mockScope.domainObject = mockDomainObject;
|
||||
mockScope.configuration = testConfiguration;
|
||||
mockQ.when.andCallFake(asPromise);
|
||||
mockQ.all.andCallFake(allPromises);
|
||||
mockA.getId.andReturn('a');
|
||||
mockA.getModel.andReturn(testModels.a);
|
||||
mockB.getId.andReturn('b');
|
||||
mockB.getModel.andReturn(testModels.b);
|
||||
mockA.useCapability.andCallFake(useCapability);
|
||||
mockB.useCapability.andCallFake(useCapability);
|
||||
mockA.hasCapability.andReturn(true);
|
||||
mockB.hasCapability.andReturn(true);
|
||||
mockA.getCapability.andCallFake(getCapability);
|
||||
mockB.getCapability.andCallFake(getCapability);
|
||||
mockSpan.getStart.andReturn(42);
|
||||
mockSpan.getEnd.andReturn(12321);
|
||||
mockUtilization.resources.andReturn(['abc', 'xyz']);
|
||||
mockUtilization.utilization.andReturn(mockPromise);
|
||||
mockLoader.load.andCallFake(function () {
|
||||
return asPromise(subgraph(mockA, {
|
||||
a: mockA,
|
||||
b: mockB
|
||||
}));
|
||||
});
|
||||
|
||||
testCapabilities = {
|
||||
"utilization": mockUtilization
|
||||
};
|
||||
|
||||
controller = new TimelineController(mockScope, mockQ, mockLoader, 0);
|
||||
});
|
||||
|
||||
it("exposes scroll state tracker in scope", function () {
|
||||
expect(mockScope.scroll.x).toEqual(0);
|
||||
expect(mockScope.scroll.y).toEqual(0);
|
||||
});
|
||||
|
||||
it("repopulates when modifications are made", function () {
|
||||
var fnWatchCall,
|
||||
strWatchCall;
|
||||
|
||||
// Find the $watch that was given a function
|
||||
mockScope.$watch.calls.forEach(function (call) {
|
||||
if (typeof call.args[0] === 'function') {
|
||||
// white-box: we know the first call is
|
||||
// the one we're looking for
|
||||
fnWatchCall = fnWatchCall || call;
|
||||
} else if (typeof call.args[0] === 'string') {
|
||||
strWatchCall = strWatchCall || call;
|
||||
}
|
||||
});
|
||||
|
||||
// Make sure string watch was for domainObject
|
||||
expect(strWatchCall.args[0]).toEqual('domainObject');
|
||||
// Initially populate
|
||||
strWatchCall.args[1](mockDomainObject);
|
||||
|
||||
// There should be to swimlanes
|
||||
expect(controller.swimlanes().length).toEqual(2);
|
||||
|
||||
// Watch should be for sum of modified flags...
|
||||
expect(fnWatchCall.args[0]()).toEqual(42);
|
||||
|
||||
// Remove the child, then fire the watch
|
||||
testModels.a.composition = [];
|
||||
fnWatchCall.args[1]();
|
||||
|
||||
// Swimlanes should have updated
|
||||
expect(controller.swimlanes().length).toEqual(1);
|
||||
});
|
||||
|
||||
it("repopulates graphs when graph choices change", function () {
|
||||
var tmp;
|
||||
|
||||
// Note that this test is brittle; it relies upon the
|
||||
// order of $watch calls in TimelineController.
|
||||
|
||||
// Initially populate
|
||||
mockScope.$watch.calls[0].args[1](mockDomainObject);
|
||||
|
||||
// Verify precondition - no graphs
|
||||
expect(controller.graphs().length).toEqual(0);
|
||||
|
||||
// Execute the watch function for graph state
|
||||
tmp = mockScope.$watch.calls[2].args[0]();
|
||||
|
||||
// Change graph state
|
||||
testConfiguration.graph = { a: true, b: true };
|
||||
|
||||
// Verify that this would have triggered a watch
|
||||
expect(mockScope.$watch.calls[2].args[0]())
|
||||
.not.toEqual(tmp);
|
||||
|
||||
// Run the function the watch would have triggered
|
||||
mockScope.$watch.calls[2].args[1]();
|
||||
|
||||
// Should have some graphs now
|
||||
expect(controller.graphs().length).toEqual(2);
|
||||
|
||||
});
|
||||
|
||||
it("reports full scrollable width using zoom controller", function () {
|
||||
var mockZoom = jasmine.createSpyObj('zoom', ['toPixels', 'duration']);
|
||||
mockZoom.toPixels.andReturn(54321);
|
||||
mockZoom.duration.andReturn(12345);
|
||||
|
||||
// Initially populate
|
||||
mockScope.$watch.calls[0].args[1](mockDomainObject);
|
||||
|
||||
expect(controller.width(mockZoom)).toEqual(54321);
|
||||
// Verify interactions; we took zoom's duration for our start/end,
|
||||
// and converted it to pixels.
|
||||
// First, check that we used the start/end (from above)
|
||||
expect(mockZoom.duration).toHaveBeenCalledWith(12321 - 42);
|
||||
// Next, verify that the result was passed to toPixels
|
||||
expect(mockZoom.toPixels).toHaveBeenCalledWith(12345);
|
||||
});
|
||||
|
||||
it("provides drag handles", function () {
|
||||
// TimelineDragPopulator et al are tested for these,
|
||||
// so just verify that handles are indeed exposed.
|
||||
expect(controller.handles()).toEqual(jasmine.any(Array));
|
||||
});
|
||||
|
||||
it("refreshes graphs on request", function () {
|
||||
var mockGraph = jasmine.createSpyObj('graph', ['refresh']);
|
||||
|
||||
// Sneak a mock graph into the graph populator...
|
||||
// This is whiteboxy and will have to change if
|
||||
// GraphPopulator changes
|
||||
controller.graphs().push(mockGraph);
|
||||
|
||||
// Refresh
|
||||
controller.refresh();
|
||||
|
||||
// Should have refreshed the graph
|
||||
expect(mockGraph.refresh).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
);
|
Reference in New Issue
Block a user