[Plugins] Bring over timeline, clock plugins
WTD-1239
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,window,afterEach*/
|
||||
|
||||
define(
|
||||
['../../../src/controllers/graph/TimelineGraphPopulator'],
|
||||
function (TimelineGraphPopulator) {
|
||||
'use strict';
|
||||
|
||||
describe("A Timeline's resource graph populator", function () {
|
||||
var mockSwimlanes,
|
||||
mockQ,
|
||||
testResources,
|
||||
populator;
|
||||
|
||||
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;
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
testResources = {
|
||||
a: [ 'xyz', 'abc' ],
|
||||
b: [ 'xyz' ],
|
||||
c: [ 'xyz', 'abc', 'def', 'ghi' ]
|
||||
};
|
||||
|
||||
mockQ = jasmine.createSpyObj('$q', ['when', 'all']);
|
||||
|
||||
mockSwimlanes = ['a', 'b', 'c'].map(function (k) {
|
||||
var mockSwimlane = jasmine.createSpyObj(
|
||||
'swimlane-' + k,
|
||||
[ 'graph', 'color' ]
|
||||
),
|
||||
mockGraph = jasmine.createSpyObj(
|
||||
'graph-' + k,
|
||||
[ 'getPointCount', 'getDomainValue', 'getRangeValue' ]
|
||||
);
|
||||
mockSwimlane.graph.andReturn(true);
|
||||
mockSwimlane.domainObject = jasmine.createSpyObj(
|
||||
'domainObject-' + k,
|
||||
[ 'getCapability', 'hasCapability', 'useCapability', 'getId' ]
|
||||
);
|
||||
mockSwimlane.color.andReturn('#' + k);
|
||||
// Provide just enough information about graphs to support
|
||||
// determination of which graphs to show
|
||||
mockSwimlane.domainObject.useCapability.andCallFake(function () {
|
||||
var obj = {};
|
||||
testResources[k].forEach(function (r) {
|
||||
obj[r] = mockGraph;
|
||||
});
|
||||
return asPromise(obj);
|
||||
});
|
||||
mockSwimlane.domainObject.hasCapability
|
||||
.andReturn(true);
|
||||
mockSwimlane.domainObject.getId
|
||||
.andReturn(k);
|
||||
mockGraph.getPointCount.andReturn(0);
|
||||
|
||||
return mockSwimlane;
|
||||
});
|
||||
|
||||
mockQ.when.andCallFake(asPromise);
|
||||
mockQ.all.andCallFake(allPromises);
|
||||
|
||||
populator = new TimelineGraphPopulator(mockQ);
|
||||
});
|
||||
|
||||
it("provides no graphs by default", function () {
|
||||
expect(populator.get()).toEqual([]);
|
||||
});
|
||||
|
||||
it("provides one graph per resource type", function () {
|
||||
populator.populate(mockSwimlanes);
|
||||
// There are 4 unique resource types shared here...
|
||||
expect(populator.get().length).toEqual(4);
|
||||
});
|
||||
|
||||
it("does not include graphs based on swimlane configuration", function () {
|
||||
mockSwimlanes[2].graph.andReturn(false);
|
||||
populator.populate(mockSwimlanes);
|
||||
// Only two unique swimlanes in the other two
|
||||
expect(populator.get().length).toEqual(2);
|
||||
// Verify interactions as well
|
||||
expect(mockSwimlanes[0].domainObject.useCapability)
|
||||
.toHaveBeenCalledWith('graph');
|
||||
expect(mockSwimlanes[1].domainObject.useCapability)
|
||||
.toHaveBeenCalledWith('graph');
|
||||
expect(mockSwimlanes[2].domainObject.useCapability)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not recreate graphs when swimlanes don't change", function () {
|
||||
var initialValue;
|
||||
// Get an initial set of graphs
|
||||
populator.populate(mockSwimlanes);
|
||||
initialValue = populator.get();
|
||||
// Repopulate with same data; should get same graphs
|
||||
populator.populate(mockSwimlanes);
|
||||
expect(populator.get()).toBe(initialValue);
|
||||
// Something changed...
|
||||
mockSwimlanes.pop();
|
||||
populator.populate(mockSwimlanes);
|
||||
// Now we should get different graphs
|
||||
expect(populator.get()).not.toBe(initialValue);
|
||||
});
|
||||
|
||||
// Regression test for WTD-1155
|
||||
it("does recreate graphs when inclusions change", function () {
|
||||
var initialValue;
|
||||
// Get an initial set of graphs
|
||||
populator.populate(mockSwimlanes);
|
||||
initialValue = populator.get();
|
||||
// Change resource graph inclusion...
|
||||
mockSwimlanes[1].graph.andReturn(false);
|
||||
populator.populate(mockSwimlanes);
|
||||
// Now we should get different graphs
|
||||
expect(populator.get()).not.toBe(initialValue);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,56 @@
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,window,afterEach*/
|
||||
|
||||
define(
|
||||
['../../../src/controllers/graph/TimelineGraphRenderer'],
|
||||
function (TimelineGraphRenderer) {
|
||||
'use strict';
|
||||
|
||||
describe("A Timeline's graph renderer", function () {
|
||||
var renderer;
|
||||
|
||||
beforeEach(function () {
|
||||
renderer = new TimelineGraphRenderer();
|
||||
});
|
||||
|
||||
it("converts utilizations to buffers", function () {
|
||||
var utilization = {
|
||||
getPointCount: function () {
|
||||
return 10;
|
||||
},
|
||||
getDomainValue: function (i) {
|
||||
return i * 10;
|
||||
},
|
||||
getRangeValue: function (i) {
|
||||
return Math.sin(i);
|
||||
}
|
||||
},
|
||||
buffer = renderer.render(utilization),
|
||||
i;
|
||||
|
||||
// Should be flat list of alternating x/y,
|
||||
// so 20 elements
|
||||
expect(buffer.length).toEqual(20);
|
||||
|
||||
// Verify contents
|
||||
for (i = 0; i < 10; i += 1) {
|
||||
// Check for 6 decimal digits of precision, roughly
|
||||
// what we expect after conversion to 32-bit float
|
||||
expect(buffer[i * 2]).toBeCloseTo(i * 10, 6);
|
||||
expect(buffer[i * 2 + 1]).toBeCloseTo(Math.sin(i), 6);
|
||||
}
|
||||
});
|
||||
|
||||
it("decodes color strings", function () {
|
||||
// Note that decoded color should have alpha channel as well
|
||||
expect(renderer.decode('#FFFFFF'))
|
||||
.toEqual([1, 1, 1, 1]);
|
||||
expect(renderer.decode('#000000'))
|
||||
.toEqual([0, 0, 0, 1]);
|
||||
expect(renderer.decode('#FF8000'))
|
||||
.toEqual([1, 0.5019607843137255, 0, 1]);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,151 @@
|
||||
/*global define,describe,it,expect,beforeEach,waitsFor,jasmine,window,afterEach*/
|
||||
|
||||
define(
|
||||
['../../../src/controllers/graph/TimelineGraph'],
|
||||
function (TimelineGraph) {
|
||||
'use strict';
|
||||
|
||||
describe("A Timeline's resource graph", function () {
|
||||
var mockDomainObjects,
|
||||
mockRenderer,
|
||||
testColors,
|
||||
mockGraphs,
|
||||
graph;
|
||||
|
||||
function asPromise(v) {
|
||||
return (v || {}).then ? v : {
|
||||
then: function (callback) {
|
||||
return asPromise(callback(v));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
beforeEach(function () {
|
||||
testColors = {
|
||||
a: [ 0, 1, 0 ],
|
||||
b: [ 1, 0, 1 ],
|
||||
c: [ 1, 0, 0 ]
|
||||
};
|
||||
|
||||
mockGraphs = [];
|
||||
mockDomainObjects = {};
|
||||
|
||||
['a', 'b', 'c'].forEach(function (k, i) {
|
||||
var mockGraph = jasmine.createSpyObj(
|
||||
'utilization-' + k,
|
||||
[ 'getPointCount', 'getDomainValue', 'getRangeValue' ]
|
||||
);
|
||||
mockDomainObjects[k] = jasmine.createSpyObj(
|
||||
'domainObject-' + k,
|
||||
[ 'getCapability', 'useCapability' ]
|
||||
);
|
||||
mockDomainObjects[k].useCapability.andReturn(asPromise({
|
||||
testResource: mockGraph
|
||||
}));
|
||||
mockGraph.getPointCount.andReturn(i + 2);
|
||||
mockGraph.testField = k;
|
||||
mockGraph.testIndex = i;
|
||||
|
||||
// Store to allow changes later
|
||||
mockGraphs.push(mockGraph);
|
||||
});
|
||||
|
||||
mockRenderer = jasmine.createSpyObj(
|
||||
'renderer',
|
||||
[ 'render', 'decode' ]
|
||||
);
|
||||
|
||||
mockRenderer.render.andCallFake(function (utilization) {
|
||||
var result = [];
|
||||
while (result.length < (utilization.testIndex + 2) * 2) {
|
||||
result.push(Math.floor(result.length / 2));
|
||||
// Alternate +/- to give something to test to
|
||||
result.push(
|
||||
((result.length % 4 > 1) ? -1 : 1) *
|
||||
(10 * utilization.testIndex)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
|
||||
mockRenderer.decode.andCallFake(function (color) {
|
||||
return testColors[color];
|
||||
});
|
||||
|
||||
graph = new TimelineGraph(
|
||||
'testResource',
|
||||
mockDomainObjects,
|
||||
mockRenderer
|
||||
);
|
||||
});
|
||||
|
||||
it("exposes minimum/maximum", function () {
|
||||
expect(graph.minimum()).toEqual(-20);
|
||||
expect(graph.maximum()).toEqual(20);
|
||||
});
|
||||
|
||||
it("exposes resource key", function () {
|
||||
expect(graph.key).toEqual('testResource');
|
||||
});
|
||||
|
||||
it("exposes a rendered drawing object", function () {
|
||||
// Much of the work here is done by the renderer,
|
||||
// so just check that it got used and assigned
|
||||
expect(graph.drawingObject.lines).toEqual([
|
||||
{
|
||||
color: testColors.a,
|
||||
buffer: [0, 0, 1, 0],
|
||||
points: 2
|
||||
},
|
||||
{
|
||||
color: testColors.b,
|
||||
buffer: [0, 10, 1, -10, 2, 10],
|
||||
points: 3
|
||||
},
|
||||
{
|
||||
color: testColors.c,
|
||||
buffer: [0, 20, 1, -20, 2, 20, 3, -20],
|
||||
points: 4
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it("allows its bounds to be specified", function () {
|
||||
graph.setBounds(42, 12321);
|
||||
expect(graph.drawingObject.origin[0]).toEqual(42);
|
||||
expect(graph.drawingObject.dimensions[0]).toEqual(12321);
|
||||
});
|
||||
|
||||
it("provides a minimum/maximum even with no data", function () {
|
||||
mockGraphs.forEach(function (mockGraph) {
|
||||
mockGraph.getPointCount.andReturn(0);
|
||||
});
|
||||
|
||||
// Create a graph of these utilizations
|
||||
graph = new TimelineGraph(
|
||||
'testResource',
|
||||
mockDomainObjects,
|
||||
mockRenderer
|
||||
);
|
||||
|
||||
// Verify that we get some usable defaults
|
||||
expect(graph.minimum()).toEqual(jasmine.any(Number));
|
||||
expect(graph.maximum()).toEqual(jasmine.any(Number));
|
||||
expect(graph.maximum() > graph.minimum()).toBeTruthy();
|
||||
});
|
||||
|
||||
it("refreshes lines upon request", function () {
|
||||
// Mock renderer looks at testIndex, so change it here...
|
||||
mockGraphs[0].testIndex = 3;
|
||||
// Should trigger a new render
|
||||
graph.refresh();
|
||||
// Values correspond to the new index now
|
||||
expect(graph.drawingObject.lines[0].buffer).toEqual(
|
||||
[0, 30, 1, -30, 2, 30, 3, -30, 4, 30]
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user