mirror of
https://github.com/nasa/openmct.git
synced 2024-12-30 09:58:52 +00:00
[Plot] Fill in specs
Fill in specs for elements used by the PlotController in order to improve coverage of the plot bundle. WTD-533.
This commit is contained in:
parent
ae05ed903b
commit
2f475fc17a
@ -17,23 +17,18 @@ define(
|
||||
min = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||
x,
|
||||
y,
|
||||
xLabels = {},
|
||||
yLabels = {},
|
||||
yUnits = {},
|
||||
domainOffset = Number.POSITIVE_INFINITY,
|
||||
buffers;
|
||||
|
||||
datas = datas || [];
|
||||
// Remove any undefined data sets
|
||||
datas = (datas || []).filter(identity);
|
||||
|
||||
datas.filter(identity).forEach(function (data) {
|
||||
// Filter out un
|
||||
datas.forEach(function (data) {
|
||||
domainOffset = Math.min(data.getDomainValue(0, domain), domainOffset);
|
||||
});
|
||||
|
||||
datas.forEach(function (data, i) {
|
||||
if (!data) {
|
||||
return; // skip null data
|
||||
}
|
||||
|
||||
vertices.push([]);
|
||||
for (index = 0; index < data.getPointCount(); index = index + 1) {
|
||||
x = data.getDomainValue(index, domain);
|
||||
@ -45,18 +40,6 @@ define(
|
||||
max[0] = Math.max(max[0], x);
|
||||
max[1] = Math.max(max[1], y);
|
||||
}
|
||||
|
||||
if (data.getDomainLabel) {
|
||||
xLabels[data.getDomainLabel(domain)] = true;
|
||||
}
|
||||
|
||||
if (data.getRangeLabel) {
|
||||
yLabels[data.getRangeLabel(range)] = true;
|
||||
}
|
||||
|
||||
if (data.getRangeUnits) {
|
||||
yUnits[data.getRangeUnits(range)] = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (max[1] === min[1]) {
|
||||
@ -64,10 +47,6 @@ define(
|
||||
min[1] = min[1] - 1.0;
|
||||
}
|
||||
|
||||
xLabels = Object.keys(xLabels).sort();
|
||||
yLabels = Object.keys(yLabels).sort();
|
||||
yUnits = Object.keys(yUnits).sort();
|
||||
|
||||
buffers = vertices.map(function (v) { return new Float32Array(v); });
|
||||
|
||||
return {
|
||||
|
@ -9,6 +9,54 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("A plot axis", function () {
|
||||
var testMetadatas = [
|
||||
{
|
||||
tests: [
|
||||
{ key: "t0", name: "T0" },
|
||||
{ key: "t1", name: "T1" }
|
||||
],
|
||||
someKey: "some value"
|
||||
},
|
||||
{
|
||||
tests: [
|
||||
{ key: "t0", name: "T0" },
|
||||
{ key: "t2", name: "T2" }
|
||||
]
|
||||
},
|
||||
{
|
||||
tests: [
|
||||
{ key: "t3", name: "T3" },
|
||||
{ key: "t4", name: "T4" },
|
||||
{ key: "t5", name: "T5" },
|
||||
{ key: "t6", name: "T6" }
|
||||
]
|
||||
}
|
||||
],
|
||||
testDefault = { key: "test", name: "Test" },
|
||||
controller = new PlotAxis("tests", testMetadatas, testDefault);
|
||||
|
||||
it("pulls out a list of domain or range options", function () {
|
||||
// Should have filtered out duplicates, etc
|
||||
expect(controller.options).toEqual([
|
||||
{ key: "t0", name: "T0" },
|
||||
{ key: "t1", name: "T1" },
|
||||
{ key: "t2", name: "T2" },
|
||||
{ key: "t3", name: "T3" },
|
||||
{ key: "t4", name: "T4" },
|
||||
{ key: "t5", name: "T5" },
|
||||
{ key: "t6", name: "T6" }
|
||||
]);
|
||||
});
|
||||
|
||||
it("chooses the first option as a default", function () {
|
||||
expect(controller.active).toEqual({ key: "t0", name: "T0" });
|
||||
});
|
||||
|
||||
it("falls back to a provided default if no options are present", function () {
|
||||
expect(new PlotAxis("tests", [{}], testDefault).active)
|
||||
.toEqual(testDefault);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -9,6 +9,21 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("The plot formatter", function () {
|
||||
var formatter;
|
||||
|
||||
beforeEach(function () {
|
||||
formatter = new PlotFormatter();
|
||||
});
|
||||
|
||||
it("formats domains using YYYY-DDD style", function () {
|
||||
expect(formatter.formatDomainValue(402513731000)).toEqual(
|
||||
"1982-276 17:22:11"
|
||||
);
|
||||
});
|
||||
|
||||
it("formats ranges as values", function () {
|
||||
expect(formatter.formatRangeValue(10)).toEqual("10.0");
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -9,6 +9,96 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("The plot palette", function () {
|
||||
it("can be used as a constructor", function () {
|
||||
// PlotPalette has all static methods, so make
|
||||
// sure it returns itself if used as a constructor.
|
||||
expect(new PlotPalette()).toBe(PlotPalette);
|
||||
});
|
||||
|
||||
it("has 30 unique colors in an integer format", function () {
|
||||
// Integer format may be useful internal to the application.
|
||||
// RGB 0-255
|
||||
var i, j;
|
||||
|
||||
// Used to verify one of R, G, B in loop below
|
||||
function verifyChannel(c) {
|
||||
expect(typeof c).toEqual("number");
|
||||
expect(c <= 255).toBeTruthy();
|
||||
expect(c >= 0).toBeTruthy();
|
||||
}
|
||||
|
||||
for (i = 0; i < 30; i += 1) {
|
||||
// Verify that we got an array of numbers
|
||||
expect(Array.isArray(PlotPalette.getIntegerColor(i)))
|
||||
.toBeTruthy();
|
||||
expect(PlotPalette.getIntegerColor(i).length).toEqual(3);
|
||||
|
||||
// Verify all three channels for type and range
|
||||
PlotPalette.getIntegerColor(i).forEach(verifyChannel);
|
||||
|
||||
// Verify uniqueness
|
||||
for (j = i + 1; j < 30; j += 1) {
|
||||
expect(PlotPalette.getIntegerColor(i)).not.toEqual(
|
||||
PlotPalette.getIntegerColor(j)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("has 30 unique colors in a floating-point format", function () {
|
||||
// Float format is useful to WebGL.
|
||||
// RGB 0.0-1.1
|
||||
var i, j;
|
||||
|
||||
// Used to verify one of R, G, B in loop below
|
||||
function verifyChannel(c) {
|
||||
expect(typeof c).toEqual("number");
|
||||
expect(c <= 1.0).toBeTruthy();
|
||||
expect(c >= 0.0).toBeTruthy();
|
||||
}
|
||||
|
||||
for (i = 0; i < 30; i += 1) {
|
||||
// Verify that we got an array of numbers
|
||||
expect(Array.isArray(PlotPalette.getFloatColor(i)))
|
||||
.toBeTruthy();
|
||||
expect(PlotPalette.getFloatColor(i).length).toEqual(4);
|
||||
|
||||
// Verify all three channels for type and range
|
||||
PlotPalette.getFloatColor(i).forEach(verifyChannel);
|
||||
|
||||
// Verify uniqueness
|
||||
for (j = i + 1; j < 30; j += 1) {
|
||||
expect(PlotPalette.getFloatColor(i)).not.toEqual(
|
||||
PlotPalette.getFloatColor(j)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("has 30 unique colors in a string format", function () {
|
||||
// String format is useful in stylesheets
|
||||
// #RRGGBB in hex
|
||||
var i, j, c;
|
||||
|
||||
|
||||
for (i = 0; i < 30; i += 1) {
|
||||
c = PlotPalette.getStringColor(i);
|
||||
|
||||
// Verify that we #-style color strings
|
||||
expect(typeof c).toEqual('string');
|
||||
expect(c.length).toEqual(7);
|
||||
expect(/^#[0-9a-fA-F]+$/.test(c)).toBeTruthy();
|
||||
|
||||
// Verify uniqueness
|
||||
for (j = i + 1; j < 30; j += 1) {
|
||||
expect(PlotPalette.getStringColor(i)).not.toEqual(
|
||||
PlotPalette.getStringColor(j)
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -9,6 +9,72 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("A plot pan-zoom stack", function () {
|
||||
var panZoomStack,
|
||||
initialOrigin,
|
||||
initialDimensions,
|
||||
otherOrigins,
|
||||
otherDimensions;
|
||||
|
||||
// Shorthand for verifying getOrigin, getDimensions, and getPanZoom,
|
||||
// which should always agree.
|
||||
function verifyPanZoom(origin, dimensions) {
|
||||
expect(panZoomStack.getOrigin()).toEqual(origin);
|
||||
expect(panZoomStack.getDimensions()).toEqual(dimensions);
|
||||
expect(panZoomStack.getPanZoom()).toEqual({
|
||||
origin: origin,
|
||||
dimensions: dimensions
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
initialOrigin = [ 4, 2 ];
|
||||
initialDimensions = [ 600, 400 ];
|
||||
otherOrigins = [ [8, 6], [12, 9] ];
|
||||
otherDimensions = [ [400, 300], [200, 300] ];
|
||||
panZoomStack =
|
||||
new PlotPanZoomStack(initialOrigin, initialDimensions);
|
||||
});
|
||||
|
||||
it("starts off reporting its initial values", function () {
|
||||
verifyPanZoom(initialOrigin, initialDimensions);
|
||||
});
|
||||
|
||||
it("allows origin/dimensions pairs to be pushed/popped", function () {
|
||||
panZoomStack.pushPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
verifyPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
panZoomStack.pushPanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
verifyPanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
panZoomStack.popPanZoom();
|
||||
verifyPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
panZoomStack.popPanZoom();
|
||||
verifyPanZoom(initialOrigin, initialDimensions);
|
||||
});
|
||||
|
||||
it("reports current stack depth", function () {
|
||||
expect(panZoomStack.getDepth()).toEqual(1);
|
||||
panZoomStack.pushPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
expect(panZoomStack.getDepth()).toEqual(2);
|
||||
panZoomStack.pushPanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
expect(panZoomStack.getDepth()).toEqual(3);
|
||||
});
|
||||
|
||||
it("allows base pan zoom to be restored", function () {
|
||||
panZoomStack.pushPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
panZoomStack.pushPanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
panZoomStack.clearPanZoom();
|
||||
verifyPanZoom(initialOrigin, initialDimensions);
|
||||
});
|
||||
|
||||
it("allows base pan zoom to be changed", function () {
|
||||
panZoomStack.pushPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
panZoomStack.setBasePanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
// Should not have changed current top-of-stack
|
||||
verifyPanZoom(otherOrigins[0], otherDimensions[0]);
|
||||
|
||||
// Clear the stack - should be at our new base pan-zoom state
|
||||
panZoomStack.clearPanZoom();
|
||||
verifyPanZoom(otherOrigins[1], otherDimensions[1]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -9,6 +9,40 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("A plot position", function () {
|
||||
var mockPanZoom,
|
||||
testOrigin = [ 10, 20 ],
|
||||
testDimensions = [ 800, 10 ];
|
||||
|
||||
beforeEach(function () {
|
||||
mockPanZoom = jasmine.createSpyObj(
|
||||
"panZoomStack",
|
||||
[ "getPanZoom" ]
|
||||
);
|
||||
mockPanZoom.getPanZoom.andReturn({
|
||||
origin: testOrigin,
|
||||
dimensions: testDimensions
|
||||
});
|
||||
});
|
||||
|
||||
it("transforms pixel coordinates to domain-range", function () {
|
||||
var position = new PlotPosition(42, 450, 100, 1000, mockPanZoom);
|
||||
// Domain: .42 * 800 + 10 = 346
|
||||
// Range: .55 * 10 + 20 = 25.5
|
||||
// Notably, y-axis is reversed between pixel space and range
|
||||
expect(position.getPosition()).toEqual([346, 25.5]);
|
||||
expect(position.getDomain()).toEqual(346);
|
||||
expect(position.getRange()).toEqual(25.5);
|
||||
});
|
||||
|
||||
it("treats a position as undefined if no pan-zoom state is present", function () {
|
||||
var position;
|
||||
|
||||
mockPanZoom.getPanZoom.andReturn({});
|
||||
position = new PlotPosition(1, 2, 100, 100, mockPanZoom);
|
||||
expect(position.getDomain()).toBeUndefined();
|
||||
expect(position.getRange()).toBeUndefined();
|
||||
expect(position.getPosition()).toEqual([]);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -8,7 +8,58 @@ define(
|
||||
function (PlotPreparer) {
|
||||
"use strict";
|
||||
|
||||
var START = 123456;
|
||||
|
||||
describe("A plot preparer", function () {
|
||||
|
||||
function makeMockData(scale) {
|
||||
var mockData = jasmine.createSpyObj(
|
||||
"data" + scale,
|
||||
[ "getPointCount", "getDomainValue", "getRangeValue" ]
|
||||
);
|
||||
mockData.getPointCount.andReturn(1000);
|
||||
mockData.getDomainValue.andCallFake(function (i) {
|
||||
return START + i * 1000;
|
||||
});
|
||||
mockData.getRangeValue.andCallFake(function (i) {
|
||||
return Math.sin(i / 100) * scale;
|
||||
});
|
||||
return mockData;
|
||||
}
|
||||
|
||||
it("fits to provided data sets", function () {
|
||||
var datas = [1, 2, 3].map(makeMockData),
|
||||
preparer = new PlotPreparer(datas);
|
||||
|
||||
expect(preparer.getDomainOffset()).toEqual(START);
|
||||
expect(preparer.getOrigin()[0]).toBeCloseTo(START, 3);
|
||||
expect(preparer.getOrigin()[1]).toBeCloseTo(-3, 3);
|
||||
expect(preparer.getDimensions()[0]).toBeCloseTo(999000, 3);
|
||||
expect(preparer.getDimensions()[1]).toBeCloseTo(6, 3);
|
||||
});
|
||||
|
||||
it("looks up values using a specified domain and range", function () {
|
||||
var datas = [makeMockData(1)],
|
||||
preparer = new PlotPreparer(datas, "testDomain", "testRange");
|
||||
|
||||
expect(datas[0].getDomainValue).toHaveBeenCalledWith(
|
||||
jasmine.any(Number),
|
||||
"testDomain"
|
||||
);
|
||||
|
||||
expect(datas[0].getRangeValue).toHaveBeenCalledWith(
|
||||
jasmine.any(Number),
|
||||
"testRange"
|
||||
);
|
||||
});
|
||||
|
||||
it("provides a default range if data set is flat", function () {
|
||||
var datas = [makeMockData(0)],
|
||||
preparer = new PlotPreparer(datas);
|
||||
|
||||
expect(preparer.getDimensions[1]).not.toEqual(0);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -9,6 +9,46 @@ define(
|
||||
"use strict";
|
||||
|
||||
describe("A plot tick generator", function () {
|
||||
var mockPanZoomStack,
|
||||
mockFormatter,
|
||||
generator;
|
||||
|
||||
beforeEach(function () {
|
||||
mockPanZoomStack = jasmine.createSpyObj(
|
||||
"panZoomStack",
|
||||
[ "getPanZoom" ]
|
||||
);
|
||||
mockFormatter = jasmine.createSpyObj(
|
||||
"formatter",
|
||||
[ "formatDomainValue", "formatRangeValue" ]
|
||||
);
|
||||
|
||||
mockPanZoomStack.getPanZoom.andReturn({
|
||||
origin: [ 0, 0 ],
|
||||
dimensions: [ 100, 100 ]
|
||||
});
|
||||
|
||||
generator =
|
||||
new PlotTickGenerator(mockPanZoomStack, mockFormatter);
|
||||
});
|
||||
|
||||
it("provides tick marks for range", function () {
|
||||
expect(generator.generateRangeTicks(11).length).toEqual(11);
|
||||
|
||||
// Should have used range formatter
|
||||
expect(mockFormatter.formatRangeValue).toHaveBeenCalled();
|
||||
expect(mockFormatter.formatDomainValue).not.toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it("provides tick marks for domain", function () {
|
||||
expect(generator.generateDomainTicks(11).length).toEqual(11);
|
||||
|
||||
// Should have used domain formatter
|
||||
expect(mockFormatter.formatRangeValue).not.toHaveBeenCalled();
|
||||
expect(mockFormatter.formatDomainValue).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
Loading…
Reference in New Issue
Block a user