Skip to content

Fix incorrect singularization for words ending with -ves (arrives/drives/curves/behaves) and add tests#1704

Open
jesi318 wants to merge 4 commits into
Humanizr:mainfrom
jesi318:ve_plural_fix
Open

Fix incorrect singularization for words ending with -ves (arrives/drives/curves/behaves) and add tests#1704
jesi318 wants to merge 4 commits into
Humanizr:mainfrom
jesi318:ve_plural_fix

Conversation

@jesi318

@jesi318 jesi318 commented Apr 3, 2026

Copy link
Copy Markdown

Here is a checklist you should tick through before submitting a pull request:

  • Implementation is clean
  • Code adheres to the existing coding standards; e.g. no curlies for one-line blocks, no redundant empty lines between methods or code blocks, spaces rather than tabs, etc.
  • No Code Analysis warnings
  • There is proper unit test coverage
  • If the code is copied from StackOverflow (or a blog or OSS) full disclosure is included. That includes required license files and/or file headers explaining where the code came from with proper attribution
  • There are very few or no comments (because comments shouldn't be needed if you write clean code)
  • Xml documentation is added/updated for the addition/change
  • Your PR is (re)based on top of the latest commits from the main branch (more info below)
  • Link to the issue(s) you're fixing from your PR description. Use fixes #<the issue number>
  • Readme is updated if you change an existing feature or add a new one
  • Run either build.cmd or build.ps1 and ensure there are no test failures

Summary

Fixes a bug where arrives.Singularize() → arrife (and similar: drives → drife, curves → curf, behaves → behafe etc) by adjusting the singularization rule set and ordering.
Adds unit tests that assert correct singular forms for common -ves cases and true -fe exceptions.

Why this change was made/ Root Cause
_default.AddSingular("([^f])ves$", "$1fe"); is a greedy rule which matched other strings mentioned in the issue above

What I changed

Reworked -ves singular rules in Vocabularies.Defaultso exceptions for nouns that map to -f/-fe (knife→knives, wife→wives, leaf→leaves, etc.) are handled before the general catch-all that converts -ves → -ve (verbs/adjectives like arrive/drive/curve/behave).
Replaced overly-generic pattern(s) that caused verbs to be mis-singularized with a combination of:

  • Explicit stem-based rules for known -f/-fe nouns, and

  • A general (.+)ves$ -> $1ve catch-all for remaining -ves cases.

  • Corrected the incorrect test yield return ["safe", "saves"]; to yield return ["safe", "safes"]; (which makes it grammattically correct according to me) and added a rule for it since it was an edge case . Please let me know if I'm wrong.

  • Added a focused unit test method Singularize_Ves_EdgeCases in InflectorTests.cs

  • ([lr])ves$ → $1f was separated because this keeps this broad heuristic distinct from explicit stem-based rules, preventing it from interfering with more precise matches and making rule behavior easier to control and debug.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 864f993ce9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/Humanizer/Inflections/Vocabularies.cs Outdated
Copilot AI review requested due to automatic review settings June 12, 2026 06:48
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b6b6fd04-9654-46c5-8c79-11764b64282b

📥 Commits

Reviewing files that changed from the base of the PR and between f9292aa and 4117afb.

📒 Files selected for processing (2)
  • src/Humanizer/Inflections/Vocabularies.cs
  • tests/Humanizer.Tests/InflectorTests.cs

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Fixed pluralization and singularization of English words ending in "-ves" (e.g., knives↔knife, wives↔wife, leaves↔leaf, arrives↔arrive)
    • Corrected plural form of "safe" from "saves" to "safes"
    • Improved handling of irregular word forms including curve, valve, and safe

Walkthrough

This PR fixes incorrect singularization of words ending in "-ves" by reordering regex rules in the default English vocabulary, adding specific irregular mappings for curve, valve, and safe, and introducing comprehensive test coverage for these edge cases.

Changes

Singularization Rule Fix and Test Coverage

Layer / File(s) Summary
Singularization rule updates and irregular mappings
src/Humanizer/Inflections/Vocabularies.cs
The singularization rule for "-ves" words is fixed by inserting a general catch-all rule and removing the problematic pattern. Specific "-ves" rules are reordered (affecting words ending in "ves", "lves", "ves" from "f", "ves" from "fe"). Irregular mappings for curve, valve, and safe are added to the default vocabulary.
Test coverage for singularization edge cases
tests/Humanizer.Tests/InflectorTests.cs
A new theory test Singularize_Ves_EdgeCases with InlineData cases validates that -ves plurals singularize correctly (arrives→arrive, knives→knife, wives→wife, leaves→leaf). Test data for safe pluralization is corrected from saves to safes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A fix for the "-ves" that would go awry,
Like "arrives" turning strange with a sigh—
Now reordered rules ring true and clear,
With tests to ensure singulars appear!
The linguists hop forward, no more affray!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main fix: correcting singularization for -ves words and adding tests.
Description check ✅ Passed The description clearly explains the bug, root cause, and changes made to fix the singularization issue.
Linked Issues check ✅ Passed The PR directly addresses issue #1674 by fixing the singularization bug where 'arrives' was incorrectly singularized to 'arrife'.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the -ves singularization rules and adding related unit tests; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI 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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates Humanizer’s inflection rules and tests to improve singularization/pluralization behavior for *ves word endings and correct a test data issue for “safe”.

Changes:

  • Added test coverage for *ves singularization edge cases (e.g., “arrives” → “arrive”, “knives” → “knife”)
  • Updated default singularization rules for *ves endings and added irregular entries for “curve/curves” and “safe/safes”
  • Corrected plural test data from “safe/saves” to “safe/safes”

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.

File Description
tests/Humanizer.Tests/InflectorTests.cs Adds *ves singularization edge-case tests and fixes “safe” plural test data
src/Humanizer/Inflections/Vocabularies.cs Adjusts *ves singularization rules and adds irregular vocabulary entries

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +46 to +49
_default.AddSingular("(.+)ves$", "$1ve");
_default.AddSingular("(hive)s$", "$1");
_default.AddSingular("(tive)s$", "$1");
_default.AddSingular("([lr]|hoo|lea|loa|thie)ves$", "$1f");
_default.AddSingular("([lr])ves$", "$1f");
_default.AddIrregular("tie", "ties", matchEnding: false);
_default.AddIrregular("lens", "lenses");
_default.AddIrregular("clove", "cloves");
_default.AddIrregular("curve", "curves");
_default.AddIrregular("clove", "cloves");
_default.AddIrregular("curve", "curves");
_default.AddIrregular("valve", "valves");
_default.AddIrregular("safe", "safes");
[InlineData("scarves", "scarf")]
[InlineData("hooves", "hoof")]
[InlineData("thieves", "thief")]
public void Singularize_Ves_EdgeCases(string plural, string expected) =>
Comment on lines +46 to +49
_default.AddSingular("(.+)ves$", "$1ve");
_default.AddSingular("(hive)s$", "$1");
_default.AddSingular("(tive)s$", "$1");
_default.AddSingular("([lr]|hoo|lea|loa|thie)ves$", "$1f");
_default.AddSingular("([lr])ves$", "$1f");
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.

2 participants