2016-11-30 4 views
0

Удивление, если кто-то там может пролить свет на то, как правильно использовать element.triggerHandler() для событий paste и keypress внутри углового символа модульный тест.Использование метода element.triggerHandler() в тестах angularjs для событий пасты и нажатия клавиш не оказывает никакого эффекта

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

Смотрите следующий plunker для полного примера, включая мои непройденные тесты: https://plnkr.co/edit/5Yyv2cnn3dRKzsj2Lj61?p=preview

Для теста paste я знаю, что я не использую правильный синтаксис, но не смог найти, как правильно это сделать. Какие-либо предложения?

element.triggerHandler('paste', 'astring')

Для теста keypress, я считаю, я правильно стрелять событие, но это, похоже, не обновлять значение элемента (извлеченного с помощью element.val())

застрял на этом для немного, любая помощь будет принята с благодарностью. Благодаря!

+0

Вы не получаете значение в element.val(), обновите значение элемента как var value = this.value + String.fromCharCode (e.keyCode); элемент [0] .value = значение; – Ajaykumar

+0

Хм, спасибо за ответ @Ajaykumar, но я не уверен, что я следую. Можете ли вы предоставить образец кода или развить плункер, чтобы проиллюстрировать, что вы имеете в виду? Я пытаюсь получить значение элемента после того, как событие было запущено, а не назначить его элементу. 'element [0] .value', к сожалению, возвращает ту же пустую строку, что и' element.val() '. –

+0

По-прежнему нужна помощь? – tasseKATT

ответ

0

Давайте начнем с короткого пробоя, что может произойти (действительно до реализации браузера), когда пользователь нажимает и отпускает 1 ключ с фокусом на входе:

  1. Event keydown является обожженные
  2. события keypress обжигает
  3. Значения ввода изменяется на 1 и событие input обжигает
  4. Событие keyup увольняется

В JS нет способа фактически имитировать пользователя, нажимая клавишу. То, что вы можете имитировать, - это то, что (как правило) происходит, когда пользователь делает это, например, шаги выше.

Функция triggerHandler выполняет все обработчики, связанные с jQuery для указанного типа события для конкретного элемента.

Таким образом, используя triggerHandler с keypress, не будет имитировать пользователя, нажимая клавишу, он только активирует событие, как шаг 2 выше. Значение не будет изменено, так как это произойдет на другом шаге.

Теперь, можно было бы подумать, что в тестах на limitKeypressLength директивы, вы можете просто смоделировать первую часть шага 3 выше себя (только заходящего значение вручную):

for (var i = 0; i < 10; i++) { 
    element.triggerHandler({type: 'keypress', keyCode: 49}); 
    element.val(element.val() + '1'); 
} 

expect(element.val()).toBe('1111111111'); 

element.triggerHandler('keypress', {which: 49}); 
element.val(element.val() + '1'); 

expect(element.val()).toBe('1111111111'); 

Это не будет работать, однако , так как даже если одиннадцатое событие нажатия клавиши попадает в вашу директиву, приведенный ниже код все равно выполнит и обновит значение.

Основная функциональность директивы limitKeypressLength состоит в том, чтобы прослушивать событие нажатия клавиши и либо звонить event.preventDefault, либо не основываться. Это то, что вы хотите проверить.

Например:

// Set value to something longer than allowed 
element.val('123456789123456789'); 

// Create the event 
var e = jQuery.Event('keypress', { 
    keyCode: 49 
}); 

// Create a spy 
spyOn(e, 'preventDefault'); 

// preventDefault should not have been called yet 
expect(e.preventDefault).not.toHaveBeenCalled(); 

// Trigger the event 
element.triggerHandler(e); 

// Assert that preventDefault has been called 
expect(e.preventDefault).toHaveBeenCalled(); 

Демо:https://plnkr.co/edit/ktmcBGSuTdMnvqVRlkeQ?p=preview

Теперь вы можете так же легко проверить, если значение элемента устанавливается равным/ниже допустимого значения.

В принципе то же самое касается директивы limitPasteLength, так как ее цель - также позвонить по телефону preventDefault на основании условия, только чтобы было сделано какое-то дополнительное издевательство.

+0

@ ZaneMattingly Если у вас возникли проблемы с написанием тестов или просто нужно руководство, просто дайте мне знать. – tasseKATT

+0

Удивительный, это имеет большой смысл, и я думаю, что вы правы, принимая разные такты для тестирования. Отличное объяснение и благодарность за рабочую демонстрацию, вы, да! : D Мне все еще интересно, как 'element.triggerHandler()' работает с событием 'paste'. Никогда не находил на нем никакой документации. Это просто не поддерживается для имитации событий вставки, и если он поддерживается, как вы поставляете данные для вставки? –

+0

Запуск события 'paste' просто запускает всех слушателей для этого события, так же, как с помощью' keypress'. Он не заполняет данные буфера обмена. Вам нужно заполнить событие или окно самостоятельно в соответствии с тем, как конкретные браузеры ожидают его просмотра. – tasseKATT