diff --git a/src/SIL.Machine/Corpora/ParatextProjectTextUpdaterBase.cs b/src/SIL.Machine/Corpora/ParatextProjectTextUpdaterBase.cs index 1289f3f4c..3445dde68 100644 --- a/src/SIL.Machine/Corpora/ParatextProjectTextUpdaterBase.cs +++ b/src/SIL.Machine/Corpora/ParatextProjectTextUpdaterBase.cs @@ -68,7 +68,7 @@ public string UpdateUsfm( ScrVers rowsVersification = UpdateUsfmParserHandler.GetRowsVersification(rows); ScrVers parseVersification = _settings.Versification; - if (rowsVersification != _settings.Versification) + if (!rowsVersification.IsEquivalentTo(_settings.Versification)) { var converter = new ConvertUsfmVersificationHandler(rowsVersification); UsfmParser.Parse(tokens, converter, _settings.Stylesheet, _settings.Versification); diff --git a/src/SIL.Machine/Corpora/ScrVersExtensions.cs b/src/SIL.Machine/Corpora/ScrVersExtensions.cs index 9fae902d4..620074a68 100644 --- a/src/SIL.Machine/Corpora/ScrVersExtensions.cs +++ b/src/SIL.Machine/Corpora/ScrVersExtensions.cs @@ -1,4 +1,7 @@ +using System; using System.Collections.Generic; +using System.Linq; +using SIL.Extensions; using SIL.Scripture; namespace SIL.Machine.Corpora @@ -58,5 +61,34 @@ public static bool HasCrossBookMappings(this ScrVers scrVers, ScrVers referenceV } return false; } + + public static bool IsEquivalentTo(this ScrVers scrVers, ScrVers other) + { + if (scrVers.Equals(other)) + return true; + + // If all verses in the versifications are 1) equal (accounts for mapping) + // and 2) graphically identical in regard to book, chapter, and verse, then the versifications are equivalent + foreach ( + (VerseRef thisVerse, VerseRef otherVerse) in scrVers + .AllIncludedVerses() + .Concat(new VerseRef()) + .Zip(other.AllIncludedVerses().Concat(new VerseRef())) + ) + { + if ( + !( + thisVerse + .ChangeVersificationWithSegments(ScrVers.Original) + .Equals(otherVerse.ChangeVersificationWithSegments(ScrVers.Original)) + && thisVerse.BBBCCCVVVS == otherVerse.BBBCCCVVVS + ) + ) + { + return false; + } + } + return true; + } } } diff --git a/tests/SIL.Machine.Tests/Corpora/ConvertUsfmVersificationHandlerTests.cs b/tests/SIL.Machine.Tests/Corpora/ConvertUsfmVersificationHandlerTests.cs index 12e48867f..3c9bbe4b5 100644 --- a/tests/SIL.Machine.Tests/Corpora/ConvertUsfmVersificationHandlerTests.cs +++ b/tests/SIL.Machine.Tests/Corpora/ConvertUsfmVersificationHandlerTests.cs @@ -974,24 +974,10 @@ private static void AssertUsfmEquals(string target, string truth) Assert.That(target, Is.Not.Null); string[] targetLines = target.Split('\n'); string[] truthLines = truth.Split('\n'); - // Assert.That(targetLines.Length, Is.EqualTo(truthLines.Length)); + Assert.That(targetLines, Has.Length.EqualTo(truthLines.Length)); for (int i = 0; i < truthLines.Length; i++) { - Assert.That( - targetLines[i].Trim(), - Is.EqualTo(truthLines[i].Trim()), - message: string.Join( - "\n", - [ - "Expected vs. \n\tActual", - .. truthLines - .Zip(targetLines) - .Select(pair => - $"\n{pair.First}\n\t{(pair.First.Trim() != pair.Second.Trim() ? "***" : "")}{pair.Second}" - ), - ] - ) - ); + Assert.That(targetLines[i].Trim(), Is.EqualTo(truthLines[i].Trim()), message: $"Line {i}"); } } } diff --git a/tests/SIL.Machine.Tests/Corpora/ScrVersExtensionsTests.cs b/tests/SIL.Machine.Tests/Corpora/ScrVersExtensionsTests.cs index ea5caba92..54644b04d 100644 --- a/tests/SIL.Machine.Tests/Corpora/ScrVersExtensionsTests.cs +++ b/tests/SIL.Machine.Tests/Corpora/ScrVersExtensionsTests.cs @@ -43,4 +43,68 @@ public void HasCrossBookMappings() Assert.That(ScrVers.Vulgate.HasCrossBookMappings(ScrVers.English)); } } + + [Test] + public void IsEquivalentTo() + { + ScrVers customVrs1; + using (CorporaUtils.VersificationLock.Lock()) + { + string src = "MAT 1:2 = MAT 1:1\nMAT 1:1 = MAT 1:2\n-EXO 25:6\n-EXO 28:23"; + using var reader = new StringReader(src); + customVrs1 = Versification.Table.Implementation.Load(reader, "vers.txt", ScrVers.English, "custom1"); + Versification.Table.Implementation.RemoveAllUnknownVersifications(); + } + + ScrVers customVrs2; + using (CorporaUtils.VersificationLock.Lock()) + { + string src = "MAT 1:1 = MAT 1:2\nMAT 1:2 = MAT 1:1\n-EXO 28:23\n-EXO 25:6"; + using var reader = new StringReader(src); + customVrs2 = Versification.Table.Implementation.Load(reader, "vers.txt", ScrVers.English, "custom2"); + Versification.Table.Implementation.RemoveAllUnknownVersifications(); + } + + ScrVers customVrs3; + using (CorporaUtils.VersificationLock.Lock()) + { + string src = + "MAT 1:1 = MAT 1:2\n# This is a comment\nMAT 1:2 = MAT 1:1\nMAT 1:2 = MAT 1:1\n-EXO 25:6\n-EXO 28:23"; + using var reader = new StringReader(src); + customVrs3 = Versification.Table.Implementation.Load(reader, "vers.txt", ScrVers.English, "custom3"); + Versification.Table.Implementation.RemoveAllUnknownVersifications(); + } + + ScrVers customVrs4; + using (CorporaUtils.VersificationLock.Lock()) + { + string src = "&MAT 1:2-3 = MAT 1:2\nMAT 1:4 = MAT 1:3\n-EXO 25:6\n-EXO 28:23"; + using var reader = new StringReader(src); + customVrs4 = Versification.Table.Implementation.Load(reader, "vers.txt", ScrVers.English, "custom4"); + Versification.Table.Implementation.RemoveAllUnknownVersifications(); + } + + ScrVers customVrs5; + using (CorporaUtils.VersificationLock.Lock()) + { + string src = ""; + using var reader = new StringReader(src); + customVrs5 = Versification.Table.Implementation.Load(reader, "vers.txt", ScrVers.English, "custom5"); + Versification.Table.Implementation.RemoveAllUnknownVersifications(); + } + + using (Assert.EnterMultipleScope()) + { + Assert.That(ScrVers.English.IsEquivalentTo(ScrVers.English)); + Assert.That(!ScrVers.English.IsEquivalentTo(ScrVers.Original)); + Assert.That(ScrVers.Original.IsEquivalentTo(ScrVers.Original)); + Assert.That(!ScrVers.Original.IsEquivalentTo(ScrVers.English)); + Assert.That(customVrs1.IsEquivalentTo(customVrs1)); + Assert.That(customVrs1.IsEquivalentTo(customVrs2)); + Assert.That(customVrs1.IsEquivalentTo(customVrs3)); + Assert.That(!customVrs1.IsEquivalentTo(customVrs4)); + Assert.That(!customVrs1.IsEquivalentTo(customVrs5)); + Assert.That(customVrs5.IsEquivalentTo(ScrVers.English)); + } + } }