Testing angular mousedown, mousemove, mouseup

In the angular docs directives section

They give roughly this example of how to make a drag object.

My question is how would you test THEIR EXAMPLE / implementation:

var startX = 0, startY = 0; scope.x = 0; scope.y = 0; element.css({ top: scope.y, left: scope.x }); element.on('mousedown', function(event) { // Prevent default dragging of selected content event.preventDefault(); startX = event.pageX - scope.x; startY = event.pageY - scope.y; $document.on('mousemove', mousemove); $document.on('mouseup', mouseup); }); function mousemove(event) { scope.y = event.pageY - startY; scope.x = event.pageX - startX; element.css({ top: scope.y + 'px', left: scope.x + 'px' }); } function mouseup() { $document.off('mousemove', mousemove); $document.off('mouseup', mouseup); } } 

but this only works for one event.

The angular example uses mousedown to add mousemove and mouseup event listeners, and https://stackoverflow.com/a/166328/ uses the triggerHandler--, which prevents bubbling / distribution.

right now I have (roughly):

 describe('on mousedown it', function(){ it('moves a thing', function(){ expect(scope.x).toBe(0); element.triggerHandler({type: 'mousedown', pageX: 0, pageY:0}); element.triggerHandler({type: 'mousemove', pageX:10, pageY:10); expect(scope.x).toBe(10); }); }); 
Test

does not work. scope.x is written as 0. what to do?

+7
angularjs unit-testing angularjs-directive jasmine
source share
2 answers

Well, as I look at this, in the example the drag and drop code is in the directive. Therefore, looking at testing, since the directive manipulates the position of the element to which the directive is bound, I would approve the changes in the position of the element, and not approve the values โ€‹โ€‹of the internal variables of the region.

Given that we have a directive called myDraggable , which is used as <span my-draggable="">Drag Me</span> , when testing:

  • Let's compile the directive.

    var scope = $rootScope.$new(); var elem = $compile('<span my-draggable="">Drag Me</span>')(scope);

  • Then send the mouse event to the compiled element

    elem.triggerHandler({type: 'mousedown', pageX: 0, pageY:0});

  • After that, since the mouse move event is bound to $document , it allows you to send the mouse move event to $document

    $document.triggerHandler({type: 'mousemove', pageX: 10, pageY:20});

  • And finally, let the statement of the final position of the compiled element

    expect(elem.css('top')).toBe('20px') expect(elem.css('left')).toBe('10px')

And when we are all together

 describe('on mousedown it', function(){ beforeEach(module('dragModule')); it('moves a thing', inject(function($compile, $rootScope, $document){ var scope = $rootScope.$new(); var elem = $compile('<span my-draggable="">Drag Me</span>')(scope); $rootScope.$digest(); elem.triggerHandler({type: 'mousedown', pageX: 0, pageY:0}); $document.triggerHandler({type: 'mousemove', pageX: 10, pageY:20}); expect(elem.css('top')).toBe('20px'); expect(elem.css('left')).toBe('10px'); })); }); 

Here's the official angular documentation on the recommended way to test the directive: https://docs.angularjs.org/guide/unit-testing#testing-directives

Here's a plunker that implements everything I just talked about: https://plnkr.co/edit/QgWiVlbNOKkhn6wkGxUK?p=preview

+4
source share

You can check / approve for scope.x as well, but consider Chanthu's answer above - a way to compile a directive with scope.

In addition, the reason for the test failure is all events, except that mousedown fires according to the document, unlike your test case.

Try the following snippet:

  describe('on mousedown it', function(){ it('moves a thing', function(){ expect(scope.x).toBe(0); element.triggerHandler({type: 'mousedown', pageX: 0, pageY:0}); document.triggerHandler({type: 'mousemove', pageX:10, pageY:10); expect(scope.x).toBe(10); }); }); 
+2
source share

All Articles