Skip to content

Commit

Permalink
refactor: fix + adjusted #7 and #8 merge result
Browse files Browse the repository at this point in the history
  • Loading branch information
cerinoligutom committed Mar 15, 2023
1 parent af7f0ea commit e8ae072
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 88 deletions.
89 changes: 20 additions & 69 deletions projects/ngx-fluent/src/lib/ngx-fluent.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,20 @@ describe('NgxFluentService', () => {
let fluentService: NgxFluentService;
let httpSpy: jasmine.SpyObj<HttpClient>;

describe('SetTranslationSourceMap option uses Record<string, string>', () => {
beforeEach(() => {
const _httpSpy = jasmine.createSpyObj('HttpClient', ['get', 'pipe']);
beforeEach(() => {
const _httpSpy = jasmine.createSpyObj('HttpClient', ['get', 'pipe']);

TestBed.configureTestingModule({
providers: [NgxFluentService, { provide: HttpClient, useValue: _httpSpy }],
});
TestBed.configureTestingModule({
providers: [NgxFluentService, { provide: HttpClient, useValue: _httpSpy }],
});

httpSpy = TestBed.inject(HttpClient) as jasmine.SpyObj<HttpClient>;
httpSpy.get.and.returnValue(of(''));
httpSpy = TestBed.inject(HttpClient) as jasmine.SpyObj<HttpClient>;
httpSpy.get.and.returnValue(of(''));

fluentService = TestBed.inject(NgxFluentService);
fluentService.setTranslationSourceMap({
en: 'assets/locales/en.ftl',
});
});
fluentService = TestBed.inject(NgxFluentService);
});

function runCommonTests() {
it('localeChanges should emit new locale', () => {
fluentService.setLocale('test-locale');

Expand Down Expand Up @@ -72,71 +69,25 @@ describe('NgxFluentService', () => {
const result = await fluentService.translate(key);
expect(result).toBeNull();
});
});
}

describe('SetTranslationSourceMap option uses Record<string, FluentBundleOptions>', () => {
describe('SetTranslationSourceMap option uses Record<string, string>', () => {
beforeEach(() => {
const _httpSpy = jasmine.createSpyObj('HttpClient', ['get', 'pipe']);

TestBed.configureTestingModule({
providers: [NgxFluentService, { provide: HttpClient, useValue: _httpSpy }],
});

httpSpy = TestBed.inject(HttpClient) as jasmine.SpyObj<HttpClient>;
httpSpy.get.and.returnValue(of(''));

fluentService = TestBed.inject(NgxFluentService);
fluentService.setTranslationSourceMap({
en: { path: 'assets/locales/en.ftl', bundleConfig: { useIsolating: false } },
en: 'assets/locales/en.ftl',
});
});

it('localeChanges should emit new locale', () => {
fluentService.setLocale('test-locale');
runCommonTests();
});

fluentService.localeChanges.subscribe((locale) => {
expect(locale).toBe('test-locale');
describe('SetTranslationSourceMap option uses Record<string, FluentBundleOptions>', () => {
beforeEach(() => {
fluentService.setTranslationSourceMap({
en: { path: 'assets/locales/en.ftl', bundleConfig: undefined },
});
});

it('currentLocale should return null initially', () => {
expect(fluentService.currentLocale).toBeNull();
});

it('currentLocale should return new locale after setting setLocale', () => {
fluentService.setLocale('en');
expect(fluentService.currentLocale).toBe('en');
});

it('unresolved locale returns null', async () => {
const key = 'test-key';
fluentService.setLocale('non-existent');

const result = await fluentService.translate(key);
expect(result).toBeNull();
});

it('resolved locale and message returns translation', async () => {
const key = 'test-key';
const value = 'test-translation';
const translation = `${key} = ${value}`;

httpSpy.get.and.returnValue(of(translation));
fluentService.setLocale('en');

const result = await fluentService.translate(key);
expect(result).toBe(value);
});

it('resolved locale and unresolved message returns null', async () => {
const key = 'unknown-key';
const translation = 'test-key = test-translation';

httpSpy.get.and.returnValue(of(translation));
fluentService.setLocale('en');

const result = await fluentService.translate(key);
expect(result).toBeNull();
});
runCommonTests();
});
});
30 changes: 22 additions & 8 deletions projects/ngx-fluent/src/lib/ngx-fluent.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { Injectable } from '@angular/core';
import { BehaviorSubject, map, catchError, of, lastValueFrom } from 'rxjs';
import { FluentBundle, FluentResource } from '@fluent/bundle';

import { TranslationSource } from './translation-source.interface';
import type { TranslationSourceConfig, TranslationSourceMap } from './types';

@Injectable({
providedIn: 'root',
})
export class NgxFluentService {
private locale = new BehaviorSubject<string | null>(null);

private translationSourceMap: Record<string, string | TranslationSource> = {};
private translationSourceMap: TranslationSourceMap = {};
private translationsMap = new Map<string, FluentBundle | null>();

localeChanges = this.locale.asObservable();
Expand All @@ -25,14 +25,25 @@ export class NgxFluentService {
return of(translationBundle);
}

// If we don't have the translation, fetch it.
// If we don't have the translation, try to fetch it.
const source = this.translationSourceMap[locale] ?? '';
const path = typeof source === 'string' ? source : source.path;

if (source instanceof FluentBundle) {
this.translationsMap.set(locale, source);
return of(source);
}

let path: string;
let config: TranslationSourceConfig['bundleConfig'];
if (source && typeof source !== 'string') {
path = source.path;
config = source.bundleConfig;
} else {
path = source;
}

return this.http.get(path, { responseType: 'text' }).pipe(
map((content) => {
let config;
if (typeof source !== 'string') config = source.bundleConfig;
const bundle = new FluentBundle(locale, config);
const resource = new FluentResource(content);
const errors = bundle.addResource(resource);
Expand Down Expand Up @@ -63,8 +74,11 @@ export class NgxFluentService {
});
}

setTranslationSourceMap(translationSourceMap: Record<string, string | TranslationSource>) {
this.translationSourceMap = translationSourceMap;
setTranslationSourceMap(translationSourceMap: TranslationSourceMap) {
this.translationSourceMap = {
...this.translationSourceMap,
...translationSourceMap,
};
}

async translate(key: string, args?: any): Promise<string | null> {
Expand Down
10 changes: 0 additions & 10 deletions projects/ngx-fluent/src/lib/translation-source.interface.ts

This file was deleted.

10 changes: 10 additions & 0 deletions projects/ngx-fluent/src/lib/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FluentBundle } from '@fluent/bundle';

type FluentBundleCtorConfig = NonNullable<ConstructorParameters<typeof FluentBundle>[1]>;

export interface TranslationSourceConfig {
path: string;
bundleConfig?: FluentBundleCtorConfig;
}

export type TranslationSourceMap = Record<string, string | TranslationSourceConfig | FluentBundle>;
2 changes: 1 addition & 1 deletion projects/ngx-fluent/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
export * from './lib/ngx-fluent.service';
export * from './lib/ngx-fluent.pipe';
export * from './lib/ngx-fluent.module';
export * from './lib/translation-source.interface';
export * from './lib/types';

0 comments on commit e8ae072

Please sign in to comment.