// tslint:disable:max-file-line-count no-floating-promises
import { ChangeDetectionStrategy, ChangeDetectorRef, Component } from '@angular/core';
import { ComponentFixture, ComponentFixtureAutoDetect, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { ButtonsModule } from '../buttons/buttons.module';
@Component({selector: 'buttons-test', template: ''})
class TestButtonsComponent {
singleModel = '0';
checkModel: any = {left: false, middle: true, right: false};
radioModel = 'Middle';
constructor(public cdRef: ChangeDetectorRef) {}
}
const html = `
`;
function createComponent(htmlTemplate,
dtc?: string): ComponentFixture {
switch (dtc) {
case 'OnPush':
TestBed.overrideComponent(TestButtonsComponent, {
set: {
template: htmlTemplate,
changeDetection: ChangeDetectionStrategy.OnPush
}
});
break;
default:
TestBed.overrideComponent(TestButtonsComponent, {
set: {template: htmlTemplate}
});
}
const fixture = TestBed.createComponent(TestButtonsComponent);
fixture.detectChanges();
return fixture;
}
describe('Directive: Buttons', () => {
let fixture: ComponentFixture;
let context: any;
let element: any;
beforeEach(
fakeAsync(() => {
TestBed.configureTestingModule({
declarations: [TestButtonsComponent],
imports: [ButtonsModule, FormsModule],
providers: [{provide: ComponentFixtureAutoDetect, useValue: true}]
});
})
);
describe('checkbox', () => {
it(
'should work correctly with default model values',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
expect(element.querySelector('#default').classList).not.toContain(
'active'
);
context.singleModel = true;
fixture.detectChanges();
tick();
expect(element.querySelector('#default').classList).toContain('active');
})
);
it(
'should work correctly with default model values with OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
expect(element.querySelector('#default').classList).not.toContain(
'active'
);
context.singleModel = true;
fixture.detectChanges();
tick();
expect(element.querySelector('#default').classList).toContain('active');
})
);
it(
'should bind custom model values',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
expect(element.querySelector('#custom').classList).not.toContain(
'active'
);
context.singleModel = '1';
fixture.detectChanges();
tick();
expect(element.querySelector('#custom').classList).toContain('active');
})
);
it(
'should bind custom model values with OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
expect(element.querySelector('#custom').classList).not.toContain(
'active'
);
context.singleModel = '1';
fixture.detectChanges();
tick();
expect(element.querySelector('#custom').classList).toContain('active');
})
);
it('should toggle default model values on click', () => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
context.singleModel = false;
fixture.detectChanges();
const btn = element.querySelector('#default');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(true);
expect(btn.classList).toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
});
it('should toggle default model values on click OnPush', () => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
context.singleModel = false;
fixture.detectChanges();
const btn = element.querySelector('#default');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(true);
expect(btn.classList).toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
});
it('should toggle custom model values on click', () => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
const btn = element.querySelector('#custom');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual('1');
expect(btn.classList).toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual('0');
expect(btn.classList).not.toContain('active');
});
it('should toggle custom model values on click OnPush', () => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
const btn = element.querySelector('#custom');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual('1');
expect(btn.classList).toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual('0');
expect(btn.classList).not.toContain('active');
});
it('should not toggle when disabled', () => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
context.singleModel = false;
fixture.detectChanges();
const btn = element.querySelector('#disabled');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
});
it('should not toggle when disabled OnPush', () => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
context.singleModel = false;
fixture.detectChanges();
const btn = element.querySelector('#disabled');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
btn.click();
fixture.detectChanges();
expect(context.singleModel).toEqual(false);
expect(btn.classList).not.toContain('active');
});
it(
'should work for btn-group',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
const btn = element.querySelector('.btn-group.checkbox');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
});
})
);
it(
'should work for btn-group OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
fixture.whenStable().then(() => {
const btn = element.querySelector('.btn-group.checkbox');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
});
})
);
});
describe('radio', () => {
it(
'should set active class based on model',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
const btn = element.querySelector('.btn-group.radio');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
context.radioModel = 'Left';
fixture.detectChanges();
tick();
expect(btn.children[0].classList).toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should set active class based on model OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
context.cdRef.markForCheck();
const btn = element.querySelector('.btn-group.radio');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
context.radioModel = 'Left';
fixture.detectChanges();
tick();
expect(btn.children[0].classList).toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should set active class via click',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
const btn = element.querySelector('.btn-group.radio');
delete context.radioModel;
expect(context.radioModel).toBeUndefined();
(btn.children[2] as HTMLElement).click();
fixture.detectChanges();
tick();
expect(context.radioModel).toEqual('Right');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).toContain('active');
(btn.children[1] as HTMLElement).click();
fixture.detectChanges();
tick();
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should set active class via click OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
context.cdRef.markForCheck();
const btn = element.querySelector('.btn-group.radio');
delete context.radioModel;
expect(context.radioModel).toBeUndefined();
(btn.children[2] as HTMLElement).click();
fixture.detectChanges();
tick();
expect(context.radioModel).toEqual('Right');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).toContain('active');
(btn.children[1] as HTMLElement).click();
fixture.detectChanges();
tick();
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should do nothing when clicking an active radio',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
const btn = element.querySelector('.btn-group.radio');
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
(btn.children[1] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should do nothing when clicking an active radio OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
context.cdRef.markForCheck();
const btn = element.querySelector('.btn-group.radio');
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
(btn.children[1] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioModel).toEqual('Middle');
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
})
);
it(
'should not toggle when disabled',
fakeAsync(() => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
const btn = element.querySelector('.btn-group.radio');
expect(context.radioModel).toEqual('Middle');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
context.radioModel = '1';
fixture.detectChanges();
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
(btn.children[3] as HTMLElement).click();
fixture.detectChanges();
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
})
);
it(
'should not toggle when disabled OnPush',
fakeAsync(() => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
fixture.detectChanges();
tick();
fixture.detectChanges();
context.cdRef.markForCheck();
const btn = element.querySelector('.btn-group.radio');
expect(context.radioModel).toEqual('Middle');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
context.radioModel = '1';
fixture.detectChanges();
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
(btn.children[3] as HTMLElement).click();
fixture.detectChanges();
expect(btn.children[1].classList).toContain('active');
expect(btn.children[3].classList).not.toContain('active');
})
);
it('should not toggle when click in active button without uncheckable', () => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
const btn = element.querySelector('.btn-group.radio');
expect(context.radioModel).toEqual('Middle');
(btn.children[1] as HTMLElement).click();
fixture.detectChanges();
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).toContain('active');
expect(btn.children[2].classList).not.toContain('active');
});
it('should unset active class via click', () => {
fixture = createComponent(html);
context = fixture.componentInstance;
element = fixture.nativeElement;
const btn = element.querySelector('.btn-group.radioUncheckable');
expect(context.radioUncheckableModel).toBeUndefined();
(btn.children[0] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioUncheckableModel).toEqual('Left');
expect(btn.children[0].classList).toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
(btn.children[0] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioUncheckableModel).toBeUndefined();
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
});
it('should unset active class via click OnPush', () => {
fixture = createComponent(html, 'OnPush');
context = fixture.componentInstance;
element = fixture.nativeElement;
context.cdRef.markForCheck();
const btn = element.querySelector('.btn-group.radioUncheckable');
expect(context.radioUncheckableModel).toBeUndefined();
(btn.children[0] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioUncheckableModel).toEqual('Left');
expect(btn.children[0].classList).toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
(btn.children[0] as HTMLElement).click();
fixture.detectChanges();
expect(context.radioUncheckableModel).toBeUndefined();
expect(btn.children[0].classList).not.toContain('active');
expect(btn.children[1].classList).not.toContain('active');
expect(btn.children[2].classList).not.toContain('active');
});
});
});