mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
273 lines
10 KiB
TypeScript
273 lines
10 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.dev/license
|
|
*/
|
|
import {
|
|
absoluteFrom,
|
|
AbsoluteFsPath,
|
|
FileSystem,
|
|
getFileSystem,
|
|
} from '@angular/compiler-cli/src/ngtsc/file_system';
|
|
import {loadTestDirectory} from '@angular/compiler-cli/src/ngtsc/testing';
|
|
import path from 'path';
|
|
import url from 'url';
|
|
|
|
import {Diagnostics} from '../../../src/diagnostics';
|
|
import {translateFiles} from '../../../src/translate/index';
|
|
import {getOutputPathFn} from '../../../src/translate/output_path';
|
|
import {runInNativeFileSystem} from '../../helpers';
|
|
|
|
const currentDir = path.dirname(url.fileURLToPath(import.meta.url));
|
|
|
|
runInNativeFileSystem(() => {
|
|
describe('translateFiles()', () => {
|
|
let fs: FileSystem;
|
|
let testDir: AbsoluteFsPath;
|
|
let testFilesDir: AbsoluteFsPath;
|
|
let translationFilesDir: AbsoluteFsPath;
|
|
|
|
beforeEach(() => {
|
|
fs = getFileSystem();
|
|
testDir = absoluteFrom('/test');
|
|
|
|
testFilesDir = fs.resolve(testDir, 'test_files');
|
|
loadTestDirectory(fs, path.resolve(path.join(currentDir, 'test_files')), testFilesDir);
|
|
translationFilesDir = fs.resolve(testDir, 'test_files');
|
|
loadTestDirectory(fs, path.resolve(path.join(currentDir, 'locales')), translationFilesDir);
|
|
});
|
|
|
|
it('should copy non-code files to the destination folders', () => {
|
|
const diagnostics = new Diagnostics();
|
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
|
translateFiles({
|
|
sourceRootPath: testFilesDir,
|
|
sourceFilePaths: ['test-1.txt', 'test-2.txt'],
|
|
outputPathFn,
|
|
translationFilePaths: resolveAll(translationFilesDir, [
|
|
'messages.de.json',
|
|
'messages.es.xlf',
|
|
'messages.fr.xlf',
|
|
'messages.it.xtb',
|
|
]),
|
|
translationFileLocales: [],
|
|
diagnostics,
|
|
missingTranslation: 'error',
|
|
duplicateTranslation: 'error',
|
|
});
|
|
|
|
expect(diagnostics.messages.length).toEqual(0);
|
|
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
});
|
|
|
|
it('should translate and copy source-code files to the destination folders', () => {
|
|
const diagnostics = new Diagnostics();
|
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
|
translateFiles({
|
|
sourceRootPath: testFilesDir,
|
|
sourceFilePaths: ['test.js'],
|
|
outputPathFn,
|
|
translationFilePaths: resolveAll(translationFilesDir, [
|
|
'messages.de.json',
|
|
'messages.es.xlf',
|
|
'messages.fr.xlf',
|
|
'messages.it.xtb',
|
|
]),
|
|
translationFileLocales: [],
|
|
diagnostics,
|
|
missingTranslation: 'error',
|
|
duplicateTranslation: 'error',
|
|
});
|
|
|
|
expect(diagnostics.messages.length).toEqual(0);
|
|
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test.js'))).toEqual(
|
|
`var name="World";var message="Bonjour, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test.js'))).toEqual(
|
|
`var name="World";var message="Guten Tag, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test.js'))).toEqual(
|
|
`var name="World";var message="Hola, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test.js'))).toEqual(
|
|
`var name="World";var message="Ciao, "+name+"!";`,
|
|
);
|
|
});
|
|
|
|
it('should translate and copy source-code files overriding the locales', () => {
|
|
const diagnostics = new Diagnostics();
|
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
|
translateFiles({
|
|
sourceRootPath: testFilesDir,
|
|
sourceFilePaths: ['test.js'],
|
|
outputPathFn,
|
|
translationFilePaths: resolveAll(translationFilesDir, [
|
|
'messages.de.json',
|
|
'messages.es.xlf',
|
|
'messages.fr.xlf',
|
|
'messages.it.xtb',
|
|
]),
|
|
translationFileLocales: ['xde', undefined, 'fr'],
|
|
diagnostics,
|
|
missingTranslation: 'error',
|
|
duplicateTranslation: 'error',
|
|
});
|
|
|
|
expect(diagnostics.messages.length).toEqual(1);
|
|
expect(diagnostics.messages).toContain({
|
|
type: 'warning',
|
|
message: `The provided locale "xde" does not match the target locale "de" found in the translation file "${fs.resolve(
|
|
translationFilesDir,
|
|
'messages.de.json',
|
|
)}".`,
|
|
});
|
|
|
|
expect(fs.readFile(fs.resolve(testDir, 'xde', 'test.js'))).toEqual(
|
|
`var name="World";var message="Guten Tag, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test.js'))).toEqual(
|
|
`var name="World";var message="Hola, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test.js'))).toEqual(
|
|
`var name="World";var message="Bonjour, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test.js'))).toEqual(
|
|
`var name="World";var message="Ciao, "+name+"!";`,
|
|
);
|
|
});
|
|
|
|
it('should merge translation files, if more than one provided, and translate source-code', () => {
|
|
const diagnostics = new Diagnostics();
|
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
|
translateFiles({
|
|
sourceRootPath: testFilesDir,
|
|
sourceFilePaths: ['test-extra.js'],
|
|
outputPathFn,
|
|
translationFilePaths: resolveAllRecursive(translationFilesDir, [
|
|
['messages.de.json', 'messages-extra.de.json'],
|
|
'messages.es.xlf',
|
|
]),
|
|
translationFileLocales: [],
|
|
diagnostics,
|
|
missingTranslation: 'error',
|
|
duplicateTranslation: 'error',
|
|
});
|
|
|
|
expect(diagnostics.messages.length).toEqual(1);
|
|
// There is no "extra" translation in the `es` locale translation file.
|
|
expect(diagnostics.messages[0]).toEqual({
|
|
type: 'error',
|
|
message: 'No translation found for "customExtra" ("Goodbye, {$PH}!").',
|
|
});
|
|
|
|
// The `de` locale translates the `customExtra` message because it is in the
|
|
// `messages-extra.de.json` file that was merged.
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test-extra.js'))).toEqual(
|
|
`var name="World";var message="Guten Tag, "+name+"!";var message="Auf wiedersehen, "+name+"!";`,
|
|
);
|
|
// The `es` locale does not translate `customExtra` because there is no translation for it.
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test-extra.js'))).toEqual(
|
|
`var name="World";var message="Hola, "+name+"!";var message="Goodbye, "+name+"!";`,
|
|
);
|
|
});
|
|
|
|
it('should transform and/or copy files to the destination folders', () => {
|
|
const diagnostics = new Diagnostics();
|
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
|
translateFiles({
|
|
sourceRootPath: testFilesDir,
|
|
sourceFilePaths: ['test-1.txt', 'test-2.txt', 'test.js'],
|
|
outputPathFn,
|
|
translationFilePaths: resolveAll(translationFilesDir, [
|
|
'messages.de.json',
|
|
'messages.es.xlf',
|
|
'messages.fr.xlf',
|
|
'messages.it.xtb',
|
|
]),
|
|
translationFileLocales: [],
|
|
diagnostics,
|
|
missingTranslation: 'error',
|
|
duplicateTranslation: 'error',
|
|
});
|
|
|
|
expect(diagnostics.messages.length).toEqual(0);
|
|
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test-1.txt'))).toEqual(
|
|
'Contents of test-1.txt',
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test-2.txt'))).toEqual(
|
|
'Contents of test-2.txt',
|
|
);
|
|
|
|
expect(fs.readFile(fs.resolve(testDir, 'fr', 'test.js'))).toEqual(
|
|
`var name="World";var message="Bonjour, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'de', 'test.js'))).toEqual(
|
|
`var name="World";var message="Guten Tag, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'es', 'test.js'))).toEqual(
|
|
`var name="World";var message="Hola, "+name+"!";`,
|
|
);
|
|
expect(fs.readFile(fs.resolve(testDir, 'it', 'test.js'))).toEqual(
|
|
`var name="World";var message="Ciao, "+name+"!";`,
|
|
);
|
|
});
|
|
|
|
function resolveAll(rootPath: string, paths: string[]): string[] {
|
|
return paths.map((p) => fs.resolve(rootPath, p));
|
|
}
|
|
function resolveAllRecursive(
|
|
rootPath: string,
|
|
paths: (string | string[])[],
|
|
): (string | string[])[] {
|
|
return paths.map((p) =>
|
|
Array.isArray(p) ? p.map((p2) => fs.resolve(rootPath, p2)) : fs.resolve(rootPath, p),
|
|
);
|
|
}
|
|
});
|
|
});
|