Add tests and allow more liberal spacing with get/instant calls
This commit is contained in:
parent
ca8b122295
commit
8093370e94
@ -21,7 +21,7 @@ const options = cli.parse({
|
|||||||
|
|
||||||
[options.dir, options.output].forEach(dir => {
|
[options.dir, options.output].forEach(dir => {
|
||||||
if (!fs.existsSync(dir)) {
|
if (!fs.existsSync(dir)) {
|
||||||
cli.fatal('The directory path you supplied was not found: ' + dir);
|
cli.fatal(`The directory path you supplied was not found: '${dir}'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -39,17 +39,12 @@ const patterns: string[] = [
|
|||||||
'/**/*.js'
|
'/**/*.js'
|
||||||
];
|
];
|
||||||
|
|
||||||
const extractor: Extractor = new Extractor(parsers, patterns);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const extractor: Extractor = new Extractor(parsers, patterns);
|
||||||
cli.info(`Extracting strings from '${options.dir}'`);
|
cli.info(`Extracting strings from '${options.dir}'`);
|
||||||
const extracted: TranslationCollection = extractor.process(options.dir);
|
const extracted: TranslationCollection = extractor.process(options.dir);
|
||||||
cli.ok(`* Extracted ${extracted.count()} strings`);
|
cli.ok(`* Extracted ${extracted.count()} strings`);
|
||||||
|
|
||||||
if (extracted.isEmpty()) {
|
|
||||||
process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
let collection: TranslationCollection = extracted;
|
let collection: TranslationCollection = extracted;
|
||||||
|
|
||||||
let compiler = new JsonCompiler();
|
let compiler = new JsonCompiler();
|
||||||
@ -60,8 +55,10 @@ try {
|
|||||||
if (!options.replace && fs.existsSync(dest)) {
|
if (!options.replace && fs.existsSync(dest)) {
|
||||||
const existing: TranslationCollection = compiler.parse(fs.readFileSync(dest, 'utf-8'));
|
const existing: TranslationCollection = compiler.parse(fs.readFileSync(dest, 'utf-8'));
|
||||||
|
|
||||||
collection = extracted.union(existing);
|
if (existing.count() > 0) {
|
||||||
cli.ok(`* Merged ${existing.count()} existing strings`);
|
collection = extracted.union(existing);
|
||||||
|
cli.ok(`* Merged ${existing.count()} existing strings`);
|
||||||
|
}
|
||||||
|
|
||||||
if (options.clean) {
|
if (options.clean) {
|
||||||
const collectionCount = collection.count();
|
const collectionCount = collection.count();
|
||||||
|
@ -25,7 +25,7 @@ export class PoCompiler implements CompilerInterface {
|
|||||||
msgstr: collection.get(key)
|
msgstr: collection.get(key)
|
||||||
};
|
};
|
||||||
return translations;
|
return translations;
|
||||||
}, <any>{})
|
}, <any> {})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ export class PoCompiler implements CompilerInterface {
|
|||||||
.reduce((values, key) => {
|
.reduce((values, key) => {
|
||||||
values[key] = po.translations[this.domain][key].msgstr.pop();
|
values[key] = po.translations[this.domain][key].msgstr.pop();
|
||||||
return values;
|
return values;
|
||||||
}, <TranslationType>{});
|
}, <TranslationType> {});
|
||||||
|
|
||||||
return new TranslationCollection(values);
|
return new TranslationCollection(values);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ export abstract class AbstractTemplateParser {
|
|||||||
* Extracts inline template from components
|
* Extracts inline template from components
|
||||||
*/
|
*/
|
||||||
protected _extractInlineTemplate(contents: string): string {
|
protected _extractInlineTemplate(contents: string): string {
|
||||||
const match = new RegExp(/template\s*:\s*(["'`])((.|[\r\n])+?[^\\])\1/).exec(contents);
|
const match = new RegExp(/template\s*:\s*(["'`])([^\1]*?)\1/).exec(contents);
|
||||||
if (match !== null) {
|
if (match !== null) {
|
||||||
return match[2];
|
return match[2];
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export class PipeParser extends AbstractTemplateParser implements ParserInterfac
|
|||||||
protected _parseTemplate(template: string): TranslationCollection {
|
protected _parseTemplate(template: string): TranslationCollection {
|
||||||
let collection: TranslationCollection = new TranslationCollection();
|
let collection: TranslationCollection = new TranslationCollection();
|
||||||
|
|
||||||
const regExp = new RegExp(/(['"`])([^\1\r\n]*)\1\s*\|\s*translate(:.*?)?/, 'g');
|
const regExp = new RegExp(/(['"`])([^\1]*)\1\s*\|\s*translate/, 'g');
|
||||||
|
|
||||||
let matches: RegExpExecArray;
|
let matches: RegExpExecArray;
|
||||||
while (matches = regExp.exec(template)) {
|
while (matches = regExp.exec(template)) {
|
||||||
|
@ -11,10 +11,10 @@ export class ServiceParser implements ParserInterface {
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
const methodRegExp: RegExp = new RegExp(/(?:get|instant)\s*\(\s*(\[?(['"`])([^\1\r\n]+)\2\]?)/);
|
const methodRegExp: RegExp = new RegExp(/(?:get|instant)\s*\(\s*(\[?\s*(['"`])([^\1\r\n]*)\2\s*\]?)/);
|
||||||
const regExp: RegExp = new RegExp(`${translateServiceVar}\.${methodRegExp.source}`, 'g');
|
const regExp: RegExp = new RegExp(`${translateServiceVar}\.${methodRegExp.source}`, 'g');
|
||||||
|
|
||||||
let matches;
|
let matches: RegExpExecArray;
|
||||||
while (matches = regExp.exec(contents)) {
|
while (matches = regExp.exec(contents)) {
|
||||||
if (this._stringContainsArray(matches[1])) {
|
if (this._stringContainsArray(matches[1])) {
|
||||||
collection = collection.addKeys(this._stringToArray(matches[1]));
|
collection = collection.addKeys(this._stringToArray(matches[1]));
|
||||||
|
@ -18,7 +18,7 @@ export class TranslationCollection {
|
|||||||
const values = keys.reduce((results, key) => {
|
const values = keys.reduce((results, key) => {
|
||||||
results[key] = '';
|
results[key] = '';
|
||||||
return results;
|
return results;
|
||||||
}, <TranslationType>{});
|
}, <TranslationType> {});
|
||||||
return new TranslationCollection(Object.assign({}, this.values, values));
|
return new TranslationCollection(Object.assign({}, this.values, values));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +41,12 @@ describe('AbstractTemplateParser', () => {
|
|||||||
expect(result).to.equal(false);
|
expect(result).to.equal(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should normalize bound attributes', () => {
|
||||||
|
const contents = `<p [translate]="'KEY'">Hello World</p>`;
|
||||||
|
const template = parser.normalizeTemplateAttributes(contents);
|
||||||
|
expect(template).to.equal('<p translate="KEY">Hello World</p>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should extract inline template', () => {
|
it('should extract inline template', () => {
|
||||||
const contents = `
|
const contents = `
|
||||||
@Component({
|
@Component({
|
||||||
@ -53,10 +59,25 @@ describe('AbstractTemplateParser', () => {
|
|||||||
expect(template).to.equal('<p translate>Hello World</p>');
|
expect(template).to.equal('<p translate>Hello World</p>');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should normalize bound attributes', () => {
|
it('should extract inline template spanning multiple lines', () => {
|
||||||
const contents = `<p [translate]="'KEY'">Hello World</p>`;
|
const contents = `
|
||||||
const template = parser.normalizeTemplateAttributes(contents);
|
@Component({
|
||||||
expect(template).to.equal('<p translate="KEY">Hello World</p>');
|
selector: 'test',
|
||||||
|
template: '
|
||||||
|
<p>
|
||||||
|
Hello World
|
||||||
|
</p>
|
||||||
|
',
|
||||||
|
styles: ['
|
||||||
|
p {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
']
|
||||||
|
})
|
||||||
|
export class TestComponent { }
|
||||||
|
`;
|
||||||
|
const template = parser.extractInlineTemplate(contents);
|
||||||
|
expect(template).to.equal('\n\t\t\t\t\t<p>\n\t\t\t\t\t\tHello World\n\t\t\t\t\t</p>\n\t\t\t\t');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,12 @@ describe('PipeParser', () => {
|
|||||||
expect(keys).to.deep.equal(['World']);
|
expect(keys).to.deep.equal(['World']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should extract strings with escaped quotes', () => {
|
||||||
|
const contents = `Hello {{ 'World\'s largest potato' | translate }}`;
|
||||||
|
const keys = parser.extract(contents, templateFilename).keys();
|
||||||
|
expect(keys).to.deep.equal([`World's largest potato`]);
|
||||||
|
});
|
||||||
|
|
||||||
it('should extract interpolated strings using translate pipe in attributes', () => {
|
it('should extract interpolated strings using translate pipe in attributes', () => {
|
||||||
const contents = `<span attr="{{ 'Hello World' | translate }}"></span>`;
|
const contents = `<span attr="{{ 'Hello World' | translate }}"></span>`;
|
||||||
const keys = parser.extract(contents, templateFilename).keys();
|
const keys = parser.extract(contents, templateFilename).keys();
|
||||||
|
@ -103,4 +103,24 @@ describe('ServiceParser', () => {
|
|||||||
expect(keys).to.deep.equal([]);
|
expect(keys).to.deep.equal([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should extract strings with liberal spacing', () => {
|
||||||
|
const contents = `
|
||||||
|
@Component({ })
|
||||||
|
export class AppComponent {
|
||||||
|
public constructor(
|
||||||
|
protected _translateService: TranslateService,
|
||||||
|
protected _otherService: OtherService
|
||||||
|
) { }
|
||||||
|
public test() {
|
||||||
|
this._translateService.instant('Hello');
|
||||||
|
this._translateService.get ( 'World' );
|
||||||
|
this._translateService.instant ( ['How'] );
|
||||||
|
this._translateService.get([ 'Are' ]);
|
||||||
|
this._translateService.get([ 'You' , 'Today' ]);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const keys = parser.extract(contents, componentFilename).keys();
|
||||||
|
expect(keys).to.deep.equal(['Hello', 'World', 'How', 'Are', 'You', 'Today']);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user