Unit test for animated zooms.
[dygraphs.git] / auto_tests / tests / interaction_model.js
index 7391061..41d0e43 100644 (file)
@@ -3,14 +3,14 @@
  *
  * @author konigsberg@google.com (Robert Konigsbrg)
  */
-var InteractionModelTestCase = TestCase("interaction-model");
+describe("interaction-model", function() {
 
-InteractionModelTestCase.prototype.setUp = function() {
+beforeEach(function() {
   document.body.innerHTML = "<div id='graph'></div>";
-};
+});
 
-InteractionModelTestCase.prototype.tearDown = function() {
-};
+afterEach(function() {
+});
 
 var data1 = "X,Y\n" +
     "20,-1\n" +
@@ -38,7 +38,8 @@ function getXLabels() {
   return ary;
 }
 
-InteractionModelTestCase.prototype.pan = function(g, xRange, yRange) {
+/*
+it('testPan', function() {
   var originalXRange = g.xAxisRange();
   var originalYRange = g.yAxisRange(0);
 
@@ -46,23 +47,24 @@ InteractionModelTestCase.prototype.pan = function(g, xRange, yRange) {
   DygraphOps.dispatchMouseMove(g, xRange[1], yRange[0]); // this is really necessary.
   DygraphOps.dispatchMouseUp(g, xRange[1], yRange[0]);
 
-  assertEqualsDelta(xRange, g.xAxisRange(), 0.2);
-  // assertEqualsDelta(originalYRange, g.yAxisRange(0), 0.2); // Not true, it's something in the middle.
+  assert.closeTo(xRange, g.xAxisRange(), 0.2);
+  // assert.closeTo(originalYRange, g.yAxisRange(0), 0.2); // Not true, it's something in the middle.
 
   var midX = (xRange[1] - xRange[0]) / 2;
   DygraphOps.dispatchMouseDown(g, midX, yRange[0]);
   DygraphOps.dispatchMouseMove(g, midX, yRange[1]); // this is really necessary.
   DygraphOps.dispatchMouseUp(g, midX, yRange[1]);
 
-  assertEqualsDelta(xRange, g.xAxisRange(), 0.2);
-  assertEqualsDelta(yRange, g.yAxisRange(0), 0.2);
-}
+  assert.closeTo(xRange, g.xAxisRange(), 0.2);
+  assert.closeTo(yRange, g.yAxisRange(0), 0.2);
+});
+*/
 
 /**
  * This tests that when changing the interaction model so pan is used instead
  * of zoom as the default behavior, a standard click method is still called.
  */
-InteractionModelTestCase.prototype.testClickCallbackIsCalled = function() {
+it('testClickCallbackIsCalled', function() {
   var clicked;
 
   var clickCallback = function(event, x) {
@@ -81,14 +83,14 @@ InteractionModelTestCase.prototype.testClickCallbackIsCalled = function() {
   DygraphOps.dispatchMouseMove_Point(g, 10, 10);
   DygraphOps.dispatchMouseUp_Point(g, 10, 10);
 
-  assertEquals(20, clicked);
-};
+  assert.equal(20, clicked);
+});
 
 /**
  * This tests that when changing the interaction model so pan is used instead
  * of zoom as the default behavior, a standard click method is still called.
  */
-InteractionModelTestCase.prototype.testClickCallbackIsCalledOnCustomPan = function() {
+it('testClickCallbackIsCalledOnCustomPan', function() {
   var clicked;
 
   var clickCallback = function(event, x) {
@@ -126,19 +128,19 @@ InteractionModelTestCase.prototype.testClickCallbackIsCalledOnCustomPan = functi
   DygraphOps.dispatchMouseMove_Point(g, 10, 10);
   DygraphOps.dispatchMouseUp_Point(g, 10, 10);
 
-  assertEquals(20, clicked);
-};
+  assert.equal(20, clicked);
+});
 
-InteractionModelTestCase.clickAt = function(g, x, y) {
+var clickAt = function(g, x, y) {
   DygraphOps.dispatchMouseDown(g, x, y);
   DygraphOps.dispatchMouseMove(g, x, y);
   DygraphOps.dispatchMouseUp(g, x, y);
-}
+};
 
 /**
  * This tests that clickCallback is still called with the nonInteractiveModel.
  */
-InteractionModelTestCase.prototype.testClickCallbackIsCalledWithNonInteractiveModel = function() {
+it('testClickCallbackIsCalledWithNonInteractiveModel', function() {
   var clicked;
 
   // TODO(danvk): also test pointClickCallback here.
@@ -160,13 +162,13 @@ InteractionModelTestCase.prototype.testClickCallbackIsCalledWithNonInteractiveMo
   DygraphOps.dispatchMouseMove_Point(g, 10, 10);
   DygraphOps.dispatchMouseUp_Point(g, 10, 10);
 
-  assertEquals(20, clicked);
-};
+  assert.equal(20, clicked);
+});
 
 /**
  * A sanity test to ensure pointClickCallback is called.
  */
-InteractionModelTestCase.prototype.testPointClickCallback = function() {
+it('testPointClickCallback', function() {
   var clicked;
   var g = new Dygraph(document.getElementById("graph"), data2, {
     pointClickCallback : function(event, point) {
@@ -174,16 +176,16 @@ InteractionModelTestCase.prototype.testPointClickCallback = function() {
     }
   });
 
-  InteractionModelTestCase.clickAt(g, 4, 40);
+  clickAt(g, 4, 40);
 
-  assertEquals(4, clicked.xval);
-  assertEquals(40, clicked.yval);
-};
+  assert.equal(4, clicked.xval);
+  assert.equal(40, clicked.yval);
+});
 
 /**
  * A sanity test to ensure pointClickCallback is not called when out of range.
  */
-InteractionModelTestCase.prototype.testNoPointClickCallbackWhenOffPoint = function() {
+it('testNoPointClickCallbackWhenOffPoint', function() {
   var clicked;
   var g = new Dygraph(document.getElementById("graph"), data2, {
     pointClickCallback : function(event, point) {
@@ -191,22 +193,22 @@ InteractionModelTestCase.prototype.testNoPointClickCallbackWhenOffPoint = functi
     }
   });
 
-  InteractionModelTestCase.clickAt(g, 5, 40);
+  clickAt(g, 5, 40);
 
-  assertUndefined(clicked);
-};
+  assert.isUndefined(clicked);
+});
 
 /**
  * Ensures pointClickCallback circle size is taken into account.
  */
-InteractionModelTestCase.prototype.testPointClickCallback_circleSize = function() {
+it('testPointClickCallback_circleSize', function() {
   // TODO(konigsberg): Implement.
-};
+});
 
 /**
  * Ensures that pointClickCallback is called prior to clickCallback
  */
-InteractionModelTestCase.prototype.testPointClickCallbackCalledPriorToClickCallback = function() {
+it('testPointClickCallbackCalledPriorToClickCallback', function() {
   var counter = 0;
   var pointClicked;
   var clicked;
@@ -221,16 +223,16 @@ InteractionModelTestCase.prototype.testPointClickCallbackCalledPriorToClickCallb
     }
   });
 
-  InteractionModelTestCase.clickAt(g, 4, 40);
-  assertEquals(1, pointClicked);
-  assertEquals(2, clicked);
-};
+  clickAt(g, 4, 40);
+  assert.equal(1, pointClicked);
+  assert.equal(2, clicked);
+});
 
 /**
  * Ensures that when there's no pointClickCallback, clicking on a point still calls
  * clickCallback
  */
-InteractionModelTestCase.prototype.testClickCallback_clickOnPoint = function() {
+it('testClickCallback_clickOnPoint', function() {
   var clicked;
   var g = new Dygraph(document.getElementById("graph"), data2, {
     clickCallback : function(event, point) {
@@ -238,121 +240,126 @@ InteractionModelTestCase.prototype.testClickCallback_clickOnPoint = function() {
     }
   });
 
-  InteractionModelTestCase.clickAt(g, 4, 40);
-  assertEquals(1, clicked);
-};
+  clickAt(g, 4, 40);
+  assert.equal(1, clicked);
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_none = function() {
+it('testIsZoomed_none', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
-  assertFalse(g.isZoomed());
-  assertFalse(g.isZoomed("x"));
-  assertFalse(g.isZoomed("y"));
-};
+  assert.isFalse(g.isZoomed());
+  assert.isFalse(g.isZoomed("x"));
+  assert.isFalse(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_x = function() {
+it('testIsZoomed_x', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
-  DygraphOps.dispatchMouseDown_Point(g, 10, 10);
-  DygraphOps.dispatchMouseMove_Point(g, 30, 10);
-  DygraphOps.dispatchMouseUp_Point(g, 30, 10);
+  DygraphOps.dispatchMouseDown_Point(g, 100, 100);
+  DygraphOps.dispatchMouseMove_Point(g, 130, 100);
+  DygraphOps.dispatchMouseUp_Point(g, 130, 100);
 
-  assertTrue(g.isZoomed());
-  assertTrue(g.isZoomed("x"));
-  assertFalse(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isTrue(g.isZoomed("x"));
+  assert.isFalse(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_y = function() {
+it('testIsZoomed_y', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   DygraphOps.dispatchMouseDown_Point(g, 10, 10);
   DygraphOps.dispatchMouseMove_Point(g, 10, 30);
   DygraphOps.dispatchMouseUp_Point(g, 10, 30);
 
-  assertTrue(g.isZoomed());
-  assertFalse(g.isZoomed("x"));
-  assertTrue(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isFalse(g.isZoomed("x"));
+  assert.isTrue(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_both = function() {
+it('testIsZoomed_both', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   // Zoom x axis
-  DygraphOps.dispatchMouseDown_Point(g, 10, 10);
-  DygraphOps.dispatchMouseMove_Point(g, 30, 10);
-  DygraphOps.dispatchMouseUp_Point(g, 30, 10);
+  DygraphOps.dispatchMouseDown_Point(g, 100, 100);
+  DygraphOps.dispatchMouseMove_Point(g, 130, 100);
+  DygraphOps.dispatchMouseUp_Point(g, 130, 100);
 
   // Now zoom y axis
-  DygraphOps.dispatchMouseDown_Point(g, 10, 10);
-  DygraphOps.dispatchMouseMove_Point(g, 1030);
-  DygraphOps.dispatchMouseUp_Point(g, 1030);
+  DygraphOps.dispatchMouseDown_Point(g, 100, 100);
+  DygraphOps.dispatchMouseMove_Point(g, 100, 130);
+  DygraphOps.dispatchMouseUp_Point(g, 100, 130);
 
 
-  assertTrue(g.isZoomed());
-  assertTrue(g.isZoomed("x"));
-  assertTrue(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isTrue(g.isZoomed("x"));
+  assert.isTrue(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_updateOptions_none = function() {
+it('testIsZoomed_updateOptions_none', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   g.updateOptions({});
 
-  assertFalse(g.isZoomed());
-  assertFalse(g.isZoomed("x"));
-  assertFalse(g.isZoomed("y"));
-};
+  assert.isFalse(g.isZoomed());
+  assert.isFalse(g.isZoomed("x"));
+  assert.isFalse(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_updateOptions_x = function() {
+it('testIsZoomed_updateOptions_x', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   g.updateOptions({dateWindow: [-.5, .3]});
-  assertTrue(g.isZoomed());
-  assertTrue(g.isZoomed("x"));
-  assertFalse(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isTrue(g.isZoomed("x"));
+  assert.isFalse(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_updateOptions_y = function() {
+it('testIsZoomed_updateOptions_y', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   g.updateOptions({valueRange: [1, 10]});
 
-  assertTrue(g.isZoomed());
-  assertFalse(g.isZoomed("x"));
-  assertTrue(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isFalse(g.isZoomed("x"));
+  assert.isTrue(g.isZoomed("y"));
+});
 
-InteractionModelTestCase.prototype.testIsZoomed_updateOptions_both = function() {
+it('testIsZoomed_updateOptions_both', function() {
   var g = new Dygraph(document.getElementById("graph"), data2, {});
 
   g.updateOptions({dateWindow: [-1, 1], valueRange: [1, 10]});
 
-  assertTrue(g.isZoomed());
-  assertTrue(g.isZoomed("x"));
-  assertTrue(g.isZoomed("y"));
-};
+  assert.isTrue(g.isZoomed());
+  assert.isTrue(g.isZoomed("x"));
+  assert.isTrue(g.isZoomed("y"));
+});
 
 
-InteractionModelTestCase.prototype.testCorrectAxisValueRangeAfterUnzoom = function() {
-  var g = new Dygraph(document.getElementById("graph"), data2, {valueRange:[1,50],dateRange:[1,9],animatedZooms:false});
+it('testCorrectAxisValueRangeAfterUnzoom', function() {
+  var g = new Dygraph(document.getElementById("graph"),
+      data2, {
+        valueRange: [1, 50],
+        dateWindow: [1, 9],
+        animatedZooms:false
+      });
   
   // Zoom x axis
-  DygraphOps.dispatchMouseDown_Point(g, 10, 10);
-  DygraphOps.dispatchMouseMove_Point(g, 30, 10);
-  DygraphOps.dispatchMouseUp_Point(g, 30, 10);
+  DygraphOps.dispatchMouseDown_Point(g, 100, 100);
+  DygraphOps.dispatchMouseMove_Point(g, 130, 100);
+  DygraphOps.dispatchMouseUp_Point(g, 130, 100);
 
   // Zoom y axis
-  DygraphOps.dispatchMouseDown_Point(g, 10, 10);
-  DygraphOps.dispatchMouseMove_Point(g, 1030);
-  DygraphOps.dispatchMouseUp_Point(g, 1030);
-  currentYAxisRange = g.yAxisRange();
-  currentXAxisRange = g.xAxisRange();
+  DygraphOps.dispatchMouseDown_Point(g, 100, 100);
+  DygraphOps.dispatchMouseMove_Point(g, 100, 130);
+  DygraphOps.dispatchMouseUp_Point(g, 100, 130);
+  var currentYAxisRange = g.yAxisRange();
+  var currentXAxisRange = g.xAxisRange();
   
   //check that the range for the axis has changed
-  assertNotEquals(1,currentXAxisRange[0]);
-  assertNotEquals(10,currentXAxisRange[1]);
-  assertNotEquals(1,currentYAxisRange[0]);
-  assertNotEquals(50,currentYAxisRange[1]);
+  assert.notEqual(1, currentXAxisRange[0]);
+  assert.notEqual(10, currentXAxisRange[1]);
+  assert.notEqual(1, currentYAxisRange[0]);
+  assert.notEqual(50, currentYAxisRange[1]);
   
   // unzoom by doubleclick.  This is really the order in which a browser
   // generates events, and we depend on it.
@@ -365,16 +372,16 @@ InteractionModelTestCase.prototype.testCorrectAxisValueRangeAfterUnzoom = functi
   // check if range for y-axis was reset to original value 
   // TODO check if range for x-axis is correct. 
   // Currently not possible because dateRange is set to null and extremes are returned
-  newYAxisRange = g.yAxisRange();
-  assertEquals(1,newYAxisRange[0]);
-  assertEquals(50,newYAxisRange[1]);
-};
+  var newYAxisRange = g.yAxisRange();
+  assert.equal(1, newYAxisRange[0]);
+  assert.equal(50, newYAxisRange[1]);
+});
 
 /**
  * Ensures pointClickCallback is called when some points along the y-axis don't
  * exist.
  */
-InteractionModelTestCase.prototype.testPointClickCallback_missingData = function() {
+it('testPointClickCallback_missingData', function() {
 
   // There's a B-value at 2, but no A-value.
   var data =
@@ -392,8 +399,60 @@ InteractionModelTestCase.prototype.testPointClickCallback_missingData = function
     }
   });
 
-  InteractionModelTestCase.clickAt(g, 2, 110);
+  clickAt(g, 2, 110);
 
-  assertEquals(2, clicked.xval);
-  assertEquals(110, clicked.yval);
-};
+  assert.equal(2, clicked.xval);
+  assert.equal(110, clicked.yval);
+});
+
+describe('animated zooms', function() {
+  var oldDuration;
+
+  before(function() {
+    oldDuration = Dygraph.ANIMATION_DURATION;
+    Dygraph.ANIMATION_DURATION = 100;  // speed up the animation for testing
+  });
+  after(function() {
+    Dygraph.ANIMATION_DURATION = oldDuration;
+  });
+
+  it('should support animated zooms', function(done) {
+    var data =
+      "X,A,B\n" +
+      "1,120,100\n"+
+      "2,110,110\n"+
+      "3,140,120\n"+
+      "4,130,110\n";
+
+    var ranges = [];
+
+    var g = new Dygraph('graph', data, {
+      animatedZooms: true,
+    });
+
+    // updating the dateWindow does not result in an animation.
+    assert.deepEqual([1, 4], g.xAxisRange());
+    g.updateOptions({dateWindow: [2, 4]});
+    assert.deepEqual([2, 4], g.xAxisRange());
+
+    g.updateOptions({
+      // zoomCallback is called once when the animation is complete.
+      zoomCallback: function(xMin, xMax) {
+        assert.equal(1, xMin);
+        assert.equal(4, xMax);
+        assert.deepEqual([1, 4], g.xAxisRange());
+        done();
+      }
+    }, false);
+
+    // Zoom out -- resetZoom() _does_ produce an animation.
+    g.resetZoom();
+    assert.notDeepEqual([2, 4], g.xAxisRange());  // first frame is synchronous
+    assert.notDeepEqual([1, 4], g.xAxisRange());
+
+    // at this point control flow goes up to zoomCallback
+  });
+
+});
+
+});