Skip to content

Commit

Permalink
Merge pull request #165 from wilsenhc/feat/noEmptyTranslation
Browse files Browse the repository at this point in the history
Feature: option for no empty translation when adding missing strings
  • Loading branch information
Spittal authored May 26, 2022
2 parents e743a59 + a9b5a02 commit f21cb32
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 5 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ This will print out a table of missing keys in your language files, as well as u
// Example1 (specific, value is a key): user.auth.username.label
// Example2 (nested, value is a node): user.auth
// Example3 (multiple): --exclude user.auth.username.label --exclude user.auth.password.label

--noEmptyTranslation
// String
// Use if you want to generate a default translated string by using the key itself
// Example 1: '' => DO NOT generate default strings (default)
// Example 2: '*' => generate default string for ALL locales
// Example 3: 'en' => generate default strings ONLY for en locale
```

## Config File
Expand Down
4 changes: 4 additions & 0 deletions bin/vue-i18n-extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ cli
'--exclude <key>',
'Use if you want to exclude a key. It can be used multiple times to exclude any amount of keys on the output'
)
.option(
'--noEmptyTranslation',
'Use if you want to generate a default translated string by using the key itself'
)
.action((options) => {
createI18NReport(resolveConfig(options));
});
Expand Down
3 changes: 2 additions & 1 deletion src/config-file/vue-i18n-extract.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export default {
add: false,
remove: false,
ci: false,
separator: '.'
separator: '.',
noEmptyTranslation: ''
};
5 changes: 3 additions & 2 deletions src/create-report/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export async function createI18NReport (options: ReportOptions): Promise<I18NRep
remove,
exclude = [],
ci,
separator
separator,
noEmptyTranslation = '',
} = options;

if (!vueFilesGlob) throw new Error('Required configuration vueFiles is missing.');
Expand Down Expand Up @@ -47,7 +48,7 @@ export async function createI18NReport (options: ReportOptions): Promise<I18NRep
}

if (add && report.missingKeys.length) {
writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot);
writeMissingToLanguageFiles(languageFiles, report.missingKeys, dot, noEmptyTranslation);
console.info('\nThe missing keys have been added to your language files.');
}

Expand Down
5 changes: 3 additions & 2 deletions src/create-report/language-files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,14 @@ export function extractI18NLanguageFromLanguageFiles (languageFiles: SimpleFile[
}, {});
}

export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot): void {
export function writeMissingToLanguageFiles (parsedLanguageFiles: SimpleFile[], missingKeys: I18NItem[], dot: DotObject.Dot = Dot, noEmptyTranslation = ''): void {
parsedLanguageFiles.forEach(languageFile => {
const languageFileContent = JSON.parse(languageFile.content);

missingKeys.forEach(item => {
if (item.language && languageFile.fileName.includes(item.language) || !item.language) {
dot.str(item.path, '', languageFileContent);
const addDefaultTranslation = (noEmptyTranslation) && ((noEmptyTranslation === '*') || (noEmptyTranslation === item.language));
dot.str(item.path, addDefaultTranslation ? item.path : '', languageFileContent);
}
});

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type ReportOptions = {
remove?: boolean;
ci?: boolean;
separator?: string;
noEmptyTranslation?: string;
}

export type SimpleFile = {
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/create-report/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,37 @@ describe('file: create-report/index', () => {
languageFileActions.readLanguageFiles(options.languageFiles),
expectedI18NReport.missingKeys,
Dot,
'',
);
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
});

it('Write missing keys to language files without empty translation', async () => {
options.add = true;
options.noEmptyTranslation = '*';
const writeMissingSpy: jest.SpyInstance<unknown> = jest.spyOn(languageFileActions, 'writeMissingToLanguageFiles');
writeMissingSpy.mockImplementation(() => jest.fn());
await createI18NReport(options);
expect(writeMissingSpy).toHaveBeenCalledWith(
languageFileActions.readLanguageFiles(options.languageFiles),
expectedI18NReport.missingKeys,
Dot,
'*',
);
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
});

it('Write missing keys to language files without empty translation for a single locale', async () => {
options.add = true;
options.noEmptyTranslation = 'en';
const writeMissingSpy: jest.SpyInstance<unknown> = jest.spyOn(languageFileActions, 'writeMissingToLanguageFiles');
writeMissingSpy.mockImplementation(() => jest.fn());
await createI18NReport(options);
expect(writeMissingSpy).toHaveBeenCalledWith(
languageFileActions.readLanguageFiles(options.languageFiles),
expectedI18NReport.missingKeys,
Dot,
'en',
);
expect(consoleInfoSpy).toHaveBeenLastCalledWith('\nThe missing keys have been added to your language files.');
});
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/create-report/language-files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,26 @@ describe('file: create-report/language-files', () => {
expect(writeFileSyncSpy).toHaveBeenCalledTimes(3);
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
});

it('Writes missing keys with no empty translation to language files', () => {
const writeFileSyncSpy = jest.spyOn(fs, 'writeFileSync');
writeFileSyncSpy.mockImplementation(() => jest.fn());
const dotStrSpy = jest.spyOn(dot, 'str');
writeMissingToLanguageFiles(readLanguageFiles(languageFiles), expectedI18NReport.missingKeys, dot, '*');
expect(dotStrSpy).toHaveBeenCalledTimes(78);
expect(writeFileSyncSpy).toHaveBeenCalledTimes(6);
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
});

it('Writes missing keys with no empty translation for single locale to language files', () => {
const writeFileSyncSpy = jest.spyOn(fs, 'writeFileSync');
writeFileSyncSpy.mockImplementation(() => jest.fn());
const dotStrSpy = jest.spyOn(dot, 'str');
writeMissingToLanguageFiles(readLanguageFiles(languageFiles), expectedI18NReport.missingKeys, dot, 'en');
expect(dotStrSpy).toHaveBeenCalledTimes(117);
expect(writeFileSyncSpy).toHaveBeenCalledTimes(9);
expect(writeFileSyncSpy.mock.calls[0][1]).toContain('missing');
});
});

describe('function: removeUnusedFromLanguageFiles', () => {
Expand Down

0 comments on commit f21cb32

Please sign in to comment.