From b98b23805381972824ff7646b5cfee5420529bd9 Mon Sep 17 00:00:00 2001 From: Martin Roob Date: Sat, 6 Apr 2019 17:03:08 +0200 Subject: [PATCH] closes #128: State is set back to translated even if source did not change --- .../src/xliffmerge/xlf12-merge.spec.ts | 28 +++++++++++++++++++ .../xliffmerge/src/xliffmerge/xliff-merge.ts | 25 +++++++++++++---- .../test/testdata/i18n/issue128master.xlf | 16 +++++++++++ .../test/testdata/i18n/issue128translated.xlf | 18 ++++++++++++ 4 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 projects/xliffmerge/test/testdata/i18n/issue128master.xlf create mode 100644 projects/xliffmerge/test/testdata/i18n/issue128translated.xlf diff --git a/projects/xliffmerge/src/xliffmerge/xlf12-merge.spec.ts b/projects/xliffmerge/src/xliffmerge/xlf12-merge.spec.ts index feb5cf1..8421cb0 100644 --- a/projects/xliffmerge/src/xliffmerge/xlf12-merge.spec.ts +++ b/projects/xliffmerge/src/xliffmerge/xlf12-merge.spec.ts @@ -779,6 +779,34 @@ describe('XliffMerge XLIFF 1.2 format tests', () => { done(); }); + it('should not change translation state when source is unchanged but has different line ending (#128)', (done) => { + FileUtil.copy(SRCDIR + 'issue128master.xlf', MASTER); + const langfileName = WORKDIR + 'messages.en.xlf'; + FileUtil.copy(SRCDIR + 'issue128translated.xlf', langfileName); + const originalContent = FileUtil.read(langfileName, 'UTF-8'); + const contentWithoutCRLF = originalContent.replace(/[\n\r]/g, ''); + expect(originalContent).not.toBe(contentWithoutCRLF); + FileUtil.replaceContent(langfileName, contentWithoutCRLF, 'UTF-8'); + const ws: WriterToString = new WriterToString(); + const commandOut = new CommandOutput(ws); + const profileContent: IConfigFile = { + xliffmergeOptions: { + defaultLanguage: 'de', + srcDir: WORKDIR, + genDir: WORKDIR, + i18nFile: MASTERFILE, + beautifyOutput: false + } + }; + const xliffMergeCmd = XliffMerge.createFromOptions(commandOut, {languages: ['de', 'en']}, profileContent); + xliffMergeCmd.run(); + expect(ws.writtenData()).not.toContain('ERROR'); + const langFileEnglish: ITranslationMessagesFile = readXliff(xliffMergeCmd.generatedI18nFile('en')); + const tu: ITransUnit = langFileEnglish.transUnitWithId('issue128'); + expect(tu.targetState()).toBe(STATE_FINAL); + done(); + }); + describe('autotranslate via google translate', () => { let apikey: string; diff --git a/projects/xliffmerge/src/xliffmerge/xliff-merge.ts b/projects/xliffmerge/src/xliffmerge/xliff-merge.ts index aea0ea3..bbcf513 100644 --- a/projects/xliffmerge/src/xliffmerge/xliff-merge.ts +++ b/projects/xliffmerge/src/xliffmerge/xliff-merge.ts @@ -24,9 +24,9 @@ import {AutoTranslateSummaryReport} from '../autotranslate/auto-translate-summar export class XliffMerge { - private commandOutput: CommandOutput; + private readonly commandOutput: CommandOutput; - private options: ProgramOptions; + private readonly options: ProgramOptions; private parameters: XliffMergeParameters; @@ -309,7 +309,7 @@ export class XliffMerge { const languageSpecificMessagesFile: ITranslationMessagesFile = this.master.createTranslationFileForLang(lang, languageXliffFilePath, isDefaultLang, this.parameters.useSourceAsTarget()); return this.autoTranslate(this.master.sourceLanguage(), lang, languageSpecificMessagesFile).pipe( - map((summary) => { + map((/* summary */) => { // write it to file TranslationMessagesFileReader.save(languageSpecificMessagesFile, this.parameters.beautifyOutput()); this.commandOutput.info('created new file "%s" for target-language="%s"', languageXliffFilePath, lang); @@ -375,7 +375,7 @@ export class XliffMerge { } else { // check for changed source content and change it if needed // (can only happen if ID is explicitely set, otherwise ID would change if source content is changed. - if (transUnit.supportsSetSourceContent() && masterTransUnit.sourceContent() !== transUnit.sourceContent()) { + if (transUnit.supportsSetSourceContent() && !this.areSourcesNearlyEqual(masterTransUnit, transUnit)) { transUnit.setSourceContent(masterTransUnit.sourceContent()); if (isDefaultLang) { // #81 changed source must be copied to target for default lang @@ -479,10 +479,9 @@ export class XliffMerge { languageSpecificMessagesFile: ITranslationMessagesFile, lastProcessedUnit: ITransUnit): ITransUnit { - const masterSourceString = masterTransUnit.sourceContentNormalized().asDisplayString(NORMALIZATION_FORMAT_DEFAULT).trim(); let changedTransUnit: ITransUnit = null; languageSpecificMessagesFile.forEachTransUnit((languageTransUnit) => { - if (languageTransUnit.sourceContentNormalized().asDisplayString(NORMALIZATION_FORMAT_DEFAULT).trim() === masterSourceString) { + if (this.areSourcesNearlyEqual(languageTransUnit, masterTransUnit)) { changedTransUnit = languageTransUnit; } }); @@ -502,6 +501,20 @@ export class XliffMerge { return mergedTransUnit; } + /** + * test wether the sources of 2 trans units are equal ignoring white spaces. + * @param tu1 tu1 + * @param tu2 tu2 + */ + private areSourcesNearlyEqual(tu1: ITransUnit, tu2: ITransUnit): boolean { + if ((tu1 && !tu2) || (tu2 && !tu1)) { + return false; + } + const s1Normalized = tu1.sourceContentNormalized().asDisplayString(NORMALIZATION_FORMAT_DEFAULT).trim(); + const s2Normalized = tu2.sourceContentNormalized().asDisplayString(NORMALIZATION_FORMAT_DEFAULT).trim(); + return s1Normalized === s2Normalized; + } + private areSourceReferencesEqual( ref1: {sourcefile: string; linenumber: number; }[], ref2: {sourcefile: string; linenumber: number; }[]): boolean { diff --git a/projects/xliffmerge/test/testdata/i18n/issue128master.xlf b/projects/xliffmerge/test/testdata/i18n/issue128master.xlf new file mode 100644 index 0000000..3b15775 --- /dev/null +++ b/projects/xliffmerge/test/testdata/i18n/issue128master.xlf @@ -0,0 +1,16 @@ + + + + + + + + Ein CR-LF-Problem + + awesome.component.html + 2 + + + + + diff --git a/projects/xliffmerge/test/testdata/i18n/issue128translated.xlf b/projects/xliffmerge/test/testdata/i18n/issue128translated.xlf new file mode 100644 index 0000000..8071731 --- /dev/null +++ b/projects/xliffmerge/test/testdata/i18n/issue128translated.xlf @@ -0,0 +1,18 @@ + + + + + + + + Ein CR-LF-Problem + + A CR-LF problem + + awesome.component.html + 2 + + + + +