import { Component, DebugElement, SimpleChanges } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TimepickerDirective } from './ngx-timepicker.directive';
import { By } from '@angular/platform-browser';
import { NgxMaterialTimepickerComponent } from '../ngx-material-timepicker.component';
import { NgxMaterialTimepickerModule } from '../ngx-material-timepicker.module';
import { DateTime } from 'luxon';
@Component({
template: `
`
})
class TestComponent {
}
describe('TimepickerDirective', () => {
const consoleWarnValue = 'Selected time doesn\'t match min or max value';
let fixture: ComponentFixture;
let input: DebugElement;
let directive: TimepickerDirective;
let timepickerComponent: NgxMaterialTimepickerComponent;
beforeEach(() => {
fixture = TestBed.configureTestingModule({
declarations: [
TestComponent
],
imports: [NgxMaterialTimepickerModule]
}).createComponent(TestComponent);
input = fixture.debugElement.query(By.directive(TimepickerDirective));
directive = input.injector.get(TimepickerDirective);
timepickerComponent = TestBed.createComponent(NgxMaterialTimepickerComponent).componentInstance;
});
it('should register NgxMaterialTimepickerComponent', () => {
const spy = spyOnProperty(directive, 'timepicker', 'set').and.callThrough();
directive.timepicker = timepickerComponent;
expect(spy).toHaveBeenCalledWith(timepickerComponent);
});
it('should throw Error if NgxMaterialTimepickerComponent is not defined', () => {
spyOnProperty(directive, 'timepicker', 'set').and.callThrough();
expect(() => directive.timepicker = null).toThrowError('NgxMaterialTimepickerComponent is not defined.' +
' Please make sure you passed the timepicker to ngxTimepicker directive');
});
describe('Format', () => {
it('should set 12 format', () => {
directive.format = 25;
expect(directive.format).toBe(12);
});
it('should set 24 format', () => {
directive.format = 24;
expect(directive.format).toBe(24);
});
it('should set value and call updateTime when format changes dynamically', () => {
const spy = spyOn(timepickerComponent, 'updateTime');
directive.timepicker = timepickerComponent;
directive.value = '11:11 pm';
directive.format = 12;
expect(directive.value.toLowerCase()).toBe('11:11 pm');
expect(spy).toHaveBeenCalledTimes(0);
directive.format = 24;
expect(directive.value).toBe('23:11');
expect(spy).toHaveBeenCalledWith('23:11');
});
it('should not call updateTime when format the same as before', () => {
const spy = spyOn(timepickerComponent, 'updateTime');
directive.timepicker = timepickerComponent;
directive.format = 12;
expect(spy).toHaveBeenCalledTimes(0);
directive.format = 12;
expect(spy).toHaveBeenCalledTimes(0);
});
});
it('should return min time in DateTime type if pass string', () => {
directive.min = '11:00 pm';
expect(directive.min['hour']).toBe(23);
expect(directive.min['minute']).toBe(0);
});
it('should return min time in DateTime type if pass DateTime', () => {
directive.min = DateTime.fromObject({hour: 10, minute: 11});
expect(directive.min.hour).toBe(10);
expect(directive.min.minute).toBe(11);
});
it('should return max time in DateTime type if pass string', () => {
directive.max = '11:00 pm';
expect(directive.max['hour']).toBe(23);
expect(directive.max['minute']).toBe(0);
});
it('should return max time in DateTime type if pass DateTime', () => {
directive.max = DateTime.fromObject({hour: 10, minute: 11});
expect(directive.max.hour).toBe(10);
expect(directive.max.minute).toBe(11);
});
it(`should clear the time if set value undefined, null, '' `, () => {
directive.value = undefined;
expect(directive.value).toBe('');
directive.value = null;
expect(directive.value).toBe('');
directive.value = '';
expect(directive.value).toBe('');
});
it('should return formatted time', () => {
directive.timepicker = timepickerComponent;
directive.value = '11:00';
expect(directive.value).toBe('11:00 AM');
});
it('should call console.warn if time is not between min and max(inclusively) value', () => {
directive.timepicker = timepickerComponent;
const spy = spyOn(console, 'warn');
directive.min = '11:00 am';
directive.value = '10:00 am';
expect(spy).toHaveBeenCalledWith(consoleWarnValue);
directive.max = '11:30 am';
directive.value = '11:35 am';
directive.value = '11:20 am';
expect(spy).toHaveBeenCalledTimes(2);
});
it('should change value and default time on timeSet output', () => {
const time = '12:12 PM';
directive.timepicker = timepickerComponent;
timepickerComponent.timeSet.next(time);
expect(directive.value).toBe(time);
expect(timepickerComponent.defaultTime).toBe(time);
});
it('should change time onChange', () => {
directive.timepicker = timepickerComponent;
directive.updateValue('11:12');
expect(directive.value).toBe('11:12 AM');
});
it('should set invalid datetime if time is in inappropriate format', () => {
directive.timepicker = timepickerComponent;
directive.value = 'test';
expect(directive.value).toBe('Invalid DateTime');
});
it('should set default time if binding value changes', () => {
const changes: SimpleChanges = {
value: {
currentValue: '10:00 am',
firstChange: true,
previousValue: undefined,
isFirstChange: () => null
}
};
directive.timepicker = timepickerComponent;
directive.ngOnChanges(changes);
expect(timepickerComponent.defaultTime).toBe('10:00 AM');
});
it('should not set default time if binding value does not change ', () => {
const changes: SimpleChanges = {
min: {
currentValue: '11:00',
firstChange: true,
previousValue: undefined,
isFirstChange: () => null
}
};
directive.timepicker = timepickerComponent;
directive.ngOnChanges(changes);
expect(timepickerComponent.defaultTime).toBeUndefined();
});
it('should open timepicker on click', () => {
const spy = spyOn(timepickerComponent, 'open');
directive.timepicker = timepickerComponent;
directive.onClick({stopPropagation: () => null});
expect(spy).toHaveBeenCalled();
});
it('should not open timepicker on click if disableClick is true', () => {
const spy = spyOn(timepickerComponent, 'open');
directive.timepicker = timepickerComponent;
directive.disableClick = true;
directive.onClick({stopPropagation: () => null});
expect(spy).toHaveBeenCalledTimes(0);
});
it('should update time and default time on writeValue function', () => {
const time = '11:11 AM';
directive.timepicker = timepickerComponent;
directive.writeValue(time);
expect(directive.value).toBe(time);
expect(timepickerComponent.defaultTime).toBe(time);
});
it('should not change default time when writeValue called with undefined', () => {
directive.timepicker = timepickerComponent;
directive.writeValue(undefined);
expect(directive.value).toBe('');
expect(timepickerComponent.defaultTime).toBeUndefined();
});
it('should set onChange function on registerOnChange', () => {
directive.timepicker = timepickerComponent;
const spy = spyOn(console, 'log');
const time = '11:12 am';
directive.registerOnChange(console.log);
directive.updateValue(time);
expect(spy).toHaveBeenCalledWith(time);
});
it('should set onTouch function on registerOnTouched', () => {
const spy = spyOn(console, 'log');
directive.registerOnTouched(console.log);
directive.onTouched();
expect(spy).toHaveBeenCalled();
});
it('should change disabled state on setDisabledState', () => {
expect(directive.disabled).toBeFalsy();
directive.setDisabledState(true);
expect(directive.disabled).toBeTruthy();
});
describe('element getter', () => {
it('should return current HTMLInputElement', () => {
expect(directive.element).toEqual(input.nativeElement);
});
});
});