Тестирование углового mousedown, mousemove, mouseup

В разделе директивы угловое документы

они предоставляют примерно этот пример того, как сделать перетаскивание.

мой вопрос в том, как бы вы проверили их пример / реализацию:

  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);
  }
}

но это работает только для одного события.

пример Angular использует mousedown для добавления прослушивателей событий mousemove и mouseup и этот ответ stackoverflow использует triggerHandler-- который предотвращает барботирование/распространение.

прямо сейчас у меня (грубо):

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);
  });
});

2 ответов


Ok как я смотрю на это, в примере, код перетаскивания находится в директиве. Поэтому, глядя на тестирование, поскольку директива манипулирует положением элемента, к которому прикреплена директива, я бы утверждал изменения в положении элемента, а не утверждал значения переменных внутренней области.

учитывая, что у нас есть директива под названием myDraggable который применяется так <span my-draggable="">Drag Me</span>, при проверке:

  1. позволяет компилировать директива.

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

  2. затем отправьте событие мыши вниз на скомпилированный элемент

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

  3. после этого, потому что событие перемещения мыши прикреплено к $document, позволяет отправить мышь мыши переместить событие в $document

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

  4. и, наконец, давайте утвердим конечную позицию скомпилированного элемент

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

и когда мы сложим все это вместе,

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');
  }));
});

вот официальная угловая документация по рекомендуемому способу тестирования директивы:https://docs.angularjs.org/guide/unit-testing#testing-directives

вот планкер, который реализует все, о чем я только что говорил:https://plnkr.co/edit/QgWiVlbNOKkhn6wkGxUK?p=preview


вы можете проверить/assert для области.x также, но рассмотрите выше ответ Chanthu-способ компиляции директивы с областью действия.

кроме того, причина, по которой ваш тест терпит неудачу, - все события, кроме mousedown, запускаются в документе, в отличие от вашего тестового примера.

попробовать следующий фрагмент:

                       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);
                        });
                      });