import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormControl, ReactiveFormsModule } from '@angular/forms';
import { GfLocalizedNumberDirective } from './localized-number.directive';
@Component({
imports: [GfLocalizedNumberDirective, ReactiveFormsModule],
template: `
`
})
class TestHostComponent {
public control = new FormControl(null);
public locale = 'en-US';
}
describe('GfLocalizedNumberDirective', () => {
let fixture: ComponentFixture;
let host: TestHostComponent;
let input: HTMLInputElement;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [TestHostComponent]
}).compileComponents();
fixture = TestBed.createComponent(TestHostComponent);
host = fixture.componentInstance;
fixture.detectChanges();
input = fixture.nativeElement.querySelector('input');
});
function typeValue(value: string) {
input.value = value;
input.dispatchEvent(new Event('input'));
fixture.detectChanges();
}
it('should force type="text" and inputmode="decimal"', () => {
expect(input.getAttribute('type')).toBe('text');
expect(input.getAttribute('inputmode')).toBe('decimal');
});
it('should parse English grouped numbers', () => {
host.locale = 'en-US';
fixture.detectChanges();
typeValue('1,234.50');
expect(host.control.value).toBe(1234.5);
typeValue('1234.50');
expect(host.control.value).toBe(1234.5);
});
it('should parse German grouped numbers', () => {
host.locale = 'de-DE';
fixture.detectChanges();
typeValue('1.234,50');
expect(host.control.value).toBe(1234.5);
typeValue('1234,50');
expect(host.control.value).toBe(1234.5);
typeValue('12.345.678,90');
expect(host.control.value).toBe(12345678.9);
});
it('should set null for empty or invalid input', () => {
typeValue('');
expect(host.control.value).toBeNull();
typeValue(' ');
expect(host.control.value).toBeNull();
typeValue('abc');
expect(host.control.value).toBeNull();
});
it('should write programmatic values to the input', () => {
host.control.setValue(1234.5);
fixture.detectChanges();
expect(input.value).toBe('1,234.5');
host.control.setValue(null);
fixture.detectChanges();
expect(input.value).toBe('');
});
it('should write and parse correctly for German locale (de-DE)', () => {
host.locale = 'de-DE';
fixture.detectChanges();
host.control.setValue(1234.5);
fixture.detectChanges();
expect(input.value).toBe('1.234,5');
typeValue('1.234,5');
expect(host.control.value).toBe(1234.5);
});
it('should preserve more than 3 fraction digits on write/parse', () => {
host.locale = 'de-DE';
fixture.detectChanges();
host.control.setValue(12.345678);
fixture.detectChanges();
expect(input.value).toBe('12,345678');
typeValue(input.value);
expect(host.control.value).toBe(12.345678);
});
it('should write empty string for non-numeric values', () => {
host.control.setValue('' as unknown as number);
fixture.detectChanges();
expect(input.value).toBe('');
});
it('should keep required validation working', () => {
host.locale = 'de-DE';
host.control.setValidators([
(control) => {
return control.value === null || control.value === undefined
? { required: true }
: null;
}
]);
host.control.updateValueAndValidity();
fixture.detectChanges();
typeValue('');
expect(host.control.hasError('required')).toBe(true);
typeValue('1.234,50');
expect(host.control.hasError('required')).toBe(false);
expect(host.control.value).toBe(1234.5);
});
});