/// /// Copyright 2015-2026 Micro Focus or one of its affiliates. /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// import { Component, Input } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { IconComponent } from './icon.component'; import { IconModule } from './icon.module'; import { IconService } from './icon.service'; @Component({ selector: 'ux-icon-test', template: ``, imports: [IconModule], }) export class IconTestComponent { @Input() name: string; @Input() size: string; @Input() rotate: 90 | 180 | 270; @Input() flipHorizontal: boolean; @Input() flipVertical: boolean; } describe('Icon Component', () => { let component: IconTestComponent; let fixture: ComponentFixture; let iconElement: HTMLElement; let service: IconService; beforeEach(() => { TestBed.configureTestingModule({ imports: [IconModule, IconTestComponent], }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(IconTestComponent); component = fixture.componentInstance; iconElement = fixture.elementRef.nativeElement.querySelector('ux-icon'); service = fixture.debugElement.query(By.directive(IconComponent)).injector.get(IconService); fixture.detectChanges(); }); it('should create the component', () => { expect(component).toBeTruthy(); }); /** * Use Case 1 * Allow icons to be looked up from iconset by name */ it('should assign the correct classes based on the specified icon name', () => { component.name = 'alert'; fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); }); it('should not override any user defined classes', () => { component.name = 'alert'; iconElement.classList.add('custom-class'); fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); expect(iconElement.classList.contains('custom-class')).toBeTruthy(); }); /** * Use Case 2 * Allow substitution of icon class and iconset class */ it('should assign the correct classes based on the specified icon name', () => { component.name = 'alert'; // perform an override using the service service.setIcon({ name: 'alert', icon: 'qtm-icon-error', iconset: 'qtm-font-icon' }); fixture.detectChanges(); expect(iconElement.classList.contains('qtm-icon-error')).toBeTruthy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeTruthy(); }); it('should update existing icons if the definition changes after initialisation', () => { component.name = 'alert'; fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); // perform an override using the service service.setIcon({ name: 'alert', icon: 'qtm-icon-error', iconset: 'qtm-font-icon' }); fixture.detectChanges(); expect(iconElement.classList.contains('qtm-icon-error')).toBeTruthy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeTruthy(); }); /** * Use Case 3 * Allow transformation of an icon */ it('should assign the correct classes based on the specified rotation', () => { component.name = 'alert'; component.rotate = 90; fixture.detectChanges(); expect(iconElement.classList.contains('ux-rotate-90')).toBeTruthy(); component.rotate = 180; fixture.detectChanges(); expect(iconElement.classList.contains('ux-rotate-180')).toBeTruthy(); component.rotate = 270; fixture.detectChanges(); expect(iconElement.classList.contains('ux-rotate-270')).toBeTruthy(); }); it('should assign the correct classes based on the specified flip', () => { component.name = 'alert'; component.flipHorizontal = true; fixture.detectChanges(); expect(iconElement.classList.contains('ux-flip-horizontal')).toBeTruthy(); component.flipVertical = true; fixture.detectChanges(); expect(iconElement.classList.contains('ux-flip-vertical')).toBeTruthy(); }); it('should assign the correct style based on the specified size', () => { component.name = 'alert'; component.size = '24px'; fixture.detectChanges(); expect(iconElement.style.fontSize).toBe('24px'); component.size = '3rem'; fixture.detectChanges(); expect(iconElement.style.fontSize).toBe('3rem'); component.size = '2em'; fixture.detectChanges(); expect(iconElement.style.fontSize).toBe('2em'); }); /** * Use Case 4 * Allow alternate glyphs for different font sizes. */ it('should allow alternate glyphs for different font sizes', () => { component.name = 'alert'; // perform an override using the service service.setIcon({ name: 'alert', icon: 'qtm-icon-error', iconset: 'qtm-font-icon', size: '24px', }); fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeFalsy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeFalsy(); fixture.componentRef.setInput('size', '24px'); fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeFalsy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeFalsy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeTruthy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeTruthy(); }); it('should allow alternate glyphs for different font sizes (array)', () => { component.name = 'alert'; // perform an override using the service service.setIcon({ name: 'alert', icon: 'qtm-icon-error', iconset: 'qtm-font-icon', size: ['24px', '32px'], }); fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeFalsy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeFalsy(); component.size = '24px'; fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeFalsy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeFalsy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeTruthy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeTruthy(); component.size = '28px'; fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeTruthy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeTruthy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeFalsy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeFalsy(); component.size = '32px'; fixture.detectChanges(); expect(iconElement.classList.contains('ux-icon')).toBeFalsy(); expect(iconElement.classList.contains('ux-icon-alert')).toBeFalsy(); expect(iconElement.classList.contains('qtm-icon-error')).toBeTruthy(); expect(iconElement.classList.contains('qtm-font-icon')).toBeTruthy(); }); });