Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Missing locale info for Kendo Intl Service when testing with Jest in Angular 7

I had multiple tests for a very specific numeric component that handles locale formatting. The tests were fine with Karma, but once we changed it to Jest this error started to appear:

NoLocale: Missing locale info for 'de-DE' Solution: http://www.telerik.com/kendo-angular-ui/components/internationalization/troubleshooting/#toc-no-locale

I tried all the suggestion from the attached linked, but no one success.

The IntlService is initialized with en-US locale id, so I changed it for each test, depending the format that I wanted to assert (de-DE or en-GB).

These are the test examples in the component.spec.ts:

numeric-textbox.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NumericTextBoxComponent } from './numeric-textbox.component';
import { FormsModule } from '@angular/forms';
import { CldrIntlService, IntlModule, load } from '@progress/kendo-angular-intl';

describe('NumericTextBoxComponent', () => {
  let component: NumericTextBoxComponent;
  let fixture: ComponentFixture<NumericTextBoxComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ FormsModule, IntlModule ],
      declarations: [ NumericTextBoxComponent ],
    })
    .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('User writes valid numbers with German/International notation', () => {
    component.format = 'n2';
    (<CldrIntlService>component.intlService).localeId = 'de-DE';
    fixture.detectChanges();
      const displayValueInput: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('input');

  // absolute integer
  displayValueInput.value = '123456789';
  displayValueInput.dispatchEvent(new Event('input'));
  displayValueInput.dispatchEvent(new Event('focusout'));
  expect(component.inputValue).toBe('123456789');
  expect(component.displayValue).toBe('123.456.789,00');
});

it('displays the correct format when the control is created in english context', () => {
    component.format = 'n2';
    (<CldrIntlService>component.intlService).localeId = 'en-GB';
    fixture.detectChanges();
      const displayValueInput: HTMLInputElement = fixture.debugElement.nativeElement.querySelector('input');
      displayValueInput.value = '123456789.12';
      displayValueInput.dispatchEvent(new Event('input'));
      displayValueInput.dispatchEvent(new Event('focusout'));
      expect(component.inputValue).toBe('123456789.12');
      expect(component.displayValue).toBe('123,456,789.12');
  });

The rare thing is 'en-GB' locale is recognised by the Intl Service (so the test is running fine), but 'de-DE' is not.

My question is: How do I import the de-DE locale information to the test environment, so that it can be recognised by the Intl Service dynamically?

UPDATE May 10th '19

The fixture.whenStable().then(()=> {}) was causing an issue in the test error handling, so it was remove.


As an additional information, the focusout event triggers the following method in the component:

numeric-textbox.component.ts

onFocusOut(first: boolean = false): void {
      console.log("onFocusOut");
        if (this.isReadOnly && !first && !this.isFocusIn) { return; }
        this.isFocusIn = false;
        // save the temporal the editable display value into the inputValue.
        // if the escape key was pressed, then we undo the actual displayValue to the lastInputValue.
        this.inputValue = !this.wasEscapePressed ? this.displayValue : this.lastInputValue;
        this.wasEscapePressed = false;
        // update the readable display value with the absolute value of the input value (or zero if it is null, zero or empty).
        this.displayValue = this.formatDisplayValue(this.inputValue);
    }

formatDisplayValue(input: string): string {
        // single signs, nulls, empty and zeros are shown as zero
        if (this.checkNullZeroOrEmpty(input) || this.isSignOnly(input)) {
            input = NumericTextBoxComponent.ZERO;
        } else if (this.IsPositiveValue(input) && input[0] === NumericTextBoxComponent.PLUS_SIGN) {
            // positive signs at the beginning are trim
            input = input.replace(NumericTextBoxComponent.PLUS_SIGN, '');
        }

        // display value are always the absolute value
        const numberValue = Math.abs(this.getNumberValue(input));

        // finally return the number formatted based in the locale. 
        return this.intlService.formatNumber(numberValue, this.format);
    }

So, when I made focus out of the input HTML element, the display value is formatted depending the locale.

like image 738
Tito Leiva Avatar asked May 07 '19 11:05

Tito Leiva


1 Answers

I suggest you try to import it as it is described in the documentation you linked to in the chapter loading additional locale data. Since you don't mention that you load additional locales I assume you are not doing it at all. Else please provide additional information how you load them.

For the de locale you need to add the following import.

// Load all required data for the de locale
import '@progress/kendo-angular-intl/locales/de/all';
like image 113
AlesD Avatar answered Oct 07 '22 23:10

AlesD