Untitled

mail@pastecode.io avatar
unknown
typescript
21 days ago
7.1 kB
14
Indexable
Never
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { BrnSelectContentComponent } from './brn-select-content.component';
import { BrnSelectOptionDirective } from './brn-select-option.directive';
import { BrnSelectTriggerDirective } from './brn-select-trigger.directive';
import { BrnSelectValueComponent } from './brn-select-value.component';
import { BrnSelectComponent } from './brn-select.component';

describe('BrnSelectComponent', () => {
	describe('Single select', () => {
		@Component({
			selector: 'brn-single-select-test',
			standalone: true,
			imports: [
				ReactiveFormsModule,
				BrnSelectComponent,
				BrnSelectOptionDirective,
				BrnSelectTriggerDirective,
				BrnSelectValueComponent,
				BrnSelectContentComponent,
			],
			template: `
				<brn-select [formControl]="formControl">
					<button brnSelectTrigger>
						<brn-select-value />
					</button>

					<brn-select-content>
						@for (option of options; track option.value) {
							<button brnOption [value]="option.value" [attr.data-test-value]="option.value">{{ option.label }}</button>
						}
					</brn-select-content>
				</brn-select>
			`,
			changeDetection: ChangeDetectionStrategy.OnPush,
		})
		class SingleSelectTestComponent {
			readonly options = [
				{
					value: '1',
					label: 'Option 1',
				},
				{
					value: '2',
					label: 'Option 2',
				},
			];
			readonly formControl = new FormControl<string | null>(null);
		}

		let component: SingleSelectTestComponent;
		let fixture: ComponentFixture<SingleSelectTestComponent>;

		beforeEach(() => TestBed.configureTestingModule({ imports: [SingleSelectTestComponent] }).compileComponents());

		beforeEach(() => {
			fixture = TestBed.createComponent(SingleSelectTestComponent);
			component = fixture.componentInstance;
		});

		it('should create', () => {
			fixture.detectChanges();
			expect(component).toBeTruthy();
			expect(component.formControl.pristine).toBe(true);
			expect(component.formControl.value).toBe(null);
		});

		it('should create with default value', () => {
			component.formControl.setValue('1');
			fixture.detectChanges();
			expect(component).toBeTruthy();
			expect(component.formControl.pristine).toBe(true);
			expect(component.formControl.value).toBe('1');
		});

		it('should update the form control when an option is selected', () => {
			fixture.detectChanges();
			expect(component.formControl.value).toBe(null);

			fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.click();
			fixture.detectChanges();

			fixture.debugElement.query(By.css('button[brnOption][data-test-value="1"]')).nativeElement.click();
			fixture.detectChanges();

			expect(component.formControl.value).toBe('1');

			fixture.debugElement.query(By.css('button[brnOption][data-test-value="2"]')).nativeElement.click();
			fixture.detectChanges();

			expect(component.formControl.value).toBe('2');
		});

		it('should update trigger when an option is selected programatically', () => {
			fixture.detectChanges();
			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe('');

			component.formControl.setValue('1');
			fixture.detectChanges();

			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe(
				'Option 1',
			);

			component.formControl.setValue('2');
			fixture.detectChanges();

			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe(
				'Option 2',
			);
		});
	});

	describe('Multi select', () => {
		let component: MultiSelectTestComponent;
		let fixture: ComponentFixture<MultiSelectTestComponent>;

		@Component({
			selector: 'brn-multi-select-test',
			standalone: true,
			imports: [
				ReactiveFormsModule,
				BrnSelectComponent,
				BrnSelectOptionDirective,
				BrnSelectTriggerDirective,
				BrnSelectValueComponent,
				BrnSelectContentComponent,
			],
			template: `
				<brn-select [formControl]="formControl" [multiple]="true">
					<button brnSelectTrigger>
						<brn-select-value />
					</button>

					<brn-select-content>
						@for (option of options; track option.value) {
							<button brnOption [value]="option.value" [attr.data-test-value]="option.value">{{ option.label }}</button>
						}
					</brn-select-content>
				</brn-select>
			`,
			changeDetection: ChangeDetectionStrategy.OnPush,
		})
		class MultiSelectTestComponent {
			readonly options = [
				{
					value: '1',
					label: 'Option 1',
				},
				{
					value: '2',
					label: 'Option 2',
				},
			];
			readonly formControl = new FormControl<string[] | null>(null);
		}

		beforeEach(() => TestBed.configureTestingModule({ imports: [MultiSelectTestComponent] }).compileComponents());

		beforeEach(() => {
			fixture = TestBed.createComponent(MultiSelectTestComponent);
			component = fixture.componentInstance;
			fixture.detectChanges();
		});

		it('should create', () => {
			fixture.detectChanges();
			expect(component).toBeTruthy();
			expect(component.formControl.pristine).toBe(true);
			expect(component.formControl.value).toBe(null);
		});

		it('should create with default value', () => {
			component.formControl.setValue(['1']);
			fixture.detectChanges();
			expect(component).toBeTruthy();
			expect(component.formControl.pristine).toBe(true);
			expect(component.formControl.value).toBe(['1']);
		});

		it('should update the form control when an option is selected', () => {
			fixture.detectChanges();
			expect(component.formControl.value).toBe(null);

			fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.click();
			fixture.detectChanges();

			fixture.debugElement.query(By.css('button[brnOption][data-test-value="1"]')).nativeElement.click();
			fixture.detectChanges();

			expect(component.formControl.value).toEqual(['1']);

			fixture.debugElement.query(By.css('button[brnOption][data-test-value="2"]')).nativeElement.click();
			fixture.detectChanges();

			expect(component.formControl.value).toEqual(['1', '2']);
		});

		it('should update trigger when an option is selected programatically', () => {
			fixture.detectChanges();
			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe('');

			component.formControl.setValue(['1']);
			fixture.detectChanges();

			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe(
				'Option 1',
			);

			component.formControl.setValue(['2']);
			fixture.detectChanges();

			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe(
				'Option 2',
			);

			component.formControl.setValue(['1', '2']);
			fixture.detectChanges();

			expect(fixture.debugElement.query(By.css('button[brnSelectTrigger]')).nativeElement.textContent.trim()).toBe(
				'Option 1, Option 2',
			);
		});
	});
});
Leave a Comment