Skip to content

Add TryGetChapters to ScriptureRangeParser - #497

Merged
pmachapman merged 2 commits into
masterfrom
scripture_range_parser_updates
Sep 28, 2026
Merged

pmachapman merged 2 commits into
masterfrom
scripture_range_parser_updates

Conversation

@pmachapman

@pmachapman pmachapman commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #486

I noticed that the ScriptureRangeParser was not in a namespace, so set the namespace to SIL.Machine.Scripture. If it was not an oversight, I can revert it to remain in the SIL.Machine namespace.

I also took the opportunity to update the unit tests to use new .Net 10 language features.


This change is Reviewable

@codecov-commenter

codecov-commenter commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.93939% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.08%. Comparing base (7109531) to head (a9d9f5a).

Files with missing lines Patch % Lines
src/SIL.Machine/Scripture/ScriptureRangeParser.cs 94.93% 5 Missing and 3 partials ⚠️
src/SIL.Machine/Corpora/UsxFileTextCorpus.cs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master     #497   +/-   ##
=======================================
  Coverage   74.07%   74.08%           
=======================================
  Files         456      456           
  Lines       38164    38178   +14     
  Branches     5228     5229    +1     
=======================================
+ Hits        28270    28283   +13     
- Misses       8734     8735    +1     
  Partials     1160     1160           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Enkidu93 Enkidu93 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@Enkidu93 reviewed 5 files and all commit messages, and made 1 comment.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on ddaspit).

@ddaspit ddaspit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two findings from a local review: one blocking, one minor. Built the branch (0 warnings) and ran the 86 existing ScriptureRangeParser tests (all pass); the empty-section behavior below was confirmed with a throwaway test against this branch.

chapters = GetChapters(chapterSelections);
return true;
}
catch (ArgumentException)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical — catching only ArgumentException lets an empty section escape as an unhandled InvalidOperationException from section.Last() (line 53), so TryGetChapters throws instead of returning false.

Confirmed on a local build of this branch: "MAT;", "MAT;;MRK", ";", and " ; " all throw. That is the input class the Try* overload exists to absorb.

Either skip empty sections in GetChapters, or throw ArgumentException for them so this catch covers them.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I updated the tests to accept an exception type to support this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to explicitly throw an ArgumentException from ParseSection rather than catch the InvalidOperationException from Last(). This would make it more consistent.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Sounds great.

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor — versification sits before the out parameter, so it cannot carry the ScrVers versification = null default that static GetChapters has just above; every caller must pass null explicitly.

Moving it after out chapters, or adding a two-argument overload, restores parity with GetChapters.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to create an overload rather than move it after the out parameter.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overload:

        public static bool TryGetChapters(
            string chapterSelections,
            out Dictionary<string, List<int>> chapters
        ) => new ScriptureRangeParser().TryGetChapters(chapterSelections, out chapters);

gives the error:

CS0111 Type 'ScriptureRangeParser' already defines a member called 'TryGetChapters' with the same parameter types

as it conflicts with:

public bool TryGetChapters(string chapterSelections, out Dictionary<string, List<int>> chapters)

That is why my original version was just:

        public static bool TryGetChapters(
            string chapterSelections,
            ScrVers versification,
            out Dictionary<string, List<int>> chapters
        ) => new ScriptureRangeParser(versification).TryGetChapters(chapterSelections, out chapters);

From what I can see our two options are having the optional paramter after the out parameter, or make versification non-optional for the static member.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed the instance method. Never mind. You can change it back to the original version with the required versification.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@pmachapman
pmachapman force-pushed the scripture_range_parser_updates branch from 170f122 to 99cb98b Compare September 23, 2026 22:04
@pmachapman
pmachapman requested a review from ddaspit September 23, 2026 22:05

@pmachapman pmachapman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmachapman made 2 comments.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on ddaspit).

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

chapters = GetChapters(chapterSelections);
return true;
}
catch (ArgumentException)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. I updated the tests to accept an exception type to support this.

@ddaspit ddaspit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ddaspit reviewed 5 files and all commit messages, made 1 comment, and resolved 1 discussion.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on pmachapman).

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to create an overload rather than move it after the out parameter.

@pmachapman
pmachapman requested a review from ddaspit September 27, 2026 19:45

@pmachapman pmachapman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmachapman made 1 comment.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on ddaspit).

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overload:

        public static bool TryGetChapters(
            string chapterSelections,
            out Dictionary<string, List<int>> chapters
        ) => new ScriptureRangeParser().TryGetChapters(chapterSelections, out chapters);

gives the error:

CS0111 Type 'ScriptureRangeParser' already defines a member called 'TryGetChapters' with the same parameter types

as it conflicts with:

public bool TryGetChapters(string chapterSelections, out Dictionary<string, List<int>> chapters)

That is why my original version was just:

        public static bool TryGetChapters(
            string chapterSelections,
            ScrVers versification,
            out Dictionary<string, List<int>> chapters
        ) => new ScriptureRangeParser(versification).TryGetChapters(chapterSelections, out chapters);

From what I can see our two options are having the optional paramter after the out parameter, or make versification non-optional for the static member.

@ddaspit ddaspit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ddaspit made 2 comments.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on pmachapman).

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I missed the instance method. Never mind. You can change it back to the original version with the required versification.

chapters = GetChapters(chapterSelections);
return true;
}
catch (ArgumentException)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to explicitly throw an ArgumentException from ParseSection rather than catch the InvalidOperationException from Last(). This would make it more consistent.

@pmachapman
pmachapman force-pushed the scripture_range_parser_updates branch from 99cb98b to a9d9f5a Compare September 28, 2026 18:30
@pmachapman
pmachapman requested a review from ddaspit September 28, 2026 18:30

@pmachapman pmachapman left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pmachapman made 2 comments.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on ddaspit).

if (char.IsDigit(section.Last()) && section.Length > 3)
public static bool TryGetChapters(
string chapterSelections,
ScrVers versification,

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

chapters = GetChapters(chapterSelections);
return true;
}
catch (ArgumentException)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Sounds great.

@ddaspit ddaspit left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

@ddaspit reviewed 2 files and all commit messages, made 1 comment, and resolved 2 discussions.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on pmachapman).

@pmachapman
pmachapman merged commit 066cf1e into master Sep 28, 2026
6 checks passed
@pmachapman
pmachapman deleted the scripture_range_parser_updates branch September 28, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a TryGetChapters function to ScriptureRangeParser

4 participants