Skip to content

Commit

Permalink
fix: synchronize sources
Browse files Browse the repository at this point in the history
Translation units with manually defined ids can have their source changed.
In order to detect that, the sources are compared on startup and updated accordingly.
  • Loading branch information
kyubisation committed Feb 9, 2021
1 parent d641def commit beab5c7
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
8 changes: 6 additions & 2 deletions server/models/translation-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ export class TranslationTarget {
}

private _calculateDistance(a: TranslationTargetUnit, b: TranslationTargetUnit) {
const sourceA = a.source.replace(/\s+/g, ' ').trim();
const sourceB = b.source.replace(/\s+/g, ' ').trim();
const sourceA = this._normalizeWhitespace(a.source);
const sourceB = this._normalizeWhitespace(b.source);
return levenshtein(sourceA, sourceB);
}

private _normalizeWhitespace(value: string) {
return value.replace(/\s+/g, ' ').trim();
}
}
38 changes: 38 additions & 0 deletions server/persistence/translation-target-registry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,42 @@ describe('TranslationTargetRegistry', () => {
const target = registry.register('de', new Map<string, TranslationTargetUnit>(), baseHref);
expect(target.baseHref).toEqual(baseHref);
});

it('should update stale source with only whitespace change', () => {
const sourceUnit = MOCK_SOURCE.units[0];
const sourceWithWhitespace = sourceUnit.source + ' ';
let unit: TranslationTargetUnit = {
...sourceUnit,
source: sourceWithWhitespace,
target: sourceWithWhitespace,
state: 'translated',
};
expect(unit.source).toEqual(sourceWithWhitespace);
const target = registry.register(
'de',
new Map<string, TranslationTargetUnit>().set(unit.id, unit)
);
unit = target.unitMap.get(unit.id)!;
expect(unit.source).toEqual(sourceUnit.source);
expect(unit.state).toEqual('translated');
});

it('should update stale source and state with textual change', () => {
const sourceUnit = MOCK_SOURCE.units[0];
const sourceWithTextChange = sourceUnit.source + ' test';
let unit: TranslationTargetUnit = {
...sourceUnit,
source: sourceWithTextChange,
target: sourceWithTextChange,
state: 'translated',
};
expect(unit.source).toEqual(sourceWithTextChange);
const target = registry.register(
'de',
new Map<string, TranslationTargetUnit>().set(unit.id, unit)
);
unit = target.unitMap.get(unit.id)!;
expect(unit.source).toEqual(sourceUnit.source);
expect(unit.state).toEqual('initial');
});
});
25 changes: 25 additions & 0 deletions server/persistence/translation-target-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export class TranslationTargetRegistry {
target.changed
.pipe(debounceTime(300))
.subscribe(() => this._persistenceStrategy.update(target));
this._synchronizeSources(target);
this._targets.set(language, target);
return target;
}
Expand All @@ -47,4 +48,28 @@ export class TranslationTargetRegistry {
values(): TranslationTarget[] {
return Array.from(this._targets.values());
}

private _synchronizeSources(target: TranslationTarget) {
let changeRequired = false;
for (const unit of target.units) {
const sourceUnit = target.source.unitMap.get(unit.id)!;
if (unit.source !== sourceUnit.source) {
if (
this._normalizeWhitespace(unit.source) !== this._normalizeWhitespace(sourceUnit.source)
) {
unit.state = 'initial';
}
unit.source = sourceUnit.source;
changeRequired = true;
}
}

if (changeRequired) {
this._persistenceStrategy.update(target);
}
}

private _normalizeWhitespace(value: string) {
return value.replace(/\s+/g, ' ').trim();
}
}

0 comments on commit beab5c7

Please sign in to comment.