2016-09-27 14 views
6

Bir kullanıcının, belirli geçersiz karakterleri basmasını kısıtlayan bir yönerge oluşturdum, bu durumda, yönergemi kullanan giriş öğesine keypress olay bağlamasını kullanarak. Bu işlevselliği test etmeye çalışıyorum, ancak bunu nasıl başaracağımı anlamıyorum.Açısal yönergeler: Bazı tuşların bir tuşa basma olayında reddedildiğini test etmek mümkün mü?

Benim direktifi

angular 
    .module('gp.rutValidator') 
    .directive('gpRutValidator', directive); 

    directive.$inject = ['$filter']; 

    function directive($filter){ 
    var ddo = { 
     restrict: 'A', 
     require: 'ngModel', 
     link: linkFn 
    }; 
    return ddo; 

    function linkFn(scope, element, attrs, ngModel){ 

     //valid characters are digits, dash and letter k 
     var regexValidKeys = (/[\d\.\-k]/i); 

     element.bind('keypress', function(e){ 

     var key = e.key || String.fromCharCode(e.keyCode); 

     if (!regexValidKeys.test(key)) { 
      e.preventDefault(); 
      return false; 
     } 

     }); 

    } 
    } 

Testim

describe('Angular Rut Validator Directive',validatorDirectiveSpec); 

    function validatorDirectiveSpec(){ 

    ////////////// GLOBALS //////////////////////////////// 
    var scope, element, evt; 
    ////////////// BEFORE EACH //////////////////////////////// 
    beforeEach(module('gp.rutValidator')); 
    beforeEach(inject(eachSpec)); 

    function eachSpec($rootScope, $compile){ 
     element = angular.element('<input ng-model="rut" gp-rut-validator>'); 
     scope = $rootScope.$new(); 
     $compile(element)(scope); 
     scope.$digest(); 
    } 

    ////////////////// HELPERS /////////////////////////////////// 
    function pressKey(keyCode) { 
     try { 
     // Chrome, Safari, Firefox 
     evt = new KeyboardEvent('keypress'); 
     delete evt.keyCode; 
     Object.defineProperty(evt, 'keyCode', {'value': keyCode}); 
     } 
     catch (e) { 
     // PhantomJS 
     evt = document.createEvent('Events'); 
     evt.initEvent('keypress', true, true); 
     evt.keyCode = keyCode; 
     } 
     element[0].dispatchEvent(evt); 
    } 
    ////////////////// SPECS ////////////////////////////////// 
    it('1. Should be reject no valid characters', spec1); 

    function spec1(){ 
     var ngModelCtrl = element.controller('ngModel'), 
      invalidCharacterKeys = [ 
            'a'.charCodeAt(0), 
            'z'.charCodeAt(0), 
            'b'.charCodeAt(0), 
            '#'.charCodeAt(0) 
            ]; 

     invalidCharacterKeys.forEach(function(keyCode){ 
     pressKey(keyCode); 
     scope.$digest(); 
     expect(scope.rut).toBe(''); 
     }); 

    } 

    } 

Ama hatayı ben yanlış yapıyorum Expected undefined to be ''.

olsun? Codepen içinde

Örnek =>http://codepen.io/gpincheiraa/pen/ozWyvA

+0

Kendimi denemedim, ama bazı hızlı kazma bir cevap bulmuş gibi görünüyor. http://stackoverflow.com/questions/23561259/sending-keydown-to-angular-directive-with-jquery-trigger – dwbartz

+0

Teşekkürler, bu teknik harika görünüyor! –

cevap

0

kullanın bu kod it('1. Should be reject not valid characters') yerine it('1. Should be reject no valid characters', spec1);

+0

neden bu şekilde kullanılmalıyım? –

+0

Aslında ne tür bir mesaj göstermeniz gerekiyor bana bir exmple ver –

+0

"pressKey (keyCode)" işlevini kullanıyorum. Bu scope.rut (değişken html öğesinde yönerge olarak model olarak iletilen değişkenin) olması beklenir. '' ' ' –

1

arasında nasıl Event.prototye.preventDefault değiştirilmesi hakkında:

var original = Event.prototype.preventDefault; 
Event.prototype.preventDefault = function(){ 
    original.bind(this); 
    handlers.filter((handler) => handler.keyCode == this.keyCode).forEach((handler)=>handler.handle(this)); 
    handlers = handlers.filter((handler)=> handler.keyCode != this.keyCode); 
} 

ve ona önceden tanımlanmış geri arama çağırttırma :

function pressKey(keyCode, cb) { 
     try { 
      // Chrome, Safari, Firefox 
      handlers.push({keyCode : keyCode, handle: cb}); 
      evt = new KeyboardEvent('keypress'); 
      delete evt.keyCode; 
      Object.defineProperty(evt, 'keyCode', {'value': keyCode}); 
      element[0].dispatchEvent(evt); 
     } 
     catch (e) { 
      // PhantomJS 
      evt = document.createEvent('Events'); 
      evt.initEvent('keypress', true, true); 
      evt.keyCode = keyCode; 
      element[0].dispatchEvent(evt); 
     } 
    } 
Daha sonra

ve bunun gibi PressKey çağrı:

pressKey(keyCode, (event)=>{expect(event.keyCode).toBe(keyCode)})); 

Nasıl altyapı/düşük seviyede dışına mantığı ayıklanması konusunda bu sizin için ...

0

sordunuz buysa% 100 emin değilim kodu ve daha net bir şekilde test etmek? Başka bir deyişle, anahtarı giriş olarak alan ve true/false sonucu döndüren bir hizmet tanımlayın. Servis html elemanının olayını dinlemez, sadece giriş alır ve çıkış verir. Bu nedenle, yasemin birim testlerinizi kullanarak bu hizmeti (başka herhangi bir hizmet gibi) test edebilirsiniz. Ardından, bu servisi kendi direktifinize enjekte edin ve olay işleyicisinden arayın (bağlanma hala yönergenin içinde gerçekleşir). Hizmet false değerini döndürürse, e.preventDefault() numaralı telefonu da arayın, aksi halde tuşa izin verin.

Açıktır ki, bu yaklaşım html öğesinin olayına nasıl abone olduğunuzu sınamayacaktır (bind), ancak bunun sizin niyetiniz olduğunu düşünmüyorum. Bu, hangi anahtarların endişelerin daha iyi ayrılmasını izleyerek iyi bir şekilde kabul edildiğini/reddedildiğini test edecektir - bu, endişelerin ayrılmasıyla ilgili olan MVC.

İlgili konular