diff --git a/platform/commonUI/formats/src/UTCTimeFormatSpec.js b/platform/commonUI/formats/src/UTCTimeFormatSpec.js index 3d331559339..1c70f85fb0f 100644 --- a/platform/commonUI/formats/src/UTCTimeFormatSpec.js +++ b/platform/commonUI/formats/src/UTCTimeFormatSpec.js @@ -62,7 +62,7 @@ define([ it("Returns appropriate time units for a given time span", function () { var ONE_DAY = 1000 * 60 * 60 * 24; var FIVE_DAYS = 5 * ONE_DAY; - var TWO_MONTHS = 60 * ONE_DAY; + var FIVE_MONTHS = 60 * ONE_DAY; var ONE_YEAR = 365 * ONE_DAY; var SEVEN_YEARS = 7 * ONE_YEAR; @@ -72,7 +72,7 @@ define([ expect(format.timeUnits(ONE_DAY)).toEqual("Hours"); //Multiple days should display "Days" expect(format.timeUnits(FIVE_DAYS)).toEqual("Days"); - expect(format.timeUnits(TWO_MONTHS)).toEqual("Months"); + expect(format.timeUnits(FIVE_MONTHS)).toEqual("Days"); //A span of one year should show a zoom level of "Months". // Multiple years will show "Years" expect(format.timeUnits(ONE_YEAR)).toEqual("Months"); diff --git a/platform/features/conductor-v2/conductor/src/ui/ConductorAxisController.js b/platform/features/conductor-v2/conductor/src/ui/ConductorAxisController.js index f4dfeb0d338..9db3efc3a14 100644 --- a/platform/features/conductor-v2/conductor/src/ui/ConductorAxisController.js +++ b/platform/features/conductor-v2/conductor/src/ui/ConductorAxisController.js @@ -34,7 +34,6 @@ define( */ function ConductorAxisController(openmct, formatService, conductorViewService, scope, element) { // Dependencies - this.d3 = d3; this.formatService = formatService; this.conductor = openmct.conductor; this.conductorViewService = conductorViewService; @@ -70,19 +69,17 @@ define( ConductorAxisController.prototype.initialize = function (element) { this.target = element[0].firstChild; var height = this.target.offsetHeight; - var vis = this.d3.select(this.target) + var vis = d3.select(this.target) .append("svg:svg") .attr("width", "100%") .attr("height", height); - this.xAxis = this.d3.axisTop(); + this.xAxis = d3.axisTop(); // draw x axis with labels and move to the bottom of the chart area this.axisElement = vis.append("g") .attr("transform", "translate(0," + (height - PADDING) + ")"); - this.initialized = true; - if (this.timeSystem !== undefined) { this.changeTimeSystem(this.timeSystem); this.setScale(); @@ -100,7 +97,7 @@ define( ConductorAxisController.prototype.changeBounds = function (bounds) { this.bounds = bounds; - if (this.initialized && !this.zooming) { + if (!this.zooming) { this.setScale(); } }; @@ -114,13 +111,15 @@ define( var bounds = this.bounds; if (timeSystem.isUTCBased()) { - this.xScale = this.xScale || this.d3.scaleUtc(); + this.xScale = this.xScale || d3.scaleUtc(); this.xScale.domain([new Date(bounds.start), new Date(bounds.end)]); } else { - this.xScale = this.xScale || this.d3.scaleLinear(); + this.xScale = this.xScale || d3.scaleLinear(); this.xScale.domain([bounds.start, bounds.end]); } + this.xAxis.scale(this.xScale); + this.xScale.range([PADDING, width - PADDING * 2]); this.axisElement.call(this.xAxis); @@ -136,16 +135,16 @@ define( this.timeSystem = timeSystem; var key = timeSystem.formats()[0]; - if (this.initialized && key !== undefined) { + if (key !== undefined) { var format = this.formatService.getFormat(key); var bounds = this.conductor.bounds(); //The D3 scale used depends on the type of time system as d3 // supports UTC out of the box. if (timeSystem.isUTCBased()) { - this.xScale = this.d3.scaleUtc(); + this.xScale = d3.scaleUtc(); } else { - this.xScale = this.d3.scaleLinear(); + this.xScale = d3.scaleLinear(); } this.xAxis.scale(this.xScale); @@ -204,9 +203,7 @@ define( }; ConductorAxisController.prototype.resize = function () { - if (this.initialized) { - this.setScale(); - } + this.setScale(); }; return ConductorAxisController; diff --git a/platform/features/conductor-v2/conductor/src/ui/MctConductorAxisSpec.js b/platform/features/conductor-v2/conductor/src/ui/ConductorAxisControllerSpec.js similarity index 56% rename from platform/features/conductor-v2/conductor/src/ui/MctConductorAxisSpec.js rename to platform/features/conductor-v2/conductor/src/ui/ConductorAxisControllerSpec.js index 0fe3c4cf3fc..c1e2bf92a51 100644 --- a/platform/features/conductor-v2/conductor/src/ui/MctConductorAxisSpec.js +++ b/platform/features/conductor-v2/conductor/src/ui/ConductorAxisControllerSpec.js @@ -20,16 +20,33 @@ * at runtime from the About dialog for additional information. *****************************************************************************/ -define(['./MctConductorAxis'], function (MctConductorAxis) { - describe("The MctConductorAxis directive", function () { +define([ + './ConductorAxisController', + 'zepto', + 'd3' +], function ( + ConductorAxisController, + $, + d3 +) { + ddescribe("The ConductorAxisController", function () { var directive, mockConductor, + mockConductorViewService, mockFormatService, mockScope, mockElement, mockTarget, mockBounds, - d3; + element, + mockTimeSystem, + mockFormat; + + function getCallback(target, name) { + return target.calls.filter(function (call){ + return call.args[0] === name; + })[0].args[1]; + } beforeEach(function () { mockScope = jasmine.createSpyObj("scope", [ @@ -52,7 +69,8 @@ define(['./MctConductorAxis'], function (MctConductorAxis) { "timeSystem", "bounds", "on", - "off" + "off", + "follow" ]); mockConductor.bounds.andReturn(mockBounds); @@ -60,61 +78,50 @@ define(['./MctConductorAxis'], function (MctConductorAxis) { "getFormat" ]); - var d3Functions = [ - "scale", - "scaleUtc", - "scaleLinear", - "select", - "append", - "attr", - "axisTop", - "call", - "tickFormat", - "domain", - "range" - ]; - d3 = jasmine.createSpyObj("d3", d3Functions); - d3Functions.forEach(function (func) { - d3[func].andReturn(d3); - }); + mockConductorViewService = jasmine.createSpyObj("conductorViewService", [ + "on", + "off", + "emit" + ]); - directive = new MctConductorAxis(mockConductor, mockFormatService); - directive.d3 = d3; - directive.link(mockScope, [mockElement]); + spyOn(d3, 'scaleUtc').andCallThrough(); + spyOn(d3, 'scaleLinear').andCallThrough(); + + element = $('
'); + $(document).find('body').append(element); + directive = new ConductorAxisController({conductor: mockConductor}, mockFormatService, mockConductorViewService, mockScope, element); + + mockTimeSystem = jasmine.createSpyObj("timeSystem", [ + "formats", + "isUTCBased" + ]); + mockFormat = jasmine.createSpyObj("format", [ + "format" + ]); + + mockTimeSystem.formats.andReturn(["mockFormat"]); + mockFormatService.getFormat.andReturn(mockFormat); + mockConductor.timeSystem.andReturn(mockTimeSystem); + mockTimeSystem.isUTCBased.andReturn(false); }); it("listens for changes to time system and bounds", function () { expect(mockConductor.on).toHaveBeenCalledWith("timeSystem", directive.changeTimeSystem); - expect(mockConductor.on).toHaveBeenCalledWith("bounds", directive.setScale); + expect(mockConductor.on).toHaveBeenCalledWith("bounds", directive.changeBounds); }); it("on scope destruction, deregisters listeners", function () { expect(mockScope.$on).toHaveBeenCalledWith("$destroy", directive.destroy); directive.destroy(); expect(mockConductor.off).toHaveBeenCalledWith("timeSystem", directive.changeTimeSystem); - expect(mockConductor.off).toHaveBeenCalledWith("bounds", directive.setScale); + expect(mockConductor.off).toHaveBeenCalledWith("bounds", directive.changeBounds); }); describe("when the time system changes", function () { - var mockTimeSystem; - var mockFormat; - - beforeEach(function () { - mockTimeSystem = jasmine.createSpyObj("timeSystem", [ - "formats", - "isUTCBased" - ]); - mockFormat = jasmine.createSpyObj("format", [ - "format" - ]); - - mockTimeSystem.formats.andReturn(["mockFormat"]); - mockFormatService.getFormat.andReturn(mockFormat); - }); - it("uses a UTC scale for UTC time systems", function () { mockTimeSystem.isUTCBased.andReturn(true); directive.changeTimeSystem(mockTimeSystem); + expect(d3.scaleUtc).toHaveBeenCalled(); expect(d3.scaleLinear).not.toHaveBeenCalled(); }); @@ -128,19 +135,46 @@ define(['./MctConductorAxis'], function (MctConductorAxis) { it("sets axis domain to time conductor bounds", function () { mockTimeSystem.isUTCBased.andReturn(false); - mockConductor.timeSystem.andReturn(mockTimeSystem); - directive.setScale(); - expect(d3.domain).toHaveBeenCalledWith([mockBounds.start, mockBounds.end]); + expect(directive.xScale.domain()).toEqual([mockBounds.start, mockBounds.end]); }); it("uses the format specified by the time system to format tick" + " labels", function () { + directive.changeTimeSystem(mockTimeSystem); - expect(d3.tickFormat).toHaveBeenCalled(); - d3.tickFormat.mostRecentCall.args[0](); expect(mockFormat.format).toHaveBeenCalled(); + + }); + + it('responds to zoom events', function () { + expect(mockConductorViewService.on).toHaveBeenCalledWith("zoom", directive.onZoom); + var cb = getCallback(mockConductorViewService.on, "zoom"); + spyOn(directive, 'setScale').andCallThrough(); + cb({bounds: {start: 0, end: 100}}); + expect(directive.setScale).toHaveBeenCalled(); + }); + + it('adjusts scale on pan', function () { + spyOn(directive, 'setScale').andCallThrough(); + directive.pan(100); + expect(directive.setScale).toHaveBeenCalled(); }); + + it('emits event on pan', function () { + spyOn(directive,'setScale').andCallThrough(); + directive.pan(100); + expect(mockConductorViewService.emit).toHaveBeenCalledWith("pan", jasmine.any(Object)); + }); + + it('cleans up listeners on destruction', function () { + directive.destroy(); + expect(mockConductor.off).toHaveBeenCalledWith("bounds", directive.changeBounds); + expect(mockConductor.off).toHaveBeenCalledWith("timeSystem", directive.changeTimeSystem); + + expect(mockConductorViewService.off).toHaveBeenCalledWith("zoom", directive.onZoom); + }); + }); }); });