diff --git a/CHANGELOG.md b/CHANGELOG.md index 72fa1e1..6bc8d37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - [L10NSharp.Windows.Forms] Restored project-local Resources support for `FallbackLanguagesDlgBase` button images (`Move`, `Move_up`, and `Move_down`). - [L10NSharp.Windows.Forms] Corrected resource manager base name to `L10NSharp.Windows.Forms.Properties.Resources`. - [L10NSharp.Windows.Forms.Tests] Corrected resource manager base name to `L10NSharp.Windows.Forms.Tests.Properties.Resources`. +- [L10NSharp] Fixed `ExtractXliff` accumulating duplicate "Not found in static scan" notes on successive runs; the note is now replaced rather than appended, and removed when the string is subsequently found. (#113) - [L10NSharp] Fixed `LocalizationManager.GetString` silently falling back to English when called with a one-shot `IEnumerable` for `preferredLanguageIds`; the sequence is now materialized before use. (#139) ### Removed diff --git a/src/L10NSharp.Tests/XLiffLocalizationManagerTests.cs b/src/L10NSharp.Tests/XLiffLocalizationManagerTests.cs index 72a02f0..c752881 100644 --- a/src/L10NSharp.Tests/XLiffLocalizationManagerTests.cs +++ b/src/L10NSharp.Tests/XLiffLocalizationManagerTests.cs @@ -239,6 +239,42 @@ public void MergeXliffDocuments_WorksAsExpected() }, true); } + [Test] + public void MergeXliffDocuments_RunTwice_DoesNotDuplicateNotFoundNotes() + { + var oldDoc = CreateTestDocument(); + var newDoc = CreateTestDocument(); + AdjustDocumentForTestingMerge(newDoc); + + var mergedDoc = XliffLocalizationManager.MergeXliffDocuments(newDoc, oldDoc, true); + var tuAfterFirstMerge = mergedDoc.GetTransUnitForId("That.test"); + Assert.IsNotNull(tuAfterFirstMerge); + var expectedNoteCount = tuAfterFirstMerge.Notes.Count; + + var mergedDoc2 = XliffLocalizationManager.MergeXliffDocuments(newDoc, mergedDoc, true); + var tuAfterSecondMerge = mergedDoc2.GetTransUnitForId("That.test"); + Assert.IsNotNull(tuAfterSecondMerge); + Assert.That(expectedNoteCount, Is.EqualTo(tuAfterSecondMerge.Notes.Count)); + } + + [Test] + public void MergeXliffDocuments_StringFoundAfterBeingMissing_RemovesNotFoundNote() + { + var oldDoc = CreateTestDocument(); + var newDoc = CreateTestDocument(); + AdjustDocumentForTestingMerge(newDoc); + + var mergedDoc = XliffLocalizationManager.MergeXliffDocuments(newDoc, oldDoc, true); + + // newDoc2 is NOT adjusted, so "That.test" IS present in it + var newDoc2 = CreateTestDocument(); + var mergedDoc2 = XliffLocalizationManager.MergeXliffDocuments(newDoc2, mergedDoc, true); + + var tu = mergedDoc2.GetTransUnitForId("That.test"); + Assert.IsNotNull(tu); + Assert.That(tu.Notes.Any(n => n.Text.Contains("Not found")), Is.False); + } + private void CheckMergedTransUnit(XLiffTransUnit tu, string sourceText, string[] notes, bool isDynamic) { Assert.IsNotNull(tu); diff --git a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs index fcd284c..9fc5b55 100644 --- a/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs +++ b/src/L10NSharp/XLiffUtils/XliffLocalizationManager.cs @@ -539,7 +539,7 @@ public virtual void HandleUiLanguageChange() { UiLanguageChanged?.Invoke(this, EventArgs.Empty); } - + /// ------------------------------------------------------------------------------------ public override string ToString() { @@ -608,6 +608,9 @@ internal static XLiffDocument MergeXliffDocuments(XLiffDocument xliffNew, XLiffD { foreach (var note in tuOld.Notes) { + // Skip "Not found[...]" notes — the string IS found in this run. + if (note.Text.StartsWith("Not found")) + continue; bool haveAlready = false; foreach (var newNote in tu.Notes) { @@ -655,13 +658,17 @@ internal static XLiffDocument MergeXliffDocuments(XLiffDocument xliffNew, XLiffD { ++missingDynamicStringCount; missingDynamicStringIds.Add(tu.Id); - if (newDynamicCount > 0) // note only if attempt made to collect dynamic strings + if (newDynamicCount > 0) // note only if attempt made to collect dynamic strings + { + tu.Notes.RemoveAll(n => n.Text.StartsWith("Not found")); tu.AddNote("en", $"Not found when running compiled program (version {xliffNew.File.ProductVersion})"); + } } else { ++missingStringCount; missingStringIds.Add(tu.Id); + tu.Notes.RemoveAll(n => n.Text.StartsWith("Not found")); tu.AddNote("en", $"Not found in static scan of compiled code (version {xliffNew.File.ProductVersion})"); } }