angular/packages/localize/tools/test/translate/integration/main_spec.ts
Joey Perrott 9dbe6fc18b refactor: update license text to point to angular.dev (#57901)
Update license text to point to angular.dev instead of angular.io

PR Close #57901
2024-09-24 15:33:00 +02:00

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),
);
}
});
});