diff --git a/packages/core/src/FormatFunction/FormatFunction.ts b/packages/core/src/FormatFunction/FormatFunction.ts new file mode 100644 index 0000000000..3cf5f78717 --- /dev/null +++ b/packages/core/src/FormatFunction/FormatFunction.ts @@ -0,0 +1,13 @@ +import { formatter } from './formatter'; +import { FinalFormatterMiddleware, TolgeePlugin } from '../types'; + +function createFormatFunction(): FinalFormatterMiddleware { + return { + format: ({ translation, params }) => formatter(translation, params), + }; +} + +export const FormatFunction = (): TolgeePlugin => (tolgee, tools) => { + tools.setFinalFormatter(createFormatFunction()); + return tolgee; +}; diff --git a/packages/core/src/FormatFunction/formatter.test.ts b/packages/core/src/FormatFunction/formatter.test.ts new file mode 100644 index 0000000000..c314580fb2 --- /dev/null +++ b/packages/core/src/FormatFunction/formatter.test.ts @@ -0,0 +1,101 @@ +import { TranslateParams } from '../types'; +import { formatter } from './formatter'; + + +describe('function formatter', () => { + // TODO! + + // test('test test', () => { + // expect(getText()).toEqual('test test'); + // }); + + // test('simple test', () => { + // matchIcu(); + // }); + + // test('this is {name}', () => { + // matchIcu({ name: 'Bob' }); + // }); + + // test('this is { name }', () => { + // matchIcu({ name: 'Bob' }); + // }); + + // test('{ user } has { num } apples.', () => { + // matchIcu({ user: 'John', num: 2 }); + // }); + + // test('passing params, but no params here', () => { + // matchIcu({ user: 'John', num: 2 }); + // }); + + // test('{ user } has { user } apples.', () => { + // matchIcu({ user: 'John', num: 2 }); + // }); + + // test("ICU: '{ parameter '} format", () => { + // matchIcu(); + // }); + + // test("this '{ escaped }' well", () => { + // matchIcu(); + // }); + + // test("this is '{ weird } but valid", () => { + // matchIcu(); + // }); + + // test("edge case '", () => { + // matchIcu(); + // }); + + // test("What's {subject}?", () => { + // matchIcu({ subject: 'that' }); + // }); + + // test('this is also } right', () => { + // matchIcu(); + // }); + + // test('this is just {} wrong', () => { + // expectToThrowWithIcu(ERROR_PARAM_EMPTY); + // }); + + // test('this also { } wrong', () => { + // expectToThrowWithIcu(ERROR_PARAM_EMPTY); + // }); + + // test('this plain { , } wrong', () => { + // expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR); + // }); + + // test('this is { unexpected', () => { + // expectToThrowWithIcu(ERROR_UNEXPECTED_END); + // }); + + // test('this is obviously bad { yo yo }', () => { + // expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR); + // }); + + // test('this is obviously bad { yo, }', () => { + // expectToThrowWithIcu(ERROR_UNEXPECTED_CHAR); + // }); + + // test('good for icu { yo, number } not for me', () => { + // unsupported(ERROR_UNEXPECTED_CHAR, { yo: 6 }); + // }); + + // describe('supported characters in params', () => { + // characterInParamSupported(Array.from('019_axAX')); + // }); + + // describe('invalid characters in params', () => { + // characterInParamFailWithIcu('[+-@#$~^&*{%)(§\'"`!?:.;<>[]\\=|☺'.split('')); + // }); + + // describe('unsupported characters which are supported in ICU', () => { + // characterInParamFail(Array.from('šřýíéúůĚŽÝÁÍÉůú¨ˇ')); + // characterInParamFail(['汉字', '字', 'हि', 'हिन्दी']); + // characterInParamFail(['😊']); + // }); +}); diff --git a/packages/core/src/FormatFunction/formatter.ts b/packages/core/src/FormatFunction/formatter.ts new file mode 100644 index 0000000000..560dfee21f --- /dev/null +++ b/packages/core/src/FormatFunction/formatter.ts @@ -0,0 +1,30 @@ +import { DefaultParamType, TranslateParams } from '../types'; + +export function formatter( + translation: string | ((p?: typeof params) => string), + params?: TranslateParams +) { + if (typeof (translation) === "function") { + switch (translation.length) { + case 0: + if (params) { + throw new Error(`Parameters were provided for translation ${translation.toString()}, but its function doesn't accept any arguments.`); + } + break; + + case 1: + if (!params) { + throw new Error(`Parameters were not provided for translation ${translation.toString()}, but its function needs arguments.`); + } + break; + + default: + throw new Error(`For translation ${translation.toString()}: a translation function should have exactly one parameter, with translation parameters passed as keys.\n For example, ({name}) => \`hello \${name}\``); + } + return translation(params); + } + if (params) { + throw new Error(`Params given to translation "${translation}" but it does not accept params. Use a function to accept params when using FormatFunction as Tolgee's formatter.`) + } + return translation; +}