我遇到了单元测试委托组件的问题,它应该阻止特殊键并允许输入与正则表达式匹配的数据。
指令组件代码是:
import {Directive, ElementRef, HostListener, Input} from '@angular/core';
@Directive({
selector: '[w2NumberLimit]',
})
export class NumberLimitDirective {
@Input() public integerLimit: number = 10;
@Input() public fractionalLimit: number = 0;
@Input() public decimalMark: string = ',';
constructor(private el: ElementRef) { }
@HostListener('keypress', ['$event']) public onKeyPress(event) {
const next: string = current.concat(event.key);
const regexp = RegExp(this.setRegexp(), 'g');
if (next && !String(next).match(regexp)) {
event.preventDefault();
}
}
private setRegexp() {
let regexp: string = '^[0-9]';
// set integer part limit
regexp = regexp + ((this.integerLimit) ? `{0,${this.integerLimit}}` : '*');
// set fractionalLimit
regexp = regexp + ((this.fractionalLimit > 0) ? `(\\${this.decimalMark}[0-9]{0,${this.fractionalLimit}})?` : '');
return regexp + '$';
}
}
单元测试代码:
describe('Directive: NumberLimitDirective', () => {
let component: TestNumberLimitComponent;
let fixture: ComponentFixture<TestNumberLimitComponent>;
let inputAutoFocusEl: DebugElement;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [NumberLimitDirective, TestNumberLimitComponent],
imports: [FormsModule],
}).compileComponents();
fixture = TestBed.createComponent(TestNumberLimitComponent);
component = fixture.componentInstance;
inputAutoFocusEl = fixture.debugElement.query(By.css('input'));
});
beforeEach(async () => {
fixture.detectChanges();
fixture.whenStable();
});
function sendInput(inputElement: any, text: number | string) {
const value = inputElement.nativeElement.value;
inputElement.nativeElement.value = value.concat(text);
const event = new Event('input');
inputElement.nativeElement.dispatchEvent(event);
fixture.detectChanges();
return fixture.whenStable();
}
function sendKeyDown(inputElement: any, event: any) {
inputElement.nativeElement.dispatchEvent(event);
fixture.detectChanges();
return fixture.whenStable();
}
function testInput(inputElement: any, text: number | string) {
const oneKeyDown = new KeyboardEvent('keypress', {key: `${text}`});
sendKeyDown(inputElement, oneKeyDown);
if (!oneKeyDown.defaultPrevented) {
sendInput(inputElement, text);
}
}
test('Check valid input for default input.', async () => {
fixture.detectChanges();
const testLocator = fixture.debugElement.query(By.css('#default'));
expect(testLocator).not.toBe(null);
await testInput(testLocator, 1);
await testInput(testLocator, ',');
await testInput(testLocator, 0);
jest.runAllTicks();
expect(testLocator.nativeElement.value).toBe('01');
});
});
测试组件代码:
@Component({
template: `
<div>
<input id="default" w2NumberLimit [value]="test" [(ngModel)]="test" #input="ngModel">
</div>`
})
export class TestNumberLimitComponent {
public test = 0;
}
默认情况下,此组件应忽略“,”和“0”。因此输出值应该是“01”,但是事件的preventDefault字段不会将其值更改为“true”。
同时,当我在我的应用程序中使用它时,此指令可以直接使用输入。使用相同的输入,它会阻止最后一个“,”和“0”输入。