I have created a custom Directive using @Directive in which I am using @HostListener and fire a Keydown event, now the code works fine. Now, when writing the test case I need to invoke the @HostListener method from the unit test case. Also I can see that in the code coverage the code is not covered. Following is the code:
Specify-char-input-directive.ts
import { Directive, HostListener, Input } from '@angular/core';
@Directive({
selector: '[tfbSpecifyCharInput]'
});
export class SpecifyCharInputDirective {
@Input() tfbSpecifyCharInput: string;
key: any;
ctrlKey: any;
@HostListener('keydown', ['$event']) onKeydown(event: KeyboardEvent): any {
this.key = event.code;
this.ctrlKey = (['KeyV', 'KeyC', 'KeyX', 'KeyA'].indexOf(event.code) !== -1 && (event.ctrlKey || event.metaKey));
const matchesNumber = /^[0-9]$/i.test(event.key);
const matchesSpclChar = /[^a-zA-Z]$/i.test(event.key);
const matchesAlpha = /^[A-ZÀ-ÿ-a-z`~/!@#%^&*-+=<>?,._#'${}|":;()]$/i.test(event.key) && !this.ctrlKey;
if (this.tfbSpecifyCharInput === 'alpha' && matchesNumber) {
event.preventDefault();
}
if (this.tfbSpecifyCharInput === 'alpha' && matchesSpclChar) {
event.preventDefault();
}
if (this.tfbSpecifyCharInput === 'numeric' && matchesAlpha) {
event.preventDefault();
}
}
}
Specify-char-input-directive.spec.ts
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Component, DebugElement, HostListener } from '@angular/core';
import { By } from '@angular/platform-browser';
import { SpecifyCharInputDirective } from './specify-char-input.directive';
@Component({
template: `<p [tfbSpecifyCharInput]="'alpha'"></p>`
})
class TestComponent {
// allows us to listen to keydown event
key: any;
@HostListener('keydown', ['$event']) onKeydown(event: KeyboardEvent): any {
this.key = event.code;
}
}
describe('tfbSpecifyCharInputDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
let inputEl: HTMLElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
SpecifyCharInputDirective
]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
inputEl = fixture.nativeElement.querySelector('p');
});
it('should initialize directive with numeric only', () => {
expect(component).toBeDefined();
});
it('should fire window keydown event', () => {
const event: Event = new KeyboardEvent('keydown', {
code: 'Enter'
});
inputEl.dispatchEvent(event);
spyOn(event, 'preventDefault');
fixture.detectChanges();
expect(component.onKeydown).toBeTruthy();
});
});
Below you can also see the code coverage report:

Here I need to cover the code and get the proper test case executed required for this method. Thanks.