From 554447fdf0f18402c083f6e808f49a5eec30f6f0 Mon Sep 17 00:00:00 2001 From: "Eli C. Lowry" <83078660+Enkidu93@users.noreply.github.com> Date: Tue, 16 Jul 2024 13:39:06 -0400 Subject: [PATCH 1/2] Check for empty string (#226) --- src/SIL.Machine/Scripture/ScriptureRangeParser.cs | 5 +++++ .../SIL.Machine.Tests/Scripture/ScriptureRangeParserTests.cs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/SIL.Machine/Scripture/ScriptureRangeParser.cs b/src/SIL.Machine/Scripture/ScriptureRangeParser.cs index bad5211e0..ddd40ca50 100644 --- a/src/SIL.Machine/Scripture/ScriptureRangeParser.cs +++ b/src/SIL.Machine/Scripture/ScriptureRangeParser.cs @@ -151,6 +151,11 @@ public Dictionary> GetChapters(string chapterSelections) Dictionary> chaptersPerBook = new Dictionary>(); chapterSelections = chapterSelections.Trim(); + if (chapterSelections.Length == 0) + { + return chaptersPerBook; + } + char delimiter = ';'; if (chapterSelections.Contains(';')) { diff --git a/tests/SIL.Machine.Tests/Scripture/ScriptureRangeParserTests.cs b/tests/SIL.Machine.Tests/Scripture/ScriptureRangeParserTests.cs index efc597b01..13da8cabb 100644 --- a/tests/SIL.Machine.Tests/Scripture/ScriptureRangeParserTests.cs +++ b/tests/SIL.Machine.Tests/Scripture/ScriptureRangeParserTests.cs @@ -177,6 +177,7 @@ public static IEnumerable GetCases() new Dictionary> { { "JHN", new List() } }, false ); + yield return new TestCaseData("", new Dictionary>(), false); //*Throw exceptions yield return new TestCaseData("MAT3-1", new Dictionary>(), true); @@ -185,7 +186,6 @@ public static IEnumerable GetCases() yield return new TestCaseData("MAT0-10", new Dictionary>(), true); yield return new TestCaseData("MAT-FLUM", new Dictionary>(), true); yield return new TestCaseData("-MAT-FLUM", new Dictionary>(), true); - yield return new TestCaseData("", new Dictionary>(), true); yield return new TestCaseData("ABC", new Dictionary>(), true); yield return new TestCaseData("MAT-ABC", new Dictionary>(), true); yield return new TestCaseData("NT;-ABC-LUK", new Dictionary>(), true); From 3911dd670c34a54ea3ddaea0e5859b4a32d5a12d Mon Sep 17 00:00:00 2001 From: "Eli C. Lowry" <83078660+Enkidu93@users.noreply.github.com> Date: Tue, 16 Jul 2024 15:08:09 -0400 Subject: [PATCH 2/2] Extend manual test to process multiple projects including zipped projects (#227) * Extend manual test to process multiple projects including zipped projects * Put ignore back * Add comment with testing instructions --------- Co-authored-by: John Lambert --- .../Corpora/UsfmManualTests.cs | 112 +++++++++++++----- 1 file changed, 82 insertions(+), 30 deletions(-) diff --git a/tests/SIL.Machine.Tests/Corpora/UsfmManualTests.cs b/tests/SIL.Machine.Tests/Corpora/UsfmManualTests.cs index f0b636cfb..6d81ae0b2 100644 --- a/tests/SIL.Machine.Tests/Corpora/UsfmManualTests.cs +++ b/tests/SIL.Machine.Tests/Corpora/UsfmManualTests.cs @@ -1,4 +1,5 @@ -using System.Text.Json; +using System.IO.Compression; +using System.Text.Json; using NUnit.Framework; namespace SIL.Machine.Corpora; @@ -66,40 +67,91 @@ public record PretranslationDto [Test] [Ignore("This is for manual testing only. Remove this tag to run the test.")] + /* + In order to run this test on specific projects, place the Paratext projects or Paratext project zips in the Corpora/TestData/project/ folder. + If only testing one project, you can instead place the project in the Corpora/TestData/ folder and rename it to "project" + */ public async Task CreateUsfmFile() { - FileParatextProjectSettingsParser parser = new(ParatextProjectPath); - ParatextProjectSettings settings = parser.Parse(); + async Task GetUsfmAsync(string projectPath) + { + ParatextProjectSettingsParserBase parser; + ZipArchive? projectArchive = null; + try + { + projectArchive = ZipFile.Open(projectPath, ZipArchiveMode.Read); + parser = new ZipParatextProjectSettingsParser(projectArchive); + } + catch (UnauthorizedAccessException) + { + parser = new FileParatextProjectSettingsParser(projectPath); + } + ParatextProjectSettings settings = parser.Parse(); - // Read text from pretranslations file - using Stream pretranslationStream = File.OpenRead(PretranslationPath); - (IReadOnlyList, string)[] pretranslations = await JsonSerializer - .DeserializeAsyncEnumerable( - pretranslationStream, - new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase } - ) - .Select(p => - ( - (IReadOnlyList)( - p?.Refs.Select(r => ScriptureRef.Parse(r, settings.Versification).ToRelaxed()).ToArray() ?? [] - ), - p?.Translation ?? "" + // Read text from pretranslations file + using Stream pretranslationStream = File.OpenRead(PretranslationPath); + (IReadOnlyList, string)[] pretranslations = await JsonSerializer + .DeserializeAsyncEnumerable( + pretranslationStream, + new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase } ) - ) - .ToArrayAsync(); - - foreach ( - string sfmFileName in Directory.EnumerateFiles( - ParatextProjectPath, - $"{settings.FileNamePrefix}*{settings.FileNameSuffix}" - ) - ) + .Select(p => + ( + (IReadOnlyList)( + p?.Refs.Select(r => ScriptureRef.Parse(r, settings.Versification).ToRelaxed()).ToArray() + ?? [] + ), + p?.Translation ?? "" + ) + ) + .ToArrayAsync(); + List sfmTexts = []; + if (projectArchive == null) + { + sfmTexts = ( + await Task.WhenAll( + Directory + .EnumerateFiles(projectPath, $"{settings.FileNamePrefix}*{settings.FileNameSuffix}") + .Select(async sfmFileName => await File.ReadAllTextAsync(sfmFileName)) + ) + ).ToList(); + } + else + { + sfmTexts = projectArchive + .Entries.Where(e => + e.Name.StartsWith(settings.FileNamePrefix) && e.Name.EndsWith(settings.FileNameSuffix) + ) + .Select(e => + { + string contents; + using (var sr = new StreamReader(e.Open())) + { + contents = sr.ReadToEnd(); + } + return contents; + }) + .ToList(); + } + foreach (string usfm in sfmTexts) + { + var updater = new UsfmTextUpdater(pretranslations, stripAllText: true, preferExistingText: true); + UsfmParser.Parse(usfm, updater, settings.Stylesheet, settings.Versification); + string newUsfm = updater.GetUsfm(settings.Stylesheet); + Assert.That(newUsfm, Is.Not.Null); + } + } + if (!File.Exists(Path.Combine(ParatextProjectPath, "Settings.xml"))) { - var updater = new UsfmTextUpdater(pretranslations, stripAllText: true, preferExistingText: true); - string usfm = await File.ReadAllTextAsync(sfmFileName); - UsfmParser.Parse(usfm, updater, settings.Stylesheet, settings.Versification); - string newUsfm = updater.GetUsfm(settings.Stylesheet); - Assert.That(newUsfm, Is.Not.Null); + Assert.Multiple(() => + { + foreach (string subdir in Directory.EnumerateFiles(ParatextProjectPath)) + Assert.DoesNotThrowAsync(async () => await GetUsfmAsync(subdir), $"Failed to parse {subdir}"); + }); + } + else + { + await GetUsfmAsync(ParatextProjectPath); } } }