refactor(localize): run the translate plugin tests in mock FileSystems (#38536)

This commit is a tidy up of the translate plugin unit tests, but also ensures
that the tests are run in the context of a mock FileSystem. This ensures
that the tests are resilient to future refactors of the plugins that will
require a FileSystem to be initialized.

PR Close #38536
This commit is contained in:
Pete Bacon Darwin 2020-08-19 14:38:44 +01:00 committed by Misko Hevery
parent bdba1a062d
commit 81053d3160
2 changed files with 457 additions and 500 deletions

View File

@ -5,188 +5,176 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize'; import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
import {ɵParsedTranslation} from '@angular/localize/private';
import {transformSync} from '@babel/core'; import {transformSync} from '@babel/core';
import {Diagnostics} from '../../../src/diagnostics'; import {Diagnostics} from '../../../src/diagnostics';
import {TranslatePluginOptions} from '../../../src/source_file_utils';
import {makeEs2015TranslatePlugin} from '../../../src/translate/source_files/es2015_translate_plugin'; import {makeEs2015TranslatePlugin} from '../../../src/translate/source_files/es2015_translate_plugin';
describe('makeEs2015Plugin', () => { runInEachFileSystem(() => {
describe('(no translations)', () => { describe('makeEs2015Plugin', () => {
it('should transform `$localize` tags with binary expression', () => { describe('(no translations)', () => {
const diagnostics = new Diagnostics(); it('should transform `$localize` tags with binary expression', () => {
const input = 'const b = 10;\n$localize`try\\n${40 + b}\\n me`;'; const input = 'const b = 10;\n$localize`try\\n${40 + b}\\n me`;';
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; const output = transformCode(input);
expect(output.code).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";'); expect(output).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";');
}); });
it('should strip meta blocks', () => { it('should strip meta blocks', () => {
const diagnostics = new Diagnostics(); const input = 'const b = 10;\n$localize `:description:try\\n${40 + b}\\n me`;';
const input = 'const b = 10;\n$localize `:description:try\\n${40 + b}\\n me`;'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";');
expect(output.code).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";'); });
});
it('should not strip escaped meta blocks', () => { it('should not strip escaped meta blocks', () => {
const diagnostics = new Diagnostics(); const input = 'const b = 10;\n$localize `\\:description:try\\n${40 + b}\\n me`;';
const input = 'const b = 10;\n$localize `\\:description:try\\n${40 + b}\\n me`;'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('const b = 10;\n":description:try\\n" + (40 + b) + "\\n me";');
expect(output.code).toEqual('const b = 10;\n":description:try\\n" + (40 + b) + "\\n me";'); });
});
it('should transform nested `$localize` tags', () => {
const input = '$localize`a${1}b${$localize`x${5}y${6}z`}c`;';
const output = transformCode(input);
expect(output).toEqual('"a" + 1 + "b" + ("x" + 5 + "y" + 6 + "z") + "c";');
});
it('should transform nested `$localize` tags', () => { it('should transform tags inside functions', () => {
const diagnostics = new Diagnostics(); const input = 'function foo() { $localize`a${1}b${2}c`; }';
const input = '$localize`a${1}b${$localize`x${5}y${6}z`}c`;'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('function foo() {\n "a" + 1 + "b" + 2 + "c";\n}');
expect(output.code).toEqual('"a" + 1 + "b" + ("x" + 5 + "y" + 6 + "z") + "c";'); });
});
it('should transform tags inside functions', () => { it('should ignore tags with the wrong name', () => {
const diagnostics = new Diagnostics(); const input = 'other`a${1}b${2}c`;';
const input = 'function foo() { $localize`a${1}b${2}c`; }'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('other`a${1}b${2}c`;');
expect(output.code).toEqual('function foo() {\n "a" + 1 + "b" + 2 + "c";\n}'); });
});
it('should ignore tags with the wrong name', () => { it('should transform tags with different tag name configured', () => {
const diagnostics = new Diagnostics(); const input = 'other`a${1}b${2}c`;';
const input = 'other`a${1}b${2}c`;'; const output = transformCode(input, {}, {localizeName: 'other'});
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"a" + 1 + "b" + 2 + "c";');
expect(output.code).toEqual('other`a${1}b${2}c`;'); });
});
it('should transform tags with different tag name configured', () => { it('should ignore tags if the identifier is not global', () => {
const diagnostics = new Diagnostics(); const input = 'function foo($localize) { $localize`a${1}b${2}c`; }';
const input = 'other`a${1}b${2}c`;'; const output = transformCode(input);
const output = transformSync( expect(output).toEqual('function foo($localize) {\n $localize`a${1}b${2}c`;\n}');
input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {}, {localizeName: 'other'})]})!; });
expect(output.code).toEqual('"a" + 1 + "b" + 2 + "c";');
});
it('should ignore tags if the identifier is not global', () => { it('should add missing translation to diagnostic errors if missingTranslation is set to "error"',
const diagnostics = new Diagnostics(); () => {
const input = 'function foo($localize) { $localize`a${1}b${2}c`; }'; const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;';
const output = transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, {})]})!; const diagnostics = new Diagnostics();
expect(output.code).toEqual('function foo($localize) {\n $localize`a${1}b${2}c`;\n}'); transformCode(input, {}, {missingTranslation: 'error'}, diagnostics);
}); expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
it('should add missing translation to diagnostic errors if missingTranslation is set to "error"', type: 'error',
() => { message: `No translation found for "${
const diagnostics = new Diagnostics(); ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;'; });
transformSync(input, {
plugins: [makeEs2015TranslatePlugin(diagnostics, {}, {missingTranslation: 'error'})]
})!;
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message: `No translation found for "${
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
}); });
});
it('should add missing translation to diagnostic errors if missingTranslation is set to "warning"', it('should add missing translation to diagnostic errors if missingTranslation is set to "warning"',
() => { () => {
const diagnostics = new Diagnostics(); const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;';
const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;'; const diagnostics = new Diagnostics();
transformSync(input, { transformCode(input, {}, {missingTranslation: 'warning'}, diagnostics);
plugins: [makeEs2015TranslatePlugin(diagnostics, {}, {missingTranslation: 'warning'})] expect(diagnostics.hasErrors).toBe(false);
})!; expect(diagnostics.messages[0]).toEqual({
expect(diagnostics.hasErrors).toBe(false); type: 'warning',
expect(diagnostics.messages[0]).toEqual({ message: `No translation found for "${
type: 'warning', ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
message: `No translation found for "${ });
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
}); });
});
it('should add missing translation to diagnostic errors if missingTranslation is set to "ignore"', it('should add missing translation to diagnostic errors if missingTranslation is set to "ignore"',
() => { () => {
const diagnostics = new Diagnostics(); const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;';
const input = 'const b = 10;\n$localize `try\\n${40 + b}\\n me`;'; const diagnostics = new Diagnostics();
transformSync(input, { transformCode(input, {}, {missingTranslation: 'ignore'}, diagnostics);
plugins: [makeEs2015TranslatePlugin(diagnostics, {}, {missingTranslation: 'ignore'})] expect(diagnostics.hasErrors).toBe(false);
})!; expect(diagnostics.messages).toEqual([]);
expect(diagnostics.hasErrors).toBe(false); });
expect(diagnostics.messages).toEqual([]);
});
});
describe('(with translations)', () => {
it('should translate message parts (identity translations)', () => {
const diagnostics = new Diagnostics();
const translations = {
[ɵcomputeMsgId('abc')]: ɵparseTranslation('abc'),
[ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('abc{$PH}'),
[ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('abc{$PH}def'),
[ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('abc{$PH}def{$PH_1}'),
[ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('Hello, {$PH}!'),
};
const input = '$localize `abc`;\n' +
'$localize `abc${1 + 2 + 3}`;\n' +
'$localize `abc${1 + 2 + 3}def`;\n' +
'$localize `abc${1 + 2 + 3}def${4 + 5 + 6}`;\n' +
'$localize `Hello, ${getName()}!`;';
const output =
transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, translations)]})!;
expect(output.code)
.toEqual(
'"abc";\n' +
'"abc" + (1 + 2 + 3) + "";\n' +
'"abc" + (1 + 2 + 3) + "def";\n' +
'"abc" + (1 + 2 + 3) + "def" + (4 + 5 + 6) + "";\n' +
'"Hello, " + getName() + "!";');
}); });
it('should translate message parts (uppercase translations)', () => { describe('(with translations)', () => {
const diagnostics = new Diagnostics(); it('should translate message parts (identity translations)', () => {
const translations = { const translations = {
[ɵcomputeMsgId('abc')]: ɵparseTranslation('ABC'), [ɵcomputeMsgId('abc')]: ɵparseTranslation('abc'),
[ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('ABC{$PH}'), [ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('abc{$PH}'),
[ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('ABC{$PH}DEF'), [ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('abc{$PH}def'),
[ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('ABC{$PH}DEF{$PH_1}'), [ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('abc{$PH}def{$PH_1}'),
[ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('HELLO, {$PH}!'), [ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('Hello, {$PH}!'),
}; };
const input = '$localize `abc`;\n' + const input = '$localize `abc`;\n' +
'$localize `abc${1 + 2 + 3}`;\n' + '$localize `abc${1 + 2 + 3}`;\n' +
'$localize `abc${1 + 2 + 3}def`;\n' + '$localize `abc${1 + 2 + 3}def`;\n' +
'$localize `abc${1 + 2 + 3}def${4 + 5 + 6}`;\n' + '$localize `abc${1 + 2 + 3}def${4 + 5 + 6}`;\n' +
'$localize `Hello, ${getName()}!`;'; '$localize `Hello, ${getName()}!`;';
const output = const output = transformCode(input, translations);
transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, translations)]})!; expect(output).toEqual(
expect(output.code) '"abc";\n' +
.toEqual( '"abc" + (1 + 2 + 3) + "";\n' +
'"ABC";\n' + '"abc" + (1 + 2 + 3) + "def";\n' +
'"ABC" + (1 + 2 + 3) + "";\n' + '"abc" + (1 + 2 + 3) + "def" + (4 + 5 + 6) + "";\n' +
'"ABC" + (1 + 2 + 3) + "DEF";\n' + '"Hello, " + getName() + "!";');
'"ABC" + (1 + 2 + 3) + "DEF" + (4 + 5 + 6) + "";\n' + });
'"HELLO, " + getName() + "!";');
});
it('should translate message parts (reversing placeholders)', () => { it('should translate message parts (uppercase translations)', () => {
const diagnostics = new Diagnostics(); const translations = {
const translations = { [ɵcomputeMsgId('abc')]: ɵparseTranslation('ABC'),
[ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]: [ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('ABC{$PH}'),
ɵparseTranslation('abc{$PH_2}def{$PH_1} - Hello, {$PH}!'), [ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('ABC{$PH}DEF'),
}; [ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('ABC{$PH}DEF{$PH_1}'),
const input = '$localize `abc${1 + 2 + 3}def${4 + 5 + 6} - Hello, ${getName()}!`;'; [ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('HELLO, {$PH}!'),
const output = };
transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, translations)]})!; const input = '$localize `abc`;\n' +
expect(output.code) '$localize `abc${1 + 2 + 3}`;\n' +
.toEqual('"abc" + getName() + "def" + (4 + 5 + 6) + " - Hello, " + (1 + 2 + 3) + "!";'); '$localize `abc${1 + 2 + 3}def`;\n' +
}); '$localize `abc${1 + 2 + 3}def${4 + 5 + 6}`;\n' +
'$localize `Hello, ${getName()}!`;';
const output = transformCode(input, translations);
expect(output).toEqual(
'"ABC";\n' +
'"ABC" + (1 + 2 + 3) + "";\n' +
'"ABC" + (1 + 2 + 3) + "DEF";\n' +
'"ABC" + (1 + 2 + 3) + "DEF" + (4 + 5 + 6) + "";\n' +
'"HELLO, " + getName() + "!";');
});
it('should translate message parts (removing placeholders)', () => { it('should translate message parts (reversing placeholders)', () => {
const diagnostics = new Diagnostics(); const translations = {
const translations = { [ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
[ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]: ɵparseTranslation('abc{$PH_2}def{$PH_1} - Hello, {$PH}!'),
ɵparseTranslation('abc{$PH} - Hello, {$PH_2}!'), };
}; const input = '$localize `abc${1 + 2 + 3}def${4 + 5 + 6} - Hello, ${getName()}!`;';
const input = '$localize `abc${1 + 2 + 3}def${4 + 5 + 6} - Hello, ${getName()}!`;'; const output = transformCode(input, translations);
const output = expect(output).toEqual(
transformSync(input, {plugins: [makeEs2015TranslatePlugin(diagnostics, translations)]})!; '"abc" + getName() + "def" + (4 + 5 + 6) + " - Hello, " + (1 + 2 + 3) + "!";');
expect(output.code).toEqual('"abc" + (1 + 2 + 3) + " - Hello, " + getName() + "!";'); });
it('should translate message parts (removing placeholders)', () => {
const translations = {
[ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
ɵparseTranslation('abc{$PH} - Hello, {$PH_2}!'),
};
const input = '$localize `abc${1 + 2 + 3}def${4 + 5 + 6} - Hello, ${getName()}!`;';
const output = transformCode(input, translations);
expect(output).toEqual('"abc" + (1 + 2 + 3) + " - Hello, " + getName() + "!";');
});
}); });
}); });
}); });
function transformCode(
input: string, translations: Record<string, ɵParsedTranslation> = {},
pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
return transformSync(input, {
plugins: [makeEs2015TranslatePlugin(diagnostics, translations, pluginOptions)],
filename: '/app/dist/test.js'
})!.code!;
}

View File

@ -5,107 +5,96 @@
* Use of this source code is governed by an MIT-style license that can be * Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize'; import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
import {ɵParsedTranslation} from '@angular/localize/private';
import {transformSync} from '@babel/core'; import {transformSync} from '@babel/core';
import {Diagnostics} from '../../../src/diagnostics'; import {Diagnostics} from '../../../src/diagnostics';
import {TranslatePluginOptions} from '../../../src/source_file_utils';
import {makeEs5TranslatePlugin} from '../../../src/translate/source_files/es5_translate_plugin'; import {makeEs5TranslatePlugin} from '../../../src/translate/source_files/es5_translate_plugin';
describe('makeEs5Plugin', () => { runInEachFileSystem(() => {
describe('(no translations)', () => { describe('makeEs5Plugin', () => {
it('should transform `$localize` calls with binary expression', () => { describe('(no translations)', () => {
const diagnostics = new Diagnostics(); it('should transform `$localize` calls with binary expression', () => {
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);'; const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; const output = transformCode(input);
expect(output.code).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";'); expect(output).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";');
}); });
it('should strip meta blocks', () => { it('should strip meta blocks', () => {
const diagnostics = new Diagnostics(); const input =
const input = 'const b = 10;\n$localize([":description:try\\n", ":placeholder:\\n me"], 40 + b);';
'const b = 10;\n$localize([":description:try\\n", ":placeholder:\\n me"], 40 + b);'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";');
expect(output.code).toEqual('const b = 10;\n"try\\n" + (40 + b) + "\\n me";'); });
});
it('should not strip escaped meta blocks', () => { it('should not strip escaped meta blocks', () => {
const diagnostics = new Diagnostics(); const input =
const input = `$localize(__makeTemplateObject([':desc:try', 'me'], ['\\\\\\:desc:try', 'me']), 40 + 2);`;
`$localize(__makeTemplateObject([':desc:try', 'me'], ['\\\\\\:desc:try', 'me']), 40 + 2);`; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('":desc:try" + (40 + 2) + "me";');
expect(output.code).toEqual('":desc:try" + (40 + 2) + "me";'); });
});
it('should transform nested `$localize` calls', () => { it('should transform nested `$localize` calls', () => {
const diagnostics = new Diagnostics(); const input = '$localize(["a", "b", "c"], 1, $localize(["x", "y", "z"], 5, 6));';
const input = '$localize(["a", "b", "c"], 1, $localize(["x", "y", "z"], 5, 6));'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"a" + 1 + "b" + ("x" + 5 + "y" + 6 + "z") + "c";');
expect(output.code).toEqual('"a" + 1 + "b" + ("x" + 5 + "y" + 6 + "z") + "c";'); });
});
it('should transform calls inside functions', () => { it('should transform calls inside functions', () => {
const diagnostics = new Diagnostics(); const input = 'function foo() { $localize(["a", "b", "c"], 1, 2); }';
const input = 'function foo() { $localize(["a", "b", "c"], 1, 2); }'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('function foo() {\n "a" + 1 + "b" + 2 + "c";\n}');
expect(output.code).toEqual('function foo() {\n "a" + 1 + "b" + 2 + "c";\n}'); });
});
it('should ignore tags with the wrong name', () => { it('should ignore tags with the wrong name', () => {
const diagnostics = new Diagnostics(); const input = 'other(["a", "b", "c"], 1, 2);';
const input = 'other(["a", "b", "c"], 1, 2);'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('other(["a", "b", "c"], 1, 2);');
expect(output.code).toEqual('other(["a", "b", "c"], 1, 2);'); });
});
it('should transform calls with different function name configured', () => { it('should transform calls with different function name configured', () => {
const diagnostics = new Diagnostics(); const input = 'other(["a", "b", "c"], 1, 2);';
const input = 'other(["a", "b", "c"], 1, 2);'; const output = transformCode(input, {}, {localizeName: 'other'});
const output = transformSync( expect(output).toEqual('"a" + 1 + "b" + 2 + "c";');
input, {plugins: [makeEs5TranslatePlugin(diagnostics, {}, {localizeName: 'other'})]})!; });
expect(output.code).toEqual('"a" + 1 + "b" + 2 + "c";');
});
it('should ignore tags if the identifier is not global', () => { it('should ignore tags if the identifier is not global', () => {
const diagnostics = new Diagnostics(); const input = 'function foo($localize) { $localize(["a", "b", "c"], 1, 2); }';
const input = 'function foo($localize) { $localize(["a", "b", "c"], 1, 2); }'; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('function foo($localize) {\n $localize(["a", "b", "c"], 1, 2);\n}');
expect(output.code) });
.toEqual('function foo($localize) {\n $localize(["a", "b", "c"], 1, 2);\n}');
});
it('should handle template object helper calls', () => { it('should handle template object helper calls', () => {
const diagnostics = new Diagnostics(); const input = `$localize(__makeTemplateObject(['try', 'me'], ['try', 'me']), 40 + 2);`;
const input = `$localize(__makeTemplateObject(['try', 'me'], ['try', 'me']), 40 + 2);`; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"try" + (40 + 2) + "me";');
expect(output.code).toEqual('"try" + (40 + 2) + "me";'); });
});
it('should handle template object aliased helper calls', () => { it('should handle template object aliased helper calls', () => {
const diagnostics = new Diagnostics(); const input = `$localize(m(['try', 'me'], ['try', 'me']), 40 + 2);`;
const input = `$localize(m(['try', 'me'], ['try', 'me']), 40 + 2);`; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"try" + (40 + 2) + "me";');
expect(output.code).toEqual('"try" + (40 + 2) + "me";'); });
});
it('should handle template object inline helper calls', () => { it('should handle template object inline helper calls', () => {
const diagnostics = new Diagnostics(); const input =
const input = `$localize((this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e})(['try', 'me'], ['try', 'me']), 40 + 2);`;
`$localize((this&&this.__makeTemplateObject||function(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e})(['try', 'me'], ['try', 'me']), 40 + 2);`; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"try" + (40 + 2) + "me";');
expect(output.code).toEqual('"try" + (40 + 2) + "me";'); });
});
it('should handle cached helper calls', () => { it('should handle cached helper calls', () => {
const diagnostics = new Diagnostics(); const input =
const input = `$localize(cachedObj||(cachedObj=__makeTemplateObject(['try', 'me'],['try', 'me'])),40 + 2)`;
`$localize(cachedObj||(cachedObj=__makeTemplateObject(['try', 'me'],['try', 'me'])),40 + 2)`; const output = transformCode(input);
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; expect(output).toEqual('"try" + (40 + 2) + "me";');
expect(output.code).toEqual('"try" + (40 + 2) + "me";'); });
});
it('should handle minified code', () => { it('should handle minified code', () => {
const diagnostics = new Diagnostics(); const input = `$localize(
const input = `$localize(
cachedObj|| cachedObj||
( (
cookedParts=['try', 'me'], cookedParts=['try', 'me'],
@ -115,13 +104,12 @@ describe('makeEs5Plugin', () => {
cookedParts.raw=rawParts, cookedParts.raw=rawParts,
cachedObj=cookedParts cachedObj=cookedParts
),40 + 2)`; ),40 + 2)`;
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; const output = transformCode(input);
expect(output.code).toEqual('"try" + (40 + 2) + "me";'); expect(output).toEqual('"try" + (40 + 2) + "me";');
}); });
it('should handle lazy-load helper calls', () => { it('should handle lazy-load helper calls', () => {
const diagnostics = new Diagnostics(); const input = `
const input = `
function _templateObject2() { function _templateObject2() {
var e = _taggedTemplateLiteral([':escaped-colons:Welcome to the i18n app.'], ['\\\\\\:escaped-colons:Welcome to the i18n app.']); var e = _taggedTemplateLiteral([':escaped-colons:Welcome to the i18n app.'], ['\\\\\\:escaped-colons:Welcome to the i18n app.']);
return _templateObject2 = function() { return e }, e return _templateObject2 = function() { return e }, e
@ -139,262 +127,243 @@ describe('makeEs5Plugin', () => {
console.log($localize(_templateObject(), '\ufffd0\ufffd')); console.log($localize(_templateObject(), '\ufffd0\ufffd'));
} }
`; `;
const output = transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, {})]})!; const output = transformCode(input);
expect(output.code).toContain('const message = ":escaped-colons:Welcome to the i18n app."'); expect(output).toContain('const message = ":escaped-colons:Welcome to the i18n app."');
expect(output.code).toContain('console.log(" Hello " + \'\ufffd0\ufffd\' + "! ");'); expect(output).toContain('console.log(" Hello " + \'\ufffd0\ufffd\' + "! ");');
expect(output.code).not.toContain('templateObject'); expect(output).not.toContain('templateObject');
expect(output.code).not.toContain('templateObject2'); expect(output).not.toContain('templateObject2');
});
it('should add diagnostic error with code-frame information if the arguments to `$localize` are missing',
() => {
const input = '$localize()';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message: '/app/dist/test.js: `$localize` called without any arguments.\n' +
'> 1 | $localize()\n' +
' | ^^^^^^^^^^^',
});
});
it('should add diagnostic error with code-frame information if the arguments to `$localize` are invalid',
() => {
const input = '$localize(...x)';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected argument to `$localize` (expected an array).\n' +
'> 1 | $localize(...x)\n' +
' | ^^^^',
});
});
it('should add diagnostic error with code-frame information if the first argument to `$localize` is not an array',
() => {
const input = '$localize(null, [])';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(null, [])\n' +
' | ^^^^',
});
});
it('should add diagnostic error with code-frame information if raw message parts are not an expression',
() => {
const input = '$localize(__makeTemplateObject([], ...[]))';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected `raw` argument to the "makeTemplateObject()" function (expected an expression).\n' +
'> 1 | $localize(__makeTemplateObject([], ...[]))\n' +
' | ^^^^^',
});
});
it('should add diagnostic error with code-frame information if cooked message parts are not an expression',
() => {
const input = '$localize(__makeTemplateObject(...[], []))';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected `cooked` argument to the "makeTemplateObject()" function (expected an expression).\n' +
'> 1 | $localize(__makeTemplateObject(...[], []))\n' +
' | ^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all cooked message parts are strings',
() => {
const input = '$localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))\n' +
' | ^^^^^^^^^^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all raw message parts are strings',
() => {
const input = '$localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))\n' +
' | ^^^^^^^^^^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all substitutions are expressions',
() => {
const input = '$localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])';
const diagnostics = new Diagnostics();
transformCode(input, {}, {}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Invalid substitutions for `$localize` (expected all substitution arguments to be expressions).\n' +
'> 1 | $localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])\n' +
' | ^^^^^',
});
});
it('should add missing translation to diagnostic errors if missingTranslation is set to "error"',
() => {
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
const diagnostics = new Diagnostics();
transformCode(input, {}, {missingTranslation: 'error'}, diagnostics);
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message: `No translation found for "${
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
});
});
it('should add missing translation to diagnostic warnings if missingTranslation is set to "warning"',
() => {
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
const diagnostics = new Diagnostics();
transformCode(input, {}, {missingTranslation: 'warning'}, diagnostics);
expect(diagnostics.hasErrors).toBe(false);
expect(diagnostics.messages[0]).toEqual({
type: 'warning',
message: `No translation found for "${
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
});
});
it('should ignore missing translations if missingTranslation is set to "ignore"', () => {
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
const diagnostics = new Diagnostics();
transformCode(input, {}, {missingTranslation: 'ignore'}, diagnostics);
expect(diagnostics.hasErrors).toBe(false);
expect(diagnostics.messages).toEqual([]);
});
});
});
describe('(with translations)', () => {
it('should translate message parts (identity translations)', () => {
const translations = {
[ɵcomputeMsgId('abc')]: ɵparseTranslation('abc'),
[ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('abc{$PH}'),
[ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('abc{$PH}def'),
[ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('abc{$PH}def{$PH_1}'),
[ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('Hello, {$PH}!'),
};
const input = '$localize(["abc"]);\n' +
'$localize(["abc", ""], 1 + 2 + 3);\n' +
'$localize(["abc", "def"], 1 + 2 + 3);\n' +
'$localize(["abc", "def", ""], 1 + 2 + 3, 4 + 5 + 6);\n' +
'$localize(["Hello, ", "!"], getName());';
const output = transformCode(input, translations);
expect(output).toEqual(
'"abc";\n' +
'"abc" + (1 + 2 + 3) + "";\n' +
'"abc" + (1 + 2 + 3) + "def";\n' +
'"abc" + (1 + 2 + 3) + "def" + (4 + 5 + 6) + "";\n' +
'"Hello, " + getName() + "!";');
}); });
it('should add diagnostic error with code-frame information if the arguments to `$localize` are missing', it('should translate message parts (uppercase translations)', () => {
() => { const translations = {
const diagnostics = new Diagnostics(); [ɵcomputeMsgId('abc')]: ɵparseTranslation('ABC'),
const input = '$localize()'; [ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('ABC{$PH}'),
transformSync( [ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('ABC{$PH}DEF'),
input, [ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('ABC{$PH}DEF{$PH_1}'),
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'}); [ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('HELLO, {$PH}!'),
expect(diagnostics.hasErrors).toBe(true); };
expect(diagnostics.messages[0]).toEqual({ const input = '$localize(["abc"]);\n' +
type: 'error', '$localize(["abc", ""], 1 + 2 + 3);\n' +
message: '/app/dist/test.js: `$localize` called without any arguments.\n' + '$localize(["abc", "def"], 1 + 2 + 3);\n' +
'> 1 | $localize()\n' + '$localize(["abc", "def", ""], 1 + 2 + 3, 4 + 5 + 6);\n' +
' | ^^^^^^^^^^^', '$localize(["Hello, ", "!"], getName());';
}); const output = transformCode(input, translations);
}); expect(output).toEqual(
'"ABC";\n' +
'"ABC" + (1 + 2 + 3) + "";\n' +
'"ABC" + (1 + 2 + 3) + "DEF";\n' +
'"ABC" + (1 + 2 + 3) + "DEF" + (4 + 5 + 6) + "";\n' +
'"HELLO, " + getName() + "!";');
});
it('should add diagnostic error with code-frame information if the arguments to `$localize` are invalid', it('should translate message parts (reversing placeholders)', () => {
() => { const translations = {
const diagnostics = new Diagnostics(); [ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
const input = '$localize(...x)'; ɵparseTranslation('abc{$PH_2}def{$PH_1} - Hello, {$PH}!'),
transformSync( };
input, const input =
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'}); '$localize(["abc", "def", " - Hello, ", "!"], 1 + 2 + 3, 4 + 5 + 6, getName());';
expect(diagnostics.hasErrors).toBe(true); const output = transformCode(input, translations);
expect(diagnostics.messages[0]).toEqual({ expect(output).toEqual(
type: 'error', '"abc" + getName() + "def" + (4 + 5 + 6) + " - Hello, " + (1 + 2 + 3) + "!";');
message: '/app/dist/test.js: Unexpected argument to `$localize` (expected an array).\n' + });
'> 1 | $localize(...x)\n' +
' | ^^^^',
});
});
it('should add diagnostic error with code-frame information if the first argument to `$localize` is not an array', it('should translate message parts (removing placeholders)', () => {
() => { const translations = {
const diagnostics = new Diagnostics(); [ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
const input = '$localize(null, [])'; ɵparseTranslation('abc{$PH} - Hello, {$PH_2}!'),
transformSync( };
input, const input =
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'}); '$localize(["abc", "def", " - Hello, ", "!"], 1 + 2 + 3, 4 + 5 + 6, getName());';
expect(diagnostics.hasErrors).toBe(true); const output = transformCode(input, translations);
expect(diagnostics.messages[0]).toEqual({ expect(output).toEqual('"abc" + (1 + 2 + 3) + " - Hello, " + getName() + "!";');
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(null, [])\n' +
' | ^^^^',
});
});
it('should add diagnostic error with code-frame information if raw message parts are not an expression',
() => {
const diagnostics = new Diagnostics();
const input = '$localize(__makeTemplateObject([], ...[]))';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected `raw` argument to the "makeTemplateObject()" function (expected an expression).\n' +
'> 1 | $localize(__makeTemplateObject([], ...[]))\n' +
' | ^^^^^',
});
});
it('should add diagnostic error with code-frame information if cooked message parts are not an expression',
() => {
const diagnostics = new Diagnostics();
const input = '$localize(__makeTemplateObject(...[], []))';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected `cooked` argument to the "makeTemplateObject()" function (expected an expression).\n' +
'> 1 | $localize(__makeTemplateObject(...[], []))\n' +
' | ^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all cooked message parts are strings',
() => {
const diagnostics = new Diagnostics();
const input = '$localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))\n' +
' | ^^^^^^^^^^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all raw message parts are strings',
() => {
const diagnostics = new Diagnostics();
const input = '$localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
'> 1 | $localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))\n' +
' | ^^^^^^^^^^^^^^',
});
});
it('should add diagnostic error with code-frame information if not all substitutions are expressions',
() => {
const diagnostics = new Diagnostics();
const input = '$localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {})], filename: '/app/dist/test.js'});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message:
'/app/dist/test.js: Invalid substitutions for `$localize` (expected all substitution arguments to be expressions).\n' +
'> 1 | $localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])\n' +
' | ^^^^^',
});
});
it('should add missing translation to diagnostic errors if missingTranslation is set to "error"',
() => {
const diagnostics = new Diagnostics();
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {}, {missingTranslation: 'error'})]});
expect(diagnostics.hasErrors).toBe(true);
expect(diagnostics.messages[0]).toEqual({
type: 'error',
message: `No translation found for "${
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
});
});
it('should add missing translation to diagnostic warnings if missingTranslation is set to "warning"',
() => {
const diagnostics = new Diagnostics();
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {}, {missingTranslation: 'warning'})]});
expect(diagnostics.hasErrors).toBe(false);
expect(diagnostics.messages[0]).toEqual({
type: 'warning',
message: `No translation found for "${
ɵcomputeMsgId('try\n{$PH}\n me')}" ("try\n{$PH}\n me").`
});
});
it('should ignore missing translations if missingTranslation is set to "ignore"', () => {
const diagnostics = new Diagnostics();
const input = 'const b = 10;\n$localize(["try\\n", "\\n me"], 40 + b);';
transformSync(
input,
{plugins: [makeEs5TranslatePlugin(diagnostics, {}, {missingTranslation: 'ignore'})]});
expect(diagnostics.hasErrors).toBe(false);
expect(diagnostics.messages).toEqual([]);
}); });
}); });
}); });
describe('(with translations)', () => { function transformCode(
it('should translate message parts (identity translations)', () => { input: string, translations: Record<string, ɵParsedTranslation> = {},
const diagnostics = new Diagnostics(); pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
const translations = { return transformSync(input, {
[ɵcomputeMsgId('abc')]: ɵparseTranslation('abc'), plugins: [makeEs5TranslatePlugin(diagnostics, translations, pluginOptions)],
[ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('abc{$PH}'), filename: '/app/dist/test.js'
[ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('abc{$PH}def'), })!.code!;
[ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('abc{$PH}def{$PH_1}'), }
[ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('Hello, {$PH}!'),
};
const input = '$localize(["abc"]);\n' +
'$localize(["abc", ""], 1 + 2 + 3);\n' +
'$localize(["abc", "def"], 1 + 2 + 3);\n' +
'$localize(["abc", "def", ""], 1 + 2 + 3, 4 + 5 + 6);\n' +
'$localize(["Hello, ", "!"], getName());';
const output =
transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, translations)]})!;
expect(output.code)
.toEqual(
'"abc";\n' +
'"abc" + (1 + 2 + 3) + "";\n' +
'"abc" + (1 + 2 + 3) + "def";\n' +
'"abc" + (1 + 2 + 3) + "def" + (4 + 5 + 6) + "";\n' +
'"Hello, " + getName() + "!";');
});
it('should translate message parts (uppercase translations)', () => {
const diagnostics = new Diagnostics();
const translations = {
[ɵcomputeMsgId('abc')]: ɵparseTranslation('ABC'),
[ɵcomputeMsgId('abc{$PH}')]: ɵparseTranslation('ABC{$PH}'),
[ɵcomputeMsgId('abc{$PH}def')]: ɵparseTranslation('ABC{$PH}DEF'),
[ɵcomputeMsgId('abc{$PH}def{$PH_1}')]: ɵparseTranslation('ABC{$PH}DEF{$PH_1}'),
[ɵcomputeMsgId('Hello, {$PH}!')]: ɵparseTranslation('HELLO, {$PH}!'),
};
const input = '$localize(["abc"]);\n' +
'$localize(["abc", ""], 1 + 2 + 3);\n' +
'$localize(["abc", "def"], 1 + 2 + 3);\n' +
'$localize(["abc", "def", ""], 1 + 2 + 3, 4 + 5 + 6);\n' +
'$localize(["Hello, ", "!"], getName());';
const output =
transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, translations)]})!;
expect(output.code)
.toEqual(
'"ABC";\n' +
'"ABC" + (1 + 2 + 3) + "";\n' +
'"ABC" + (1 + 2 + 3) + "DEF";\n' +
'"ABC" + (1 + 2 + 3) + "DEF" + (4 + 5 + 6) + "";\n' +
'"HELLO, " + getName() + "!";');
});
it('should translate message parts (reversing placeholders)', () => {
const diagnostics = new Diagnostics();
const translations = {
[ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
ɵparseTranslation('abc{$PH_2}def{$PH_1} - Hello, {$PH}!'),
};
const input = '$localize(["abc", "def", " - Hello, ", "!"], 1 + 2 + 3, 4 + 5 + 6, getName());';
const output =
transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, translations)]})!;
expect(output.code)
.toEqual('"abc" + getName() + "def" + (4 + 5 + 6) + " - Hello, " + (1 + 2 + 3) + "!";');
});
it('should translate message parts (removing placeholders)', () => {
const diagnostics = new Diagnostics();
const translations = {
[ɵcomputeMsgId('abc{$PH}def{$PH_1} - Hello, {$PH_2}!')]:
ɵparseTranslation('abc{$PH} - Hello, {$PH_2}!'),
};
const input = '$localize(["abc", "def", " - Hello, ", "!"], 1 + 2 + 3, 4 + 5 + 6, getName());';
const output =
transformSync(input, {plugins: [makeEs5TranslatePlugin(diagnostics, translations)]})!;
expect(output.code).toEqual('"abc" + (1 + 2 + 3) + " - Hello, " + getName() + "!";');
});
});