mirror of https://github.com/abpframework/abp.git
committed by
GitHub
8 changed files with 235 additions and 60 deletions
@ -1,27 +1,29 @@ |
|||
import { Directive, Output, Renderer2, ElementRef, OnInit, EventEmitter, Input } from '@angular/core'; |
|||
import { Directive, ElementRef, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; |
|||
import { takeUntilDestroy } from '@ngx-validate/core'; |
|||
import { fromEvent } from 'rxjs'; |
|||
import { debounceTime } from 'rxjs/operators'; |
|||
import { takeUntilDestroy } from '@ngx-validate/core'; |
|||
|
|||
@Directive({ |
|||
// tslint:disable-next-line: directive-selector
|
|||
selector: '[input.debounce]' |
|||
selector: '[input.debounce]', |
|||
}) |
|||
export class InputEventDebounceDirective implements OnInit { |
|||
export class InputEventDebounceDirective implements OnInit, OnDestroy { |
|||
@Input() debounce = 300; |
|||
|
|||
@Output('input.debounce') readonly debounceEvent = new EventEmitter<Event>(); |
|||
|
|||
constructor(private renderer: Renderer2, private el: ElementRef) {} |
|||
constructor(private el: ElementRef) {} |
|||
|
|||
ngOnInit(): void { |
|||
fromEvent(this.el.nativeElement, 'input') |
|||
.pipe( |
|||
debounceTime(this.debounce), |
|||
takeUntilDestroy(this) |
|||
takeUntilDestroy(this), |
|||
) |
|||
.subscribe((event: Event) => { |
|||
this.debounceEvent.emit(event); |
|||
}); |
|||
} |
|||
|
|||
ngOnDestroy(): void {} |
|||
} |
|||
|
|||
@ -0,0 +1,36 @@ |
|||
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; |
|||
import { AutofocusDirective } from '../directives/autofocus.directive'; |
|||
import { timer } from 'rxjs'; |
|||
|
|||
describe('AutofocusDirective', () => { |
|||
let spectator: SpectatorDirective<AutofocusDirective>; |
|||
let directive: AutofocusDirective; |
|||
let input: HTMLInputElement; |
|||
const createDirective = createDirectiveFactory({ |
|||
directive: AutofocusDirective, |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
spectator = createDirective('<input [autofocus]="10" />', { |
|||
hostProps: {}, |
|||
}); |
|||
directive = spectator.directive; |
|||
input = spectator.query('input'); |
|||
}); |
|||
|
|||
test('should be created', () => { |
|||
expect(directive).toBeTruthy(); |
|||
}); |
|||
|
|||
test('should have 10ms delay', () => { |
|||
expect(directive.delay).toBe(10); |
|||
}); |
|||
|
|||
test('should focus element after given delay', done => { |
|||
timer(0).subscribe(() => expect('input').not.toBeFocused()); |
|||
timer(11).subscribe(() => { |
|||
expect('input').toBeFocused(); |
|||
done(); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,40 @@ |
|||
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; |
|||
import { InputEventDebounceDirective } from '../directives/debounce.directive'; |
|||
import { timer } from 'rxjs'; |
|||
|
|||
describe('InputEventDebounceDirective', () => { |
|||
let spectator: SpectatorDirective<InputEventDebounceDirective>; |
|||
let directive: InputEventDebounceDirective; |
|||
let input: HTMLInputElement; |
|||
let inputEventFn = jest.fn(() => {}); |
|||
|
|||
const createDirective = createDirectiveFactory({ |
|||
directive: InputEventDebounceDirective, |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
spectator = createDirective('<input (input.debounce)="inputEventFn()" [debounce]="20" />', { |
|||
hostProps: { inputEventFn }, |
|||
}); |
|||
directive = spectator.directive; |
|||
input = spectator.query('input'); |
|||
inputEventFn.mockClear(); |
|||
}); |
|||
|
|||
test('should be created', () => { |
|||
expect(directive).toBeTruthy(); |
|||
}); |
|||
|
|||
test('should have 20ms debounce time', () => { |
|||
expect(directive.debounce).toBe(20); |
|||
}); |
|||
|
|||
test('should call fromEvent with target element and target event', done => { |
|||
spectator.dispatchFakeEvent('input', 'input', true); |
|||
timer(0).subscribe(() => expect(inputEventFn).not.toHaveBeenCalled()); |
|||
timer(21).subscribe(() => { |
|||
expect(inputEventFn).toHaveBeenCalled(); |
|||
done(); |
|||
}); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,55 @@ |
|||
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; |
|||
import { EllipsisDirective } from '../directives/ellipsis.directive'; |
|||
|
|||
describe('EllipsisDirective', () => { |
|||
let spectator: SpectatorDirective<EllipsisDirective>; |
|||
let directive: EllipsisDirective; |
|||
let el: HTMLDivElement; |
|||
const createDirective = createDirectiveFactory({ |
|||
directive: EllipsisDirective, |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
spectator = createDirective( |
|||
'<div [abpEllipsis]="width" [abpEllipsisEnabled]="true" [title]="title">test content</div>', |
|||
{ |
|||
hostProps: { |
|||
title: 'test title', |
|||
width: '100px', |
|||
}, |
|||
}, |
|||
); |
|||
directive = spectator.directive; |
|||
el = spectator.query('div'); |
|||
}); |
|||
|
|||
test('should be created', () => { |
|||
expect(directive).toBeTruthy(); |
|||
}); |
|||
|
|||
test('should have 100px ellipsis width', () => { |
|||
expect(directive.width).toBe('100px'); |
|||
}); |
|||
|
|||
test('should be enabled if abpEllipsisEnabled input is true', () => { |
|||
expect(directive.enabled).toBe(true); |
|||
}); |
|||
|
|||
test('should have given title', () => { |
|||
expect(directive.title).toBe('test title'); |
|||
}); |
|||
|
|||
test('should have element innerText as title if not specified', () => { |
|||
spectator.setHostInput({ title: undefined }); |
|||
expect(directive.title).toBe(el.innerText); |
|||
}); |
|||
|
|||
test('should add abp-ellipsis-inline class to element if width is given', () => { |
|||
expect(el).toHaveClass('abp-ellipsis-inline'); |
|||
}); |
|||
|
|||
test('should add abp-ellipsis class to element if width is not given', () => { |
|||
spectator.setHostInput({ width: undefined }); |
|||
expect(el).toHaveClass('abp-ellipsis'); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,39 @@ |
|||
import { createDirectiveFactory, SpectatorDirective } from '@ngneat/spectator/jest'; |
|||
import { ClickEventStopPropagationDirective } from '../directives/stop-propagation.directive'; |
|||
|
|||
describe('ClickEventStopPropagationDirective', () => { |
|||
let spectator: SpectatorDirective<ClickEventStopPropagationDirective>; |
|||
let directive: ClickEventStopPropagationDirective; |
|||
let link: HTMLAnchorElement; |
|||
let childClickEventFn = jest.fn(() => null); |
|||
let parentClickEventFn = jest.fn(() => null); |
|||
const createDirective = createDirectiveFactory({ |
|||
directive: ClickEventStopPropagationDirective, |
|||
}); |
|||
|
|||
beforeEach(() => { |
|||
spectator = createDirective( |
|||
'<div (click)="parentClickEventFn()"><a (click.stop)="childClickEventFn()" >Link</a></div>', |
|||
{ |
|||
hostProps: { parentClickEventFn, childClickEventFn }, |
|||
}, |
|||
); |
|||
directive = spectator.directive; |
|||
link = spectator.query('a'); |
|||
childClickEventFn.mockClear(); |
|||
parentClickEventFn.mockClear(); |
|||
}); |
|||
|
|||
test('should be created', () => { |
|||
expect(directive).toBeTruthy(); |
|||
}); |
|||
|
|||
test('should not call click event of parent when child element is clicked', done => { |
|||
spectator.setHostInput({ parentClickEventFn, childClickEventFn }); |
|||
spectator.click('a'); |
|||
spectator.detectChanges(); |
|||
expect(childClickEventFn).toHaveBeenCalled(); |
|||
expect(parentClickEventFn).not.toHaveBeenCalled(); |
|||
done(); |
|||
}); |
|||
}); |
|||
Loading…
Reference in new issue