I have a line chart component written using D3 and Angular. It has draggable bars used to change the scale of x axis. Now I am trying to test the component using Karma/Jasmine. I have a trouble triggering drag event in the unit test.
Other events like mouseover and click are triggered just fine. I think it's the synthetized implementation of "drag" event in d3 which causes issue.
Here is the code I use to trigger dragging (such code fires a correct d3 drag event on a test html page, but fails inside a unit test).
var leftBar = element.find(".left-bar")[0];
var evObjStart = document.createEvent("MouseEvents");
evObjStart.initMouseEvent("mousedown", true, true, window, 1, 12, 320, 12, 320, false, false, false, false, 0, null);
var evObj = document.createEvent("MouseEvents");
evObj.initMouseEvent("mousemove", true, true, window, 1, 100, 320, 100, 320, false, false, false, false, 0, null);
var evObjEnd = document.createEvent("MouseEvents");
evObjEnd.initMouseEvent("mouseup", true, true, window, 1, 200, 320, 200, 320, false, false, false, false, 0, null);
leftBar.dispatchEvent(evObjStart);
leftBar.dispatchEvent(evObj);
leftBar.dispatchEvent(evObjEnd);
I found out that only the first event is correctly dispatched (leftBar.dispatchEvent(evObjStart)).
Other two events are not dispatched at all. leftBar variable is correct 100%. I am totally lost on where to search the error.
P.S. I tried generating "dragstart", "drag" and "dragend" events, but they are not handled properly by d3 in browser (did not work in a basic test example in console). Mousedown/mousemove/mouseup sequence works correctly in browser, but only mousedown is dispatched in the unit test. Will be very grateful for any help or ideas.
While this isn't an answer, I hope this helps.
Here's a way you can break your handlers off into something testable.
Add them as members of your controller like so:
app.controller('MyDirectiveCtrl', function($scope) {
this.dragHandler = function() {
// do stuff
};
});
app.directive('MyDirective', function(){
return {
controller: 'MyDirectiveCtrl',
link: function(scope, elem, attrs, ctrl) {
var drag = d3.behavior.drag();
drag.on('drag', ctrl.dragHandler);
d3.select(elem[0]).call(drag);
}
}
});
Then to test:
<!-- language: lang-js -->
// create the controller
var ctrl = $controller('MyDirectiveCtrl', {
$scope: mockScope
});
// call the handler
ctrl.dragHandler(mock, args, here);
// assert some difference
expect(mock).toBe(differentSomehow
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With