Browse Source

Merge pull request #2127 from abpframework/test/core-directives

Test/core directives
pull/2128/head
Mehmet Erim 7 years ago
committed by GitHub
parent
commit
8f74e30089
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts
  2. 16
      npm/ng-packs/packages/core/src/lib/directives/ellipsis.directive.ts
  3. 10
      npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts
  4. 36
      npm/ng-packs/packages/core/src/lib/tests/autofocus.directive.spec.ts
  5. 85
      npm/ng-packs/packages/core/src/lib/tests/config.plugin.spec.ts
  6. 40
      npm/ng-packs/packages/core/src/lib/tests/debounce.directive.spec.ts
  7. 55
      npm/ng-packs/packages/core/src/lib/tests/ellipsis.directive.spec.ts
  8. 39
      npm/ng-packs/packages/core/src/lib/tests/stop-propagation.directive.spec.ts

14
npm/ng-packs/packages/core/src/lib/directives/debounce.directive.ts

@ -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 {}
}

16
npm/ng-packs/packages/core/src/lib/directives/ellipsis.directive.ts

@ -1,9 +1,9 @@
import { AfterContentInit, ChangeDetectorRef, Directive, ElementRef, HostBinding, Input } from '@angular/core';
import { AfterViewInit, ChangeDetectorRef, Directive, ElementRef, HostBinding, Input } from '@angular/core';
@Directive({
selector: '[abpEllipsis]',
})
export class EllipsisDirective implements AfterContentInit {
export class EllipsisDirective implements AfterViewInit {
@Input('abpEllipsis')
width: string;
@ -31,14 +31,8 @@ export class EllipsisDirective implements AfterContentInit {
constructor(private cdRef: ChangeDetectorRef, private elRef: ElementRef) {}
ngAfterContentInit() {
setTimeout(() => {
const title = this.title;
this.title = title || (this.elRef.nativeElement as HTMLElement).innerText;
if (this.title !== title) {
this.cdRef.detectChanges();
}
}, 0);
ngAfterViewInit() {
this.title = this.title || (this.elRef.nativeElement as HTMLElement).innerText;
this.cdRef.detectChanges();
}
}

10
npm/ng-packs/packages/core/src/lib/directives/stop-propagation.directive.ts

@ -1,15 +1,15 @@
import { Directive, ElementRef, EventEmitter, OnInit, Output, Renderer2 } from '@angular/core';
import { Directive, ElementRef, EventEmitter, OnInit, Output, Renderer2, OnDestroy } from '@angular/core';
import { fromEvent } from 'rxjs';
import { takeUntilDestroy } from '@ngx-validate/core';
@Directive({
// tslint:disable-next-line: directive-selector
selector: '[click.stop]'
selector: '[click.stop]',
})
export class ClickEventStopPropagationDirective implements OnInit {
export class ClickEventStopPropagationDirective implements OnInit, OnDestroy {
@Output('click.stop') readonly stopPropEvent = new EventEmitter<MouseEvent>();
constructor(private renderer: Renderer2, private el: ElementRef) {}
constructor(private el: ElementRef) {}
ngOnInit(): void {
fromEvent(this.el.nativeElement, 'click')
@ -19,4 +19,6 @@ export class ClickEventStopPropagationDirective implements OnInit {
this.stopPropEvent.emit(event);
});
}
ngOnDestroy(): void {}
}

36
npm/ng-packs/packages/core/src/lib/tests/autofocus.directive.spec.ts

@ -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();
});
});
});

85
npm/ng-packs/packages/core/src/lib/tests/config.plugin.spec.ts

@ -2,7 +2,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
import { NgxsModule, NGXS_PLUGINS, Store } from '@ngxs/store';
import { environment } from '../../../../../apps/dev-app/src/environments/environment';
import { LAYOUTS } from '../../../../theme-basic/src/public-api';
import { LAYOUTS } from '@abp/ng.theme.basic';
import { RouterOutletComponent } from '../components';
import { CoreModule } from '../core.module';
import { eLayoutType } from '../enums/common';
@ -68,27 +68,7 @@ const expectedState = {
path: '',
children: [],
url: '/',
},
{
name: 'AbpAccount::Menu:Account',
path: 'account',
invisible: true,
layout: 'application',
children: [
{
path: 'login',
name: 'AbpAccount::Login',
order: 1,
url: '/account/login',
},
{
path: 'register',
name: 'AbpAccount::Register',
order: 2,
url: '/account/register',
},
],
url: '/account',
order: 1,
},
{
name: 'AbpUiNavigation::Menu:Administration',
@ -137,17 +117,10 @@ const expectedState = {
},
],
url: '/tenant-management',
order: 2,
},
],
},
],
flattedRoutes: [
{
name: '::Menu:Home',
path: '',
children: [],
url: '/',
},
{
name: 'AbpAccount::Menu:Account',
path: 'account',
@ -168,18 +141,16 @@ const expectedState = {
},
],
url: '/account',
order: 2,
},
],
flattedRoutes: [
{
path: 'login',
name: 'AbpAccount::Login',
name: '::Menu:Home',
path: '',
children: [],
url: '/',
order: 1,
url: '/account/login',
},
{
path: 'register',
name: 'AbpAccount::Register',
order: 2,
url: '/account/register',
},
{
name: 'AbpUiNavigation::Menu:Administration',
@ -228,6 +199,7 @@ const expectedState = {
},
],
url: '/tenant-management',
order: 2,
},
],
},
@ -286,6 +258,7 @@ const expectedState = {
},
],
url: '/tenant-management',
order: 2,
},
{
path: 'tenants',
@ -294,6 +267,40 @@ const expectedState = {
requiredPolicy: 'AbpTenantManagement.Tenants',
url: '/tenant-management/tenants',
},
{
name: 'AbpAccount::Menu:Account',
path: 'account',
invisible: true,
layout: 'application',
children: [
{
path: 'login',
name: 'AbpAccount::Login',
order: 1,
url: '/account/login',
},
{
path: 'register',
name: 'AbpAccount::Register',
order: 2,
url: '/account/register',
},
],
url: '/account',
order: 2,
},
{
path: 'login',
name: 'AbpAccount::Login',
order: 1,
url: '/account/login',
},
{
path: 'register',
name: 'AbpAccount::Register',
order: 2,
url: '/account/register',
},
],
};

40
npm/ng-packs/packages/core/src/lib/tests/debounce.directive.spec.ts

@ -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();
});
});
});

55
npm/ng-packs/packages/core/src/lib/tests/ellipsis.directive.spec.ts

@ -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');
});
});

39
npm/ng-packs/packages/core/src/lib/tests/stop-propagation.directive.spec.ts

@ -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…
Cancel
Save