gettext utils - fix issue where `ngettext` would not work

- ngettext was not correctly set up and would not do any pluralisation
- add full unit test suite for JS translation utils
- add full JSDOC definitions for JS translation utils
pull/8693/head
LB Johnston 2022-06-25 17:09:16 +10:00 zatwierdzone przez Karl Hobley
rodzic f797896cba
commit d6baee0754
2 zmienionych plików z 157 dodań i 8 usunięć

Wyświetl plik

@ -0,0 +1,76 @@
import {
getFormat,
gettext,
gettextNoop,
ngettext,
pluralIdx,
} from './gettext';
const STRING =
'The name wagtail stems from the constant sideways wagging of the tail.';
describe('gettext', () => {
beforeEach(() => {
window.django = { gettext: jest.fn((val) => val) };
});
it('should return the value based on the django util', () => {
expect(window.django.gettext).not.toHaveBeenCalled();
expect(gettext(STRING)).toEqual(STRING);
expect(window.django.gettext).toHaveBeenCalledWith(STRING);
});
});
describe('ngettext', () => {
beforeEach(() => {
window.django = { ngettext: jest.fn((val) => val) };
});
it('should return the value based on the django util', () => {
expect(window.django.ngettext).not.toHaveBeenCalled();
expect(ngettext('One bird', 'Many birds', 2)).toEqual('One bird');
expect(window.django.ngettext).toHaveBeenCalledWith(
'One bird',
'Many birds',
2,
);
});
});
describe('getFormat', () => {
beforeEach(() => {
window.django = { get_format: jest.fn(() => 1) };
});
it('should return the value based on the django util', () => {
expect(window.django.get_format).not.toHaveBeenCalled();
expect(getFormat('FIRST_DAY_OF_WEEK')).toEqual(1);
expect(window.django.get_format).toHaveBeenCalledWith('FIRST_DAY_OF_WEEK');
});
});
describe('gettextNoop', () => {
beforeEach(() => {
window.django = { gettext_noop: jest.fn((val) => val) };
});
it('should return the value based on the django util', () => {
expect(window.django.gettext_noop).not.toHaveBeenCalled();
expect(gettextNoop(STRING)).toEqual(STRING);
expect(window.django.gettext_noop).toHaveBeenCalledWith(STRING);
});
});
describe('pluralIdx', () => {
beforeEach(() => {
window.django = {
pluralidx: jest.fn((val) => ({ 0: true, 1: false }[val] || true)),
};
});
it('should return the value based on the django util', () => {
expect(window.django.pluralidx).not.toHaveBeenCalled();
expect(pluralIdx(0)).toEqual(true);
expect(window.django.pluralidx).toHaveBeenCalledWith(0);
});
});

Wyświetl plik

@ -1,4 +1,17 @@
// https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#gettext /**
* Translation / Internationalisation utilities based on Django's `JavaScriptCatalogView`
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#module-django.views.i18n
*/
/**
* The gettext function behaves similarly to the standard gettext interface within Django.
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#gettext
*
* @param {string} text
* @returns {string}
*/
export function gettext(text: string): string { export function gettext(text: string): string {
const djangoGettext = (window as any).django?.gettext; const djangoGettext = (window as any).django?.gettext;
@ -9,18 +22,38 @@ export function gettext(text: string): string {
return text; return text;
} }
// https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#ngettext /**
export function ngettext(text: string): string { * The ngettext function provides an interface to pluralize words and phrases.
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#ngettext
*
* @param {string} singular
* @param {string} plural
* @param {number} count
* @returns {string}
*
* @example
* const ngettext('one bird', 'two or more in the hand', 2);
* // 'two or more in the hand'
*
*/
export function ngettext(
singular: string,
plural: string,
count: number,
): string {
const djangoNgettext = (window as any).django?.ngettext; const djangoNgettext = (window as any).django?.ngettext;
if (djangoNgettext) { if (djangoNgettext) {
return djangoNgettext(text); return djangoNgettext(singular, plural, count);
} }
return text; return singular;
} }
// https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#get-format /**
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#get-format
*/
export type FormatType = export type FormatType =
| 'DATE_FORMAT' | 'DATE_FORMAT'
| 'DATE_INPUT_FORMATS' | 'DATE_INPUT_FORMATS'
@ -37,6 +70,20 @@ export type FormatType =
| 'TIME_INPUT_FORMATS' | 'TIME_INPUT_FORMATS'
| 'YEAR_MONTH_FORMAT'; | 'YEAR_MONTH_FORMAT';
/**
* The getFormat function has access to the configured i18n formatting settings and
* can retrieve the format string for a given setting name.
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#get-format
*
* @param {FormatType} formatType
* @returns {str}
*
* @example
* get_format('DATE_FORMAT');
* // 'N j, Y'
*
*/
export function getFormat(formatType: FormatType): string { export function getFormat(formatType: FormatType): string {
const djangoGetFormat = (window as any).django?.get_format; const djangoGetFormat = (window as any).django?.get_format;
@ -47,7 +94,16 @@ export function getFormat(formatType: FormatType): string {
return ''; return '';
} }
// https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#gettext_noop /**
* Marks strings for translation but doesnt translate them now.
* This can be used to store strings in global variables that should stay in the base
* language (because they might be used externally) and will be translated later.
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#gettext_noop
*
* @param {string} text
* @returns {string}
*/
export function gettextNoop(text: string): string { export function gettextNoop(text: string): string {
const djangoGettextNoop = (window as any).django?.gettext_noop; const djangoGettextNoop = (window as any).django?.gettext_noop;
@ -58,7 +114,24 @@ export function gettextNoop(text: string): string {
return text; return text;
} }
// https://docs.djangoproject.com/en/3.1/topics/i18n/translation/#pluralidx /**
* The pluralidx function works in a similar way to the pluralize template filter,
* determining if a given count should use a plural form of a word or not.
*
* https://docs.djangoproject.com/en/stable/topics/i18n/translation/#pluralidx
*
* @param {number} count
* @returns {boolean}
*
* @example
* pluralidx(0);
* // true
* pluralidx(1);
* // false
* pluralidx(2);
* // true
*
*/
export function pluralIdx(count: number): boolean { export function pluralIdx(count: number): boolean {
const djangoPluralIdx = (window as any).django?.pluralidx; const djangoPluralIdx = (window as any).django?.pluralidx;