test(localize): ensure tests pass on Windows (#40952)
These tests were relying upon unix-like paths, which caused them to fail on Windows. Note that the `filegroup` Bazel rule tends not to work well on Windows, so this has been replaced with `copy_to_bin` instead. PR Close #40952
This commit is contained in:
parent
5ae28a4aa4
commit
51a79772b2
|
@ -35,7 +35,7 @@ export function makeEs5ExtractPlugin(
|
||||||
// If we get a BabelParseError here then something went wrong with Babel itself
|
// If we get a BabelParseError here then something went wrong with Babel itself
|
||||||
// since there must be something wrong with the structure of the AST generated
|
// since there must be something wrong with the structure of the AST generated
|
||||||
// by Babel parsing a TaggedTemplateExpression.
|
// by Babel parsing a TaggedTemplateExpression.
|
||||||
throw buildCodeFrameError(callPath, e);
|
throw buildCodeFrameError(fs, callPath, e);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 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 {AbsoluteFsPath, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, AbsoluteFsPath, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {ɵisMissingTranslationError, ɵmakeTemplateObject, ɵParsedTranslation, ɵSourceLocation, ɵtranslate} from '@angular/localize';
|
import {ɵisMissingTranslationError, ɵmakeTemplateObject, ɵParsedTranslation, ɵSourceLocation, ɵtranslate} from '@angular/localize';
|
||||||
import {NodePath} from '@babel/traverse';
|
import {NodePath} from '@babel/traverse';
|
||||||
import * as t from '@babel/types';
|
import * as t from '@babel/types';
|
||||||
|
@ -400,8 +400,19 @@ export function isBabelParseError(e: any): e is BabelParseError {
|
||||||
return e.type === 'BabelParseError';
|
return e.type === 'BabelParseError';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildCodeFrameError(path: NodePath, e: BabelParseError): string {
|
export function buildCodeFrameError(
|
||||||
const filename = path.hub.file.opts.filename || '(unknown file)';
|
fs: PathManipulation, path: NodePath, e: BabelParseError): string {
|
||||||
|
let filename = path.hub.file.opts.filename;
|
||||||
|
if (filename) {
|
||||||
|
filename = fs.resolve(filename);
|
||||||
|
let cwd = path.hub.file.opts.cwd;
|
||||||
|
if (cwd) {
|
||||||
|
cwd = fs.resolve(cwd);
|
||||||
|
filename = fs.relative(cwd, filename);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filename = '(unknown file)';
|
||||||
|
}
|
||||||
const message = path.hub.file.buildCodeFrameError(e.node, e.message).message;
|
const message = path.hub.file.buildCodeFrameError(e.node, e.message).message;
|
||||||
return `${filename}: ${message}`;
|
return `${filename}: ${message}`;
|
||||||
}
|
}
|
||||||
|
@ -434,9 +445,14 @@ export function serializeLocationPosition(location: ɵSourceLocation): string {
|
||||||
|
|
||||||
function getFileFromPath(fs: PathManipulation, path: NodePath|undefined): AbsoluteFsPath|null {
|
function getFileFromPath(fs: PathManipulation, path: NodePath|undefined): AbsoluteFsPath|null {
|
||||||
const opts = path?.hub.file.opts;
|
const opts = path?.hub.file.opts;
|
||||||
return opts?.filename ?
|
const filename = opts?.filename;
|
||||||
fs.resolve(opts.generatorOpts.sourceRoot ?? opts.cwd, fs.relative(opts.cwd, opts.filename)) :
|
if (!filename) {
|
||||||
null;
|
return null;
|
||||||
|
}
|
||||||
|
const relativePath = fs.relative(opts.cwd, filename);
|
||||||
|
const root = opts.generatorOpts.sourceRoot ?? opts.cwd;
|
||||||
|
const absPath = fs.resolve(root, relativePath);
|
||||||
|
return absPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLineAndColumn(loc: {line: number, column: number}): {line: number, column: number} {
|
function getLineAndColumn(loc: {line: number, column: number}): {line: number, column: number} {
|
||||||
|
|
|
@ -105,7 +105,7 @@ if (require.main === module) {
|
||||||
const sourceRootPath = options.r;
|
const sourceRootPath = options.r;
|
||||||
const sourceFilePaths = glob.sync(options.s, {cwd: sourceRootPath, nodir: true});
|
const sourceFilePaths = glob.sync(options.s, {cwd: sourceRootPath, nodir: true});
|
||||||
const translationFilePaths: (string|string[])[] = convertArraysFromArgs(options.t);
|
const translationFilePaths: (string|string[])[] = convertArraysFromArgs(options.t);
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(options.o));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(options.o));
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const missingTranslation = options.m as DiagnosticHandlingStrategy;
|
const missingTranslation = options.m as DiagnosticHandlingStrategy;
|
||||||
const duplicateTranslation = options.d as DiagnosticHandlingStrategy;
|
const duplicateTranslation = options.d as DiagnosticHandlingStrategy;
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
* 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 {AbsoluteFsPath} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {AbsoluteFsPath, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {join} from 'path';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that will return an absolute path to where a file is to be written, given a locale and
|
* A function that will return an absolute path to where a file is to be written, given a locale and
|
||||||
|
@ -23,8 +22,8 @@ export interface OutputPathFn {
|
||||||
* The special `{{LOCALE}}` marker will be replaced with the locale code of the current translation.
|
* The special `{{LOCALE}}` marker will be replaced with the locale code of the current translation.
|
||||||
* @param outputFolder An absolute path to the folder containing this set of translations.
|
* @param outputFolder An absolute path to the folder containing this set of translations.
|
||||||
*/
|
*/
|
||||||
export function getOutputPathFn(outputFolder: AbsoluteFsPath): OutputPathFn {
|
export function getOutputPathFn(fs: PathManipulation, outputFolder: AbsoluteFsPath): OutputPathFn {
|
||||||
const [pre, post] = outputFolder.split('{{LOCALE}}');
|
const [pre, post] = outputFolder.split('{{LOCALE}}');
|
||||||
return post === undefined ? (_locale, relativePath) => join(pre, relativePath) :
|
return post === undefined ? (_locale, relativePath) => fs.join(pre, relativePath) :
|
||||||
(locale, relativePath) => join(pre + locale + post, relativePath);
|
(locale, relativePath) => fs.join(pre + locale + post, relativePath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ export function makeEs2015TranslatePlugin(
|
||||||
// If we get a BabelParseError here then something went wrong with Babel itself
|
// If we get a BabelParseError here then something went wrong with Babel itself
|
||||||
// since there must be something wrong with the structure of the AST generated
|
// since there must be something wrong with the structure of the AST generated
|
||||||
// by Babel parsing a TaggedTemplateExpression.
|
// by Babel parsing a TaggedTemplateExpression.
|
||||||
throw buildCodeFrameError(path, e);
|
throw buildCodeFrameError(fs, path, e);
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ export function makeEs5TranslatePlugin(
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (isBabelParseError(e)) {
|
if (isBabelParseError(e)) {
|
||||||
diagnostics.error(buildCodeFrameError(callPath, e));
|
diagnostics.error(buildCodeFrameError(fs, callPath, e));
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ export class SourceFileTranslationHandler implements TranslationHandler {
|
||||||
makeEs2015TranslatePlugin(diagnostics, translationBundle.translations, options, this.fs),
|
makeEs2015TranslatePlugin(diagnostics, translationBundle.translations, options, this.fs),
|
||||||
makeEs5TranslatePlugin(diagnostics, translationBundle.translations, options, this.fs),
|
makeEs5TranslatePlugin(diagnostics, translationBundle.translations, options, this.fs),
|
||||||
],
|
],
|
||||||
|
cwd: sourceRoot,
|
||||||
filename,
|
filename,
|
||||||
});
|
});
|
||||||
if (translated && translated.code) {
|
if (translated && translated.code) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/logging/testing",
|
"//packages/compiler-cli/src/ngtsc/logging/testing",
|
||||||
"//packages/localize",
|
"//packages/localize",
|
||||||
"//packages/localize/src/tools",
|
"//packages/localize/src/tools",
|
||||||
|
"//packages/localize/src/tools/test/helpers",
|
||||||
"//packages/localize/src/utils",
|
"//packages/localize/src/utils",
|
||||||
"@npm//@babel/core",
|
"@npm//@babel/core",
|
||||||
"@npm//@babel/generator",
|
"@npm//@babel/generator",
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
* 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 {absoluteFrom, getFileSystem, relativeFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
||||||
import {MockLogger} from '@angular/compiler-cli/src/ngtsc/logging/testing';
|
import {MockLogger} from '@angular/compiler-cli/src/ngtsc/logging/testing';
|
||||||
|
|
||||||
import {MessageExtractor} from '../../src/extract/extraction';
|
import {MessageExtractor} from '../../src/extract/extraction';
|
||||||
|
import {runInNativeFileSystem} from '../helpers';
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
runInNativeFileSystem(() => {
|
||||||
describe('extractMessages', () => {
|
describe('extractMessages', () => {
|
||||||
it('should extract a message for each $localize template tag', () => {
|
it('should extract a message for each $localize template tag', () => {
|
||||||
const fs = getFileSystem();
|
const fs = getFileSystem();
|
||||||
|
@ -20,7 +20,7 @@ runInEachFileSystem(() => {
|
||||||
const filename = 'relative/path.js';
|
const filename = 'relative/path.js';
|
||||||
const file = fs.resolve(basePath, filename);
|
const file = fs.resolve(basePath, filename);
|
||||||
const extractor = new MessageExtractor(fs, logger, {basePath});
|
const extractor = new MessageExtractor(fs, logger, {basePath});
|
||||||
fs.ensureDir(absoluteFrom('/root/path/relative'));
|
fs.ensureDir(fs.dirname(file));
|
||||||
fs.writeFile(file, [
|
fs.writeFile(file, [
|
||||||
'$localize`:meaning|description:a${1}b${2}c`;',
|
'$localize`:meaning|description:a${1}b${2}c`;',
|
||||||
'$localize(__makeTemplateObject(["a", ":custom-placeholder:b", "c"], ["a", ":custom-placeholder:b", "c"]), 1, 2);',
|
'$localize(__makeTemplateObject(["a", ":custom-placeholder:b", "c"], ["a", ":custom-placeholder:b", "c"]), 1, 2);',
|
||||||
|
@ -40,19 +40,19 @@ runInEachFileSystem(() => {
|
||||||
{
|
{
|
||||||
start: {line: 0, column: 10},
|
start: {line: 0, column: 10},
|
||||||
end: {line: 0, column: 32},
|
end: {line: 0, column: 32},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: ':meaning|description:a',
|
text: ':meaning|description:a',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: {line: 0, column: 36},
|
start: {line: 0, column: 36},
|
||||||
end: {line: 0, column: 37},
|
end: {line: 0, column: 37},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: 'b',
|
text: 'b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: {line: 0, column: 41},
|
start: {line: 0, column: 41},
|
||||||
end: {line: 0, column: 42},
|
end: {line: 0, column: 42},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: 'c',
|
text: 'c',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -60,18 +60,8 @@ runInEachFileSystem(() => {
|
||||||
placeholderNames: ['PH', 'PH_1'],
|
placeholderNames: ['PH', 'PH_1'],
|
||||||
substitutions: jasmine.any(Object),
|
substitutions: jasmine.any(Object),
|
||||||
substitutionLocations: {
|
substitutionLocations: {
|
||||||
PH: {
|
PH: {start: {line: 0, column: 34}, end: {line: 0, column: 35}, file, text: '1'},
|
||||||
start: {line: 0, column: 34},
|
PH_1: {start: {line: 0, column: 39}, end: {line: 0, column: 40}, file, text: '2'}
|
||||||
end: {line: 0, column: 35},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '1'
|
|
||||||
},
|
|
||||||
PH_1: {
|
|
||||||
start: {line: 0, column: 39},
|
|
||||||
end: {line: 0, column: 40},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '2'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
legacyIds: [],
|
legacyIds: [],
|
||||||
location: {
|
location: {
|
||||||
|
@ -92,19 +82,19 @@ runInEachFileSystem(() => {
|
||||||
{
|
{
|
||||||
start: {line: 1, column: 69},
|
start: {line: 1, column: 69},
|
||||||
end: {line: 1, column: 72},
|
end: {line: 1, column: 72},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: '"a"',
|
text: '"a"',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: {line: 1, column: 74},
|
start: {line: 1, column: 74},
|
||||||
end: {line: 1, column: 97},
|
end: {line: 1, column: 97},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: '":custom-placeholder:b"',
|
text: '":custom-placeholder:b"',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
start: {line: 1, column: 99},
|
start: {line: 1, column: 99},
|
||||||
end: {line: 1, column: 102},
|
end: {line: 1, column: 102},
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
file,
|
||||||
text: '"c"',
|
text: '"c"',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -112,18 +102,9 @@ runInEachFileSystem(() => {
|
||||||
placeholderNames: ['custom-placeholder', 'PH_1'],
|
placeholderNames: ['custom-placeholder', 'PH_1'],
|
||||||
substitutions: jasmine.any(Object),
|
substitutions: jasmine.any(Object),
|
||||||
substitutionLocations: {
|
substitutionLocations: {
|
||||||
'custom-placeholder': {
|
'custom-placeholder':
|
||||||
start: {line: 1, column: 106},
|
{start: {line: 1, column: 106}, end: {line: 1, column: 107}, file, text: '1'},
|
||||||
end: {line: 1, column: 107},
|
PH_1: {start: {line: 1, column: 109}, end: {line: 1, column: 110}, file, text: '2'}
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '1'
|
|
||||||
},
|
|
||||||
PH_1: {
|
|
||||||
start: {line: 1, column: 109},
|
|
||||||
end: {line: 1, column: 110},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '2'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
legacyIds: [],
|
legacyIds: [],
|
||||||
location: {
|
location: {
|
||||||
|
@ -145,38 +126,13 @@ runInEachFileSystem(() => {
|
||||||
placeholderNames: ['PH', 'PH_1'],
|
placeholderNames: ['PH', 'PH_1'],
|
||||||
substitutions: jasmine.any(Object),
|
substitutions: jasmine.any(Object),
|
||||||
substitutionLocations: {
|
substitutionLocations: {
|
||||||
PH: {
|
PH: {start: {line: 2, column: 26}, end: {line: 2, column: 27}, file, text: '1'},
|
||||||
start: {line: 2, column: 26},
|
PH_1: {start: {line: 2, column: 31}, end: {line: 2, column: 32}, file, text: '2'}
|
||||||
end: {line: 2, column: 27},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '1'
|
|
||||||
},
|
|
||||||
PH_1: {
|
|
||||||
start: {line: 2, column: 31},
|
|
||||||
end: {line: 2, column: 32},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: '2'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
messagePartLocations: [
|
messagePartLocations: [
|
||||||
{
|
{start: {line: 2, column: 10}, end: {line: 2, column: 24}, file, text: ':@@custom-id:a'},
|
||||||
start: {line: 2, column: 10},
|
{start: {line: 2, column: 28}, end: {line: 2, column: 29}, file, text: 'b'},
|
||||||
end: {line: 2, column: 24},
|
{start: {line: 2, column: 33}, end: {line: 2, column: 34}, file, text: 'c'}
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: ':@@custom-id:a'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
start: {line: 2, column: 28},
|
|
||||||
end: {line: 2, column: 29},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: 'b'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
start: {line: 2, column: 33},
|
|
||||||
end: {line: 2, column: 34},
|
|
||||||
file: absoluteFrom('/root/path/relative/path.js'),
|
|
||||||
text: 'c'
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
legacyIds: [],
|
legacyIds: [],
|
||||||
location: {
|
location: {
|
||||||
|
|
|
@ -15,6 +15,7 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/testing",
|
"//packages/compiler-cli/src/ngtsc/testing",
|
||||||
"//packages/localize/src/tools",
|
"//packages/localize/src/tools",
|
||||||
"//packages/localize/src/tools/test:test_lib",
|
"//packages/localize/src/tools/test:test_lib",
|
||||||
|
"//packages/localize/src/tools/test/helpers",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -7,15 +7,15 @@
|
||||||
*/
|
*/
|
||||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, setFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem, setFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {InvalidFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/src/invalid_file_system';
|
import {InvalidFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/src/invalid_file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
||||||
import {MockLogger} from '@angular/compiler-cli/src/ngtsc/logging/testing';
|
import {MockLogger} from '@angular/compiler-cli/src/ngtsc/logging/testing';
|
||||||
import {loadTestDirectory} from '@angular/compiler-cli/src/ngtsc/testing';
|
import {loadTestDirectory} from '@angular/compiler-cli/src/ngtsc/testing';
|
||||||
|
|
||||||
import {extractTranslations} from '../../../src/extract/main';
|
import {extractTranslations} from '../../../src/extract/main';
|
||||||
import {FormatOptions} from '../../../src/extract/translation_files/format_options';
|
import {FormatOptions} from '../../../src/extract/translation_files/format_options';
|
||||||
|
import {runInNativeFileSystem} from '../../helpers';
|
||||||
import {toAttributes} from '../translation_files/utils';
|
import {toAttributes} from '../translation_files/utils';
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
runInNativeFileSystem(() => {
|
||||||
let fs: FileSystem;
|
let fs: FileSystem;
|
||||||
let logger: MockLogger;
|
let logger: MockLogger;
|
||||||
let rootPath: AbsoluteFsPath;
|
let rootPath: AbsoluteFsPath;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package(default_visibility = ["//packages/localize/src/tools/test/extract/integration:__pkg__"])
|
package(default_visibility = ["//packages/localize/src/tools/test/extract/integration:__pkg__"])
|
||||||
|
|
||||||
load("@npm//typescript:index.bzl", "tsc")
|
load("@npm//typescript:index.bzl", "tsc")
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
|
||||||
|
|
||||||
tsc(
|
tsc(
|
||||||
name = "compile_es5",
|
name = "compile_es5",
|
||||||
|
@ -44,7 +45,8 @@ tsc(
|
||||||
data = glob(["src/*.ts"]),
|
data = glob(["src/*.ts"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
# Use copy_to_bin since filegroup doesn't seem to work on Windows.
|
||||||
|
copy_to_bin(
|
||||||
name = "test_files",
|
name = "test_files",
|
||||||
srcs = glob([
|
srcs = glob([
|
||||||
"**/*.js",
|
"**/*.js",
|
||||||
|
|
|
@ -6,30 +6,42 @@
|
||||||
* 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 {getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {FileSystem, getFileSystem, PathSegment, relativeFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
||||||
import {ɵParsedMessage} from '@angular/localize/private';
|
import {ɵParsedMessage} from '@angular/localize/private';
|
||||||
import {transformSync} from '@babel/core';
|
import {transformSync} from '@babel/core';
|
||||||
|
|
||||||
import {makeEs5ExtractPlugin} from '../../../src/extract/source_files/es5_extract_plugin';
|
import {makeEs5ExtractPlugin} from '../../../src/extract/source_files/es5_extract_plugin';
|
||||||
|
import {runInNativeFileSystem} from '../../helpers';
|
||||||
|
|
||||||
|
runInNativeFileSystem(() => {
|
||||||
|
let fs: FileSystem;
|
||||||
|
let testPath: PathSegment;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs = getFileSystem();
|
||||||
|
testPath = relativeFrom('app/dist/test.js');
|
||||||
|
});
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
|
||||||
describe('makeEs5ExtractPlugin()', () => {
|
describe('makeEs5ExtractPlugin()', () => {
|
||||||
it('should error with code-frame information if the first argument to `$localize` is not an array',
|
it('should error with code-frame information if the first argument to `$localize` is not an array',
|
||||||
() => {
|
() => {
|
||||||
const input = '$localize(null, [])';
|
const input = '$localize(null, [])';
|
||||||
expect(() => transformCode(input))
|
expect(() => transformCode(input))
|
||||||
.toThrowError(
|
.toThrowError(
|
||||||
'Cannot create property \'message\' on string \'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
|
`Cannot create property 'message' on string '${testPath}: ` +
|
||||||
|
'Unexpected messageParts for `$localize` (expected an array of strings).\n' +
|
||||||
'> 1 | $localize(null, [])\n' +
|
'> 1 | $localize(null, [])\n' +
|
||||||
' | ^^^^\'');
|
' | ^^^^\'');
|
||||||
});
|
});
|
||||||
|
|
||||||
function transformCode(input: string): ɵParsedMessage[] {
|
function transformCode(input: string): ɵParsedMessage[] {
|
||||||
const messages: ɵParsedMessage[] = [];
|
const messages: ɵParsedMessage[] = [];
|
||||||
|
const cwd = fs.resolve('/');
|
||||||
|
const filename = fs.resolve(cwd, testPath);
|
||||||
transformSync(input, {
|
transformSync(input, {
|
||||||
plugins: [makeEs5ExtractPlugin(getFileSystem(), messages)],
|
plugins: [makeEs5ExtractPlugin(getFileSystem(), messages)],
|
||||||
filename: '/app/dist/test.js'
|
filename,
|
||||||
|
cwd,
|
||||||
})!.code!;
|
})!.code!;
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
load("//tools:defaults.bzl", "ts_library")
|
||||||
|
|
||||||
|
ts_library(
|
||||||
|
name = "helpers",
|
||||||
|
testonly = True,
|
||||||
|
srcs = glob(
|
||||||
|
["**/*.ts"],
|
||||||
|
),
|
||||||
|
visibility = ["//packages/localize/src/tools/test:__subpackages__"],
|
||||||
|
deps = [
|
||||||
|
"//packages/compiler-cli/src/ngtsc/file_system",
|
||||||
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
||||||
|
],
|
||||||
|
)
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* @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.io/license
|
||||||
|
*/
|
||||||
|
import {setFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
|
import {InvalidFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/src/invalid_file_system';
|
||||||
|
import {MockFileSystemNative} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only run these tests on the "native" file-system.
|
||||||
|
*
|
||||||
|
* Babel uses the `path.resolve()` function internally, which makes it very hard to mock out the
|
||||||
|
* file-system from the outside. We run these tests on Unix and Windows in our CI jobs, so there is
|
||||||
|
* test coverage.
|
||||||
|
*/
|
||||||
|
export function runInNativeFileSystem(callback: () => void) {
|
||||||
|
describe(`<<FileSystem: Native>>`, () => {
|
||||||
|
beforeEach(() => setFileSystem(new MockFileSystemNative()));
|
||||||
|
afterEach(() => setFileSystem(new InvalidFileSystem()));
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
|
@ -6,16 +6,16 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {absoluteFrom, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
||||||
import {ɵmakeTemplateObject} from '@angular/localize';
|
import {ɵmakeTemplateObject} from '@angular/localize';
|
||||||
import {NodePath, TransformOptions, transformSync} from '@babel/core';
|
import {NodePath, TransformOptions, transformSync} from '@babel/core';
|
||||||
import generate from '@babel/generator';
|
import generate from '@babel/generator';
|
||||||
|
|
||||||
import template from '@babel/template';
|
import template from '@babel/template';
|
||||||
import {Expression, Identifier, TaggedTemplateExpression, ExpressionStatement, CallExpression, isParenthesizedExpression, numericLiteral, binaryExpression, NumericLiteral} from '@babel/types';
|
import {Expression, Identifier, TaggedTemplateExpression, ExpressionStatement, CallExpression, isParenthesizedExpression, numericLiteral, binaryExpression, NumericLiteral} from '@babel/types';
|
||||||
import {isGlobalIdentifier, isNamedIdentifier, isStringLiteralArray, isArrayOfExpressions, unwrapStringLiteralArray, unwrapMessagePartsFromLocalizeCall, wrapInParensIfNecessary, buildLocalizeReplacement, unwrapSubstitutionsFromLocalizeCall, unwrapMessagePartsFromTemplateLiteral, getLocation} from '../src/source_file_utils';
|
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
import {isGlobalIdentifier, isNamedIdentifier, isStringLiteralArray, isArrayOfExpressions, unwrapStringLiteralArray, unwrapMessagePartsFromLocalizeCall, wrapInParensIfNecessary, buildLocalizeReplacement, unwrapSubstitutionsFromLocalizeCall, unwrapMessagePartsFromTemplateLiteral, getLocation} from '../src/source_file_utils';
|
||||||
|
import {runInNativeFileSystem} from './helpers';
|
||||||
|
|
||||||
|
runInNativeFileSystem(() => {
|
||||||
let fs: PathManipulation;
|
let fs: PathManipulation;
|
||||||
beforeEach(() => fs = getFileSystem());
|
beforeEach(() => fs = getFileSystem());
|
||||||
describe('utils', () => {
|
describe('utils', () => {
|
||||||
|
@ -414,7 +414,7 @@ runInEachFileSystem(() => {
|
||||||
it('should return a plain object containing the start, end and file of a NodePath', () => {
|
it('should return a plain object containing the start, end and file of a NodePath', () => {
|
||||||
const taggedTemplate = getTaggedTemplate('const x = $localize `message`;', {
|
const taggedTemplate = getTaggedTemplate('const x = $localize `message`;', {
|
||||||
filename: 'src/test.js',
|
filename: 'src/test.js',
|
||||||
sourceRoot: '/root',
|
sourceRoot: fs.resolve('/project'),
|
||||||
});
|
});
|
||||||
const location = getLocation(fs, taggedTemplate)!;
|
const location = getLocation(fs, taggedTemplate)!;
|
||||||
expect(location).toBeDefined();
|
expect(location).toBeDefined();
|
||||||
|
@ -422,12 +422,12 @@ runInEachFileSystem(() => {
|
||||||
expect(location.start.constructor.name).toEqual('Object');
|
expect(location.start.constructor.name).toEqual('Object');
|
||||||
expect(location.end).toEqual({line: 0, column: 29});
|
expect(location.end).toEqual({line: 0, column: 29});
|
||||||
expect(location.end?.constructor.name).toEqual('Object');
|
expect(location.end?.constructor.name).toEqual('Object');
|
||||||
expect(location.file).toEqual(absoluteFrom('/root/src/test.js'));
|
expect(location.file).toEqual(fs.resolve('/project/src/test.js'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return `undefined` if the NodePath has no filename', () => {
|
it('should return `undefined` if the NodePath has no filename', () => {
|
||||||
const taggedTemplate = getTaggedTemplate(
|
const taggedTemplate = getTaggedTemplate(
|
||||||
'const x = $localize ``;', {sourceRoot: '/root', filename: undefined});
|
'const x = $localize ``;', {sourceRoot: fs.resolve('/project'), filename: undefined});
|
||||||
const location = getLocation(fs, taggedTemplate);
|
const location = getLocation(fs, taggedTemplate);
|
||||||
expect(location).toBeUndefined();
|
expect(location).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
@ -451,7 +451,8 @@ function getExpressions<T extends Expression>(
|
||||||
const expressions: NodePath<Expression>[] = [];
|
const expressions: NodePath<Expression>[] = [];
|
||||||
transformSync(code, {
|
transformSync(code, {
|
||||||
code: false,
|
code: false,
|
||||||
filename: '/test/file.js',
|
filename: 'test/file.js',
|
||||||
|
cwd: '/',
|
||||||
plugins: [{
|
plugins: [{
|
||||||
visitor: {
|
visitor: {
|
||||||
Expression: (path: NodePath<Expression>) => {
|
Expression: (path: NodePath<Expression>) => {
|
||||||
|
@ -468,7 +469,8 @@ function getLocalizeCall(code: string): NodePath<CallExpression> {
|
||||||
let callPaths: NodePath<CallExpression>[] = [];
|
let callPaths: NodePath<CallExpression>[] = [];
|
||||||
transformSync(code, {
|
transformSync(code, {
|
||||||
code: false,
|
code: false,
|
||||||
filename: '/test/file.js',
|
filename: 'test/file.js',
|
||||||
|
cwd: '/',
|
||||||
plugins: [{
|
plugins: [{
|
||||||
visitor: {
|
visitor: {
|
||||||
CallExpression(path) {
|
CallExpression(path) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fs = getFileSystem();
|
fs = getFileSystem();
|
||||||
rootPath = absoluteFrom('/root/path');
|
rootPath = absoluteFrom('/src/path');
|
||||||
filePath = relativeFrom('relative/path');
|
filePath = relativeFrom('relative/path');
|
||||||
enTranslationPath = absoluteFrom('/translations/en/relative/path');
|
enTranslationPath = absoluteFrom('/translations/en/relative/path');
|
||||||
enUSTranslationPath = absoluteFrom('/translations/en-US/relative/path');
|
enUSTranslationPath = absoluteFrom('/translations/en-US/relative/path');
|
||||||
|
|
|
@ -12,18 +12,17 @@ ts_library(
|
||||||
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
"//packages/compiler-cli/src/ngtsc/file_system/testing",
|
||||||
"//packages/compiler-cli/src/ngtsc/testing",
|
"//packages/compiler-cli/src/ngtsc/testing",
|
||||||
"//packages/localize/src/tools",
|
"//packages/localize/src/tools",
|
||||||
|
"//packages/localize/src/tools/test/helpers",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
jasmine_node_test(
|
jasmine_node_test(
|
||||||
name = "integration",
|
name = "integration",
|
||||||
bootstrap = ["//tools/testing:node_no_angular_es5"],
|
bootstrap = ["//tools/testing:node_no_angular_es5"],
|
||||||
data = glob(
|
data = [
|
||||||
[
|
"//packages/localize/src/tools/test/translate/integration/locales",
|
||||||
"locales/**",
|
"//packages/localize/src/tools/test/translate/integration/test_files",
|
||||||
"test_files/**",
|
|
||||||
],
|
],
|
||||||
),
|
|
||||||
deps = [
|
deps = [
|
||||||
":test_lib",
|
":test_lib",
|
||||||
"@npm//glob",
|
"@npm//glob",
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package(default_visibility = ["//packages/localize/src/tools/test/translate/integration:__pkg__"])
|
||||||
|
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
|
||||||
|
|
||||||
|
# Use copy_to_bin since filegroup doesn't seem to work on Windows.
|
||||||
|
copy_to_bin(
|
||||||
|
name = "locales",
|
||||||
|
srcs = glob([
|
||||||
|
"**/*.json",
|
||||||
|
"**/*.xlf",
|
||||||
|
"**/*.xtb",
|
||||||
|
]),
|
||||||
|
)
|
|
@ -6,15 +6,15 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, AbsoluteFsPath, FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
|
||||||
import {loadTestDirectory} from '@angular/compiler-cli/src/ngtsc/testing';
|
import {loadTestDirectory} from '@angular/compiler-cli/src/ngtsc/testing';
|
||||||
import {resolve as realResolve} from 'path';
|
import {resolve as realResolve} from 'path';
|
||||||
|
|
||||||
import {Diagnostics} from '../../../src/diagnostics';
|
import {Diagnostics} from '../../../src/diagnostics';
|
||||||
import {translateFiles} from '../../../src/translate/main';
|
import {translateFiles} from '../../../src/translate/main';
|
||||||
import {getOutputPathFn} from '../../../src/translate/output_path';
|
import {getOutputPathFn} from '../../../src/translate/output_path';
|
||||||
|
import {runInNativeFileSystem} from '../../helpers';
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
runInNativeFileSystem(() => {
|
||||||
describe('translateFiles()', () => {
|
describe('translateFiles()', () => {
|
||||||
let fs: FileSystem;
|
let fs: FileSystem;
|
||||||
let testDir: AbsoluteFsPath;
|
let testDir: AbsoluteFsPath;
|
||||||
|
@ -33,7 +33,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should copy non-code files to the destination folders', () => {
|
it('should copy non-code files to the destination folders', () => {
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(testDir, '{{LOCALE}}'));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
||||||
translateFiles({
|
translateFiles({
|
||||||
sourceRootPath: testFilesDir,
|
sourceRootPath: testFilesDir,
|
||||||
sourceFilePaths: ['test-1.txt', 'test-2.txt'],
|
sourceFilePaths: ['test-1.txt', 'test-2.txt'],
|
||||||
|
@ -69,7 +69,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should translate and copy source-code files to the destination folders', () => {
|
it('should translate and copy source-code files to the destination folders', () => {
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(testDir, '{{LOCALE}}'));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
||||||
translateFiles({
|
translateFiles({
|
||||||
sourceRootPath: testFilesDir,
|
sourceRootPath: testFilesDir,
|
||||||
sourceFilePaths: ['test.js'],
|
sourceFilePaths: ['test.js'],
|
||||||
|
@ -97,7 +97,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should translate and copy source-code files overriding the locales', () => {
|
it('should translate and copy source-code files overriding the locales', () => {
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(testDir, '{{LOCALE}}'));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
||||||
translateFiles({
|
translateFiles({
|
||||||
sourceRootPath: testFilesDir,
|
sourceRootPath: testFilesDir,
|
||||||
sourceFilePaths: ['test.js'],
|
sourceFilePaths: ['test.js'],
|
||||||
|
@ -131,7 +131,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should merge translation files, if more than one provided, and translate source-code', () => {
|
it('should merge translation files, if more than one provided, and translate source-code', () => {
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(testDir, '{{LOCALE}}'));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
||||||
translateFiles({
|
translateFiles({
|
||||||
sourceRootPath: testFilesDir,
|
sourceRootPath: testFilesDir,
|
||||||
sourceFilePaths: ['test-extra.js'],
|
sourceFilePaths: ['test-extra.js'],
|
||||||
|
@ -165,7 +165,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
it('should transform and/or copy files to the destination folders', () => {
|
it('should transform and/or copy files to the destination folders', () => {
|
||||||
const diagnostics = new Diagnostics();
|
const diagnostics = new Diagnostics();
|
||||||
const outputPathFn = getOutputPathFn(fs.resolve(testDir, '{{LOCALE}}'));
|
const outputPathFn = getOutputPathFn(fs, fs.resolve(testDir, '{{LOCALE}}'));
|
||||||
translateFiles({
|
translateFiles({
|
||||||
sourceRootPath: testFilesDir,
|
sourceRootPath: testFilesDir,
|
||||||
sourceFilePaths: ['test-1.txt', 'test-2.txt', 'test.js'],
|
sourceFilePaths: ['test-1.txt', 'test-2.txt', 'test.js'],
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package(default_visibility = ["//packages/localize/src/tools/test/translate/integration:__pkg__"])
|
||||||
|
|
||||||
|
load("@build_bazel_rules_nodejs//:index.bzl", "copy_to_bin")
|
||||||
|
|
||||||
|
# Use copy_to_bin since filegroup doesn't seem to work on Windows.
|
||||||
|
copy_to_bin(
|
||||||
|
name = "test_files",
|
||||||
|
srcs = glob([
|
||||||
|
"**/*.js",
|
||||||
|
"**/*.txt",
|
||||||
|
]),
|
||||||
|
)
|
|
@ -5,36 +5,39 @@
|
||||||
* 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 {absoluteFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
|
import {absoluteFrom, getFileSystem, PathManipulation} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
import {runInEachFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system/testing';
|
||||||
|
|
||||||
import {getOutputPathFn} from '../../src/translate/output_path';
|
import {getOutputPathFn} from '../../src/translate/output_path';
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
runInEachFileSystem(() => {
|
||||||
|
let fs: PathManipulation;
|
||||||
|
beforeEach(() => fs = getFileSystem());
|
||||||
|
|
||||||
describe('getOutputPathFn()', () => {
|
describe('getOutputPathFn()', () => {
|
||||||
it('should return a function that joins the `outputPath` and the `relativePath`', () => {
|
it('should return a function that joins the `outputPath` and the `relativePath`', () => {
|
||||||
const fn = getOutputPathFn(absoluteFrom('/output/path'));
|
const fn = getOutputPathFn(fs, absoluteFrom('/output/path'));
|
||||||
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/path/relative/path'));
|
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/path/relative/path'));
|
||||||
expect(fn('en', '../parent/path')).toEqual(absoluteFrom('/output/parent/path'));
|
expect(fn('en', '../parent/path')).toEqual(absoluteFrom('/output/parent/path'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a function that interpolates the `{{LOCALE}}` in the middle of the `outputPath`',
|
it('should return a function that interpolates the `{{LOCALE}}` in the middle of the `outputPath`',
|
||||||
() => {
|
() => {
|
||||||
const fn = getOutputPathFn(absoluteFrom('/output/{{LOCALE}}/path'));
|
const fn = getOutputPathFn(fs, absoluteFrom('/output/{{LOCALE}}/path'));
|
||||||
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/en/path/relative/path'));
|
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/en/path/relative/path'));
|
||||||
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output/fr/path/relative/path'));
|
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output/fr/path/relative/path'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a function that interpolates the `{{LOCALE}}` in the middle of a path segment in the `outputPath`',
|
it('should return a function that interpolates the `{{LOCALE}}` in the middle of a path segment in the `outputPath`',
|
||||||
() => {
|
() => {
|
||||||
const fn = getOutputPathFn(absoluteFrom('/output-{{LOCALE}}-path'));
|
const fn = getOutputPathFn(fs, absoluteFrom('/output-{{LOCALE}}-path'));
|
||||||
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output-en-path/relative/path'));
|
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output-en-path/relative/path'));
|
||||||
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output-fr-path/relative/path'));
|
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output-fr-path/relative/path'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return a function that interpolates the `{{LOCALE}}` at the end of the `outputPath`',
|
it('should return a function that interpolates the `{{LOCALE}}` at the end of the `outputPath`',
|
||||||
() => {
|
() => {
|
||||||
const fn = getOutputPathFn(absoluteFrom('/output/{{LOCALE}}'));
|
const fn = getOutputPathFn(fs, absoluteFrom('/output/{{LOCALE}}'));
|
||||||
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/en/relative/path'));
|
expect(fn('en', 'relative/path')).toEqual(absoluteFrom('/output/en/relative/path'));
|
||||||
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output/fr/relative/path'));
|
expect(fn('fr', 'relative/path')).toEqual(absoluteFrom('/output/fr/relative/path'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 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 {FileSystem, getFileSystem} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
|
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
|
||||||
import {ɵParsedTranslation} from '@angular/localize/private';
|
import {ɵParsedTranslation} from '@angular/localize/private';
|
||||||
import {transformSync} from '@babel/core';
|
import {transformSync} from '@babel/core';
|
||||||
|
@ -13,8 +13,15 @@ import {transformSync} from '@babel/core';
|
||||||
import {Diagnostics} from '../../../src/diagnostics';
|
import {Diagnostics} from '../../../src/diagnostics';
|
||||||
import {TranslatePluginOptions} from '../../../src/source_file_utils';
|
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';
|
||||||
|
import {runInNativeFileSystem} from '../../helpers';
|
||||||
|
|
||||||
|
runInNativeFileSystem(() => {
|
||||||
|
let fs: FileSystem;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs = getFileSystem();
|
||||||
|
});
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
|
||||||
describe('makeEs2015Plugin', () => {
|
describe('makeEs2015Plugin', () => {
|
||||||
describe('(no translations)', () => {
|
describe('(no translations)', () => {
|
||||||
it('should transform `$localize` tags with binary expression', () => {
|
it('should transform `$localize` tags with binary expression', () => {
|
||||||
|
@ -172,9 +179,12 @@ runInEachFileSystem(() => {
|
||||||
function transformCode(
|
function transformCode(
|
||||||
input: string, translations: Record<string, ɵParsedTranslation> = {},
|
input: string, translations: Record<string, ɵParsedTranslation> = {},
|
||||||
pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
|
pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
|
||||||
|
const cwd = fs.resolve('/');
|
||||||
|
const filename = fs.resolve(cwd, 'app/dist/test.js');
|
||||||
return transformSync(input, {
|
return transformSync(input, {
|
||||||
plugins: [makeEs2015TranslatePlugin(diagnostics, translations, pluginOptions)],
|
plugins: [makeEs2015TranslatePlugin(diagnostics, translations, pluginOptions)],
|
||||||
filename: '/app/dist/test.js'
|
filename,
|
||||||
|
cwd,
|
||||||
})!.code!;
|
})!.code!;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 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 {FileSystem, getFileSystem, PathSegment, relativeFrom} from '@angular/compiler-cli/src/ngtsc/file_system';
|
||||||
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
|
import {ɵcomputeMsgId, ɵparseTranslation} from '@angular/localize';
|
||||||
import {ɵParsedTranslation} from '@angular/localize/private';
|
import {ɵParsedTranslation} from '@angular/localize/private';
|
||||||
import {transformSync} from '@babel/core';
|
import {transformSync} from '@babel/core';
|
||||||
|
@ -13,8 +13,17 @@ import {transformSync} from '@babel/core';
|
||||||
import {Diagnostics} from '../../../src/diagnostics';
|
import {Diagnostics} from '../../../src/diagnostics';
|
||||||
import {TranslatePluginOptions} from '../../../src/source_file_utils';
|
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';
|
||||||
|
import {runInNativeFileSystem} from '../../helpers';
|
||||||
|
|
||||||
|
runInNativeFileSystem(() => {
|
||||||
|
let fs: FileSystem;
|
||||||
|
let testPath: PathSegment;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fs = getFileSystem();
|
||||||
|
testPath = relativeFrom('app/dist/test.js');
|
||||||
|
});
|
||||||
|
|
||||||
runInEachFileSystem(() => {
|
|
||||||
describe('makeEs5Plugin', () => {
|
describe('makeEs5Plugin', () => {
|
||||||
describe('(no translations)', () => {
|
describe('(no translations)', () => {
|
||||||
it('should transform `$localize` calls with binary expression', () => {
|
it('should transform `$localize` calls with binary expression', () => {
|
||||||
|
@ -142,7 +151,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.hasErrors).toBe(true);
|
expect(diagnostics.hasErrors).toBe(true);
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message: '/app/dist/test.js: `$localize` called without any arguments.\n' +
|
message: `${testPath}: \`$localize\` called without any arguments.\n` +
|
||||||
'> 1 | $localize()\n' +
|
'> 1 | $localize()\n' +
|
||||||
' | ^^^^^^^^^^^',
|
' | ^^^^^^^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -156,8 +165,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.hasErrors).toBe(true);
|
expect(diagnostics.hasErrors).toBe(true);
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message: `${testPath}: Unexpected argument to \`$localize\` (expected an array).\n` +
|
||||||
'/app/dist/test.js: Unexpected argument to `$localize` (expected an array).\n' +
|
|
||||||
'> 1 | $localize(...x)\n' +
|
'> 1 | $localize(...x)\n' +
|
||||||
' | ^^^^',
|
' | ^^^^',
|
||||||
});
|
});
|
||||||
|
@ -172,7 +180,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
|
`${testPath}: Unexpected messageParts for \`$localize\` (expected an array of strings).\n` +
|
||||||
'> 1 | $localize(null, [])\n' +
|
'> 1 | $localize(null, [])\n' +
|
||||||
' | ^^^^',
|
' | ^^^^',
|
||||||
});
|
});
|
||||||
|
@ -187,7 +195,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Unexpected `raw` argument to the "makeTemplateObject()" function (expected an expression).\n' +
|
`${testPath}: Unexpected \`raw\` argument to the "makeTemplateObject()" function (expected an expression).\n` +
|
||||||
'> 1 | $localize(__makeTemplateObject([], ...[]))\n' +
|
'> 1 | $localize(__makeTemplateObject([], ...[]))\n' +
|
||||||
' | ^^^^^',
|
' | ^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -202,7 +210,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Unexpected `cooked` argument to the "makeTemplateObject()" function (expected an expression).\n' +
|
`${testPath}: Unexpected \`cooked\` argument to the "makeTemplateObject()" function (expected an expression).\n` +
|
||||||
'> 1 | $localize(__makeTemplateObject(...[], []))\n' +
|
'> 1 | $localize(__makeTemplateObject(...[], []))\n' +
|
||||||
' | ^^^^^',
|
' | ^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -217,7 +225,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
|
`${testPath}: Unexpected messageParts for \`$localize\` (expected an array of strings).\n` +
|
||||||
'> 1 | $localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))\n' +
|
'> 1 | $localize(__makeTemplateObject(["a", 12, "b"], ["a", "12", "b"]))\n' +
|
||||||
' | ^^^^^^^^^^^^^^',
|
' | ^^^^^^^^^^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -232,7 +240,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Unexpected messageParts for `$localize` (expected an array of strings).\n' +
|
`${testPath}: Unexpected messageParts for \`$localize\` (expected an array of strings).\n` +
|
||||||
'> 1 | $localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))\n' +
|
'> 1 | $localize(__makeTemplateObject(["a", "12", "b"], ["a", 12, "b"]))\n' +
|
||||||
' | ^^^^^^^^^^^^^^',
|
' | ^^^^^^^^^^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -247,7 +255,7 @@ runInEachFileSystem(() => {
|
||||||
expect(diagnostics.messages[0]).toEqual({
|
expect(diagnostics.messages[0]).toEqual({
|
||||||
type: 'error',
|
type: 'error',
|
||||||
message:
|
message:
|
||||||
'/app/dist/test.js: Invalid substitutions for `$localize` (expected all substitution arguments to be expressions).\n' +
|
`${testPath}: Invalid substitutions for \`$localize\` (expected all substitution arguments to be expressions).\n` +
|
||||||
'> 1 | $localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])\n' +
|
'> 1 | $localize(__makeTemplateObject(["a", "b"], ["a", "b"]), ...[])\n' +
|
||||||
' | ^^^^^',
|
' | ^^^^^',
|
||||||
});
|
});
|
||||||
|
@ -361,9 +369,12 @@ runInEachFileSystem(() => {
|
||||||
function transformCode(
|
function transformCode(
|
||||||
input: string, translations: Record<string, ɵParsedTranslation> = {},
|
input: string, translations: Record<string, ɵParsedTranslation> = {},
|
||||||
pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
|
pluginOptions?: TranslatePluginOptions, diagnostics = new Diagnostics()): string {
|
||||||
|
const cwd = fs.resolve('/');
|
||||||
|
const filename = fs.resolve(cwd, testPath);
|
||||||
return transformSync(input, {
|
return transformSync(input, {
|
||||||
plugins: [makeEs5TranslatePlugin(diagnostics, translations, pluginOptions)],
|
plugins: [makeEs5TranslatePlugin(diagnostics, translations, pluginOptions)],
|
||||||
filename: '/app/dist/test.js'
|
filename,
|
||||||
|
cwd,
|
||||||
})!.code!;
|
})!.code!;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,7 +23,7 @@ runInEachFileSystem(() => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fs = getFileSystem();
|
fs = getFileSystem();
|
||||||
rootPath = absoluteFrom('/root/path');
|
rootPath = absoluteFrom('/src/path');
|
||||||
filePath = relativeFrom('relative/path.js');
|
filePath = relativeFrom('relative/path.js');
|
||||||
enTranslationPath = absoluteFrom('/translations/en/relative/path.js');
|
enTranslationPath = absoluteFrom('/translations/en/relative/path.js');
|
||||||
enUSTranslationPath = absoluteFrom('/translations/en-US/relative/path.js');
|
enUSTranslationPath = absoluteFrom('/translations/en-US/relative/path.js');
|
||||||
|
|
Loading…
Reference in New Issue