igniteui-angular-sovn
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
417 lines (335 loc) • 15 kB
text/typescript
import { Component, ViewChild } from '@angular/core';
import { TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { IgxRadioGroupDirective } from './radio-group.directive';
import { FormsModule, ReactiveFormsModule, UntypedFormGroup, UntypedFormBuilder } from '@angular/forms';
import { configureTestSuite } from '../../test-utils/configure-suite';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser';
import { IgxRadioComponent } from '../../radio/radio.component';
import { NgFor } from '@angular/common';
describe('IgxRadioGroupDirective', () => {
configureTestSuite();
beforeAll(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
FormsModule,
ReactiveFormsModule,
NoopAnimationsModule,
RadioGroupComponent,
RadioGroupSimpleComponent,
RadioGroupWithModelComponent,
RadioGroupRequiredComponent,
RadioGroupReactiveFormsComponent,
RadioGroupDeepProjectionComponent
]
})
.compileComponents();
}));
it('Properly initialize the radio group buttons\' properties.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
expect(radioInstance.radioButtons).toBeDefined();
expect(radioInstance.radioButtons.length).toEqual(3);
const allRequiredButtons = radioInstance.radioButtons.filter((btn) => btn.required);
expect(allRequiredButtons.length).toEqual(radioInstance.radioButtons.length);
const allButtonsWithGroupName = radioInstance.radioButtons.filter((btn) => btn.name === radioInstance.name);
expect(allButtonsWithGroupName.length).toEqual(radioInstance.radioButtons.length);
const buttonWithGroupValue = radioInstance.radioButtons.find((btn) => btn.value === radioInstance.value);
expect(buttonWithGroupValue).toBeDefined();
expect(buttonWithGroupValue).toEqual(radioInstance.selected);
}));
it('Setting radioGroup\'s properties should affect all radio buttons.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
expect(radioInstance.radioButtons).toBeDefined();
// name
radioInstance.name = 'newGroupName';
fixture.detectChanges();
const allButtonsWithNewName = radioInstance.radioButtons.filter((btn) => btn.name === 'newGroupName');
expect(allButtonsWithNewName.length).toEqual(radioInstance.radioButtons.length);
// required
radioInstance.required = true;
fixture.detectChanges();
const allRequiredButtons = radioInstance.radioButtons.filter((btn) => btn.required);
expect(allRequiredButtons.length).toEqual(radioInstance.radioButtons.length);
// invalid
radioInstance.invalid = true;
fixture.detectChanges();
const allInvalidButtons = radioInstance.radioButtons.filter((btn) => btn.invalid);
expect(allInvalidButtons.length).toEqual(radioInstance.radioButtons.length);
}));
it('Set value should change selected property', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
expect(radioInstance.value).toBeDefined();
expect(radioInstance.value).toEqual('Baz');
expect(radioInstance.selected).toBeDefined();
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.last);
spyOn(radioInstance.change, 'emit');
radioInstance.value = 'Foo';
fixture.detectChanges();
expect(radioInstance.value).toEqual('Foo');
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
expect(radioInstance.change.emit).not.toHaveBeenCalled();
}));
it('Set selected property should change value', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
expect(radioInstance.value).toBeDefined();
expect(radioInstance.value).toEqual('Baz');
expect(radioInstance.selected).toBeDefined();
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.last);
spyOn(radioInstance.change, 'emit');
radioInstance.selected = radioInstance.radioButtons.first;
fixture.detectChanges();
expect(radioInstance.value).toEqual('Foo');
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
expect(radioInstance.change.emit).not.toHaveBeenCalled();
}));
it('Clicking on a radio button should update the model.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupWithModelComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
radioInstance.radioButtons.first.nativeLabel.nativeElement.click();
fixture.detectChanges();
tick();
expect(radioInstance.value).toEqual('Winter');
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
}));
it('Updating the model should select a radio button.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupWithModelComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
fixture.componentInstance.personBob.favoriteSeason = 'Winter';
fixture.detectChanges();
tick();
expect(radioInstance.value).toEqual('Winter');
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.first);
}));
it('Properly update the model when radio group is hosted in Reactive forms.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupReactiveFormsComponent);
fixture.detectChanges();
tick();
expect(fixture.componentInstance.personForm).toBeDefined();
expect(fixture.componentInstance.model).toBeDefined();
expect(fixture.componentInstance.newModel).toBeUndefined();
fixture.componentInstance.personForm.patchValue({ favoriteSeason: fixture.componentInstance.seasons[0] });
fixture.componentInstance.updateModel();
fixture.detectChanges();
tick();
expect(fixture.componentInstance.newModel).toBeDefined();
expect(fixture.componentInstance.newModel.name).toEqual(fixture.componentInstance.model.name);
expect(fixture.componentInstance.newModel.favoriteSeason).toEqual(fixture.componentInstance.seasons[0]);
}));
it('Properly initialize selection when value is falsy in deep content projection', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupDeepProjectionComponent);
fixture.detectChanges();
tick();
const radioGroup = fixture.componentInstance.radioGroup;
expect(radioGroup.value).toEqual(0);
expect(radioGroup.radioButtons.first.checked).toEqual(true);
}));
it('Properly rebind dynamically added components', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupDeepProjectionComponent);
const radioInstance = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
fixture.componentInstance.choices = [ 0, 1, 4, 7 ];
fixture.detectChanges();
tick();
radioInstance.radioButtons.last.nativeLabel.nativeElement.click();
fixture.detectChanges();
tick();
expect(radioInstance.value).toEqual(7);
expect(radioInstance.selected).toEqual(radioInstance.radioButtons.last);
}));
it('Updates checked radio button correctly', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupSimpleComponent);
fixture.detectChanges();
tick();
const radioGroup = fixture.componentInstance.radioGroup;
expect(radioGroup.radioButtons.first.checked).toEqual(true);
expect(radioGroup.radioButtons.last.checked).toEqual(false);
radioGroup.radioButtons.last.select();
fixture.detectChanges();
tick();
expect(radioGroup.radioButtons.first.checked).toEqual(false);
expect(radioGroup.radioButtons.last.checked).toEqual(true);
}));
it('Should update styles correctly when required radio group\'s value is set.', fakeAsync(() => {
const fixture = TestBed.createComponent(RadioGroupRequiredComponent);
const radioGroup = fixture.componentInstance.radioGroup;
fixture.detectChanges();
tick();
const domRadio = fixture.debugElement.query(By.css('igx-radio')).nativeElement;
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(false);
expect(radioGroup.selected).toBeUndefined;
expect(radioGroup.invalid).toBe(false);
dispatchRadioEvent('keyup', domRadio, fixture);
expect(domRadio.classList.contains('igx-radio--focused')).toBe(true);
dispatchRadioEvent('blur', domRadio, fixture);
fixture.detectChanges();
tick();
expect(radioGroup.invalid).toBe(true);
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(true);
dispatchRadioEvent('keyup', domRadio, fixture);
expect(domRadio.classList.contains('igx-radio--focused')).toBe(true);
radioGroup.radioButtons.first.select();
fixture.detectChanges();
tick();
expect(domRadio.classList.contains('igx-radio--checked')).toBe(true);
expect(radioGroup.invalid).toBe(false);
expect(radioGroup.radioButtons.first.checked).toEqual(true);
expect(domRadio.classList.contains('igx-radio--invalid')).toBe(false);
}));
});
class RadioGroupSimpleComponent {
public radioGroup: IgxRadioGroupDirective;
}
class RadioGroupComponent {
public radioGroup: IgxRadioGroupDirective;
}
class RadioGroupRequiredComponent {
public radioGroup: IgxRadioGroupDirective;
}
interface Person {
name: string;
favoriteSeason: string;
}
class RadioGroupWithModelComponent {
public radioGroup: IgxRadioGroupDirective;
public seasons = [
'Winter',
'Spring',
'Summer',
'Autumn',
];
public personBob: Person = { name: 'Bob', favoriteSeason: 'Summer' };
}
class RadioGroupReactiveFormsComponent {
public seasons = [
'Winter',
'Spring',
'Summer',
'Autumn',
];
public newModel: Person;
public model: Person = { name: 'Kirk', favoriteSeason: this.seasons[1] };
public personForm: UntypedFormGroup;
constructor(private _formBuilder: UntypedFormBuilder) {
this._createForm();
}
public updateModel() {
const formModel = this.personForm.value;
this.newModel = {
name: formModel.name as string,
favoriteSeason: formModel.favoriteSeason as string
};
}
private _createForm() {
// create form
this.personForm = this._formBuilder.group({
name: '',
favoriteSeason: ''
});
// simulate model loading from service
this.personForm.setValue({
name: this.model.name,
favoriteSeason: this.model.favoriteSeason
});
}
}
class RadioGroupDeepProjectionComponent {
public radioGroup: IgxRadioGroupDirective;
public choices = [0, 1, 2];
public group1: UntypedFormGroup;
constructor(private _builder: UntypedFormBuilder) {
this._createForm();
}
private _createForm() {
this.group1 = this._builder.group({
favouriteChoice: 0
});
}
}
const dispatchRadioEvent = (eventName, radioNativeElement, fixture) => {
radioNativeElement.dispatchEvent(new Event(eventName));
fixture.detectChanges();
};