Skip to content

fix(titleCase): extra spaces when input already contains spaces#122

Open
guoyangzhen wants to merge 1 commit intounjs:mainfrom
guoyangzhen:fix/titleCase-extra-spaces
Open

fix(titleCase): extra spaces when input already contains spaces#122
guoyangzhen wants to merge 1 commit intounjs:mainfrom
guoyangzhen:fix/titleCase-extra-spaces

Conversation

@guoyangzhen
Copy link
Copy Markdown

@guoyangzhen guoyangzhen commented Mar 30, 2026

Fixes #96

Problem

titleCase('Hello World') produces 'Hello World' (double space). Calling titleCase(titleCase('hello')) also produces double spaces because splitByCase does not recognize space as a separator.

Root cause: splitByCase uses STR_SPLITTERS = ['-', '_', '/', '.'] but does not include space. When processing 'Hello World', the falling-edge detection at the space character (uppercase W → space) splits the string incorrectly, attaching the space to the preceding token: ['Hello ', 'World'].

Fix

Added space to STR_SPLITTERS. Now splitByCase('Hello World') correctly returns ['Hello', 'World'], and titleCase joins them with a single space.

This also improves camelCase, kebabCase, snakeCase, etc. for space-separated input.

Tests

  • All existing 63 tests pass
  • Added 3 new test cases: Hello World, hello world, Hello World
  • Verified titleCase is now idempotent: titleCase(titleCase('hello')) === 'Hello'

Summary by CodeRabbit

  • Bug Fixes

    • Improved text splitting behavior by properly treating spaces as delimiters during case-based operations.
    • Enhanced whitespace normalization when formatting text in title case, now correctly handling multiple consecutive spaces.
  • Tests

    • Expanded test coverage for multi-word input scenarios and whitespace handling edge cases.

The splitByCase function did not recognize space as a separator,
causing 'Hello World' to be split as ['Hello ', 'World'] with the
space trailing the first token. When titleCase joined with spaces,
this produced double spaces ('Hello  World').

Fix: add space to STR_SPLITTERS so splitByCase properly splits on
spaces. This also makes titleCase idempotent and fixes other case
functions (camelCase, kebabCase, etc.) to handle space-separated
input correctly.

Fixes unjs#96
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

This PR fixes a bug in the titleCase function where spaces were being incorrectly handled during string splitting. A space character was added to the default string splitters configuration, and test cases were added to validate the fix properly handles already title-cased strings and multiple spaces.

Changes

Cohort / File(s) Summary
String Splitter Configuration
src/index.ts
Added space character to STR_SPLITTERS to properly treat spaces as delimiter boundaries during string splitting operations.
Test Coverage
test/scule.test.ts
Extended titleCase test suite with three new cases covering already title-cased strings, lowercase multi-word input, and input with multiple consecutive spaces.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Poem

🐰 A space was lost in our splitting dance,
Now words align with proper stance,
No extra gaps in titles bright,
Each word's placement crystal right! ✨

🚥 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the fix addressing the core issue of extra spaces being inserted by titleCase when handling space-separated input.
Linked Issues check ✅ Passed The pull request successfully addresses all requirements from issue #96: adding space to STR_SPLITTERS fixes titleCase to handle space-separated input without inserting extra spaces, making it idempotent.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the titleCase spacing issue; no unrelated modifications to other functionality or files are present.

✏️ 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/scule.test.ts (1)

136-149: Add an explicit idempotency assertion for titleCase.

This suite now covers input variants well; adding one direct nested-call check would lock the issue objective more explicitly.

Suggested test addition
 describe("titleCase", () => {
   test.each([
     ["", ""],
     ["f", "F"],
     ["foo", "Foo"],
     ["foo-bar", "Foo Bar"],
     ["this-IS-aTitle", "This is a Title"],
     ["Hello World", "Hello World"],
     ["hello world", "Hello World"],
     ["Hello  World", "Hello World"],
   ])("%s => %s", (input, expected) => {
     expect(titleCase(input)).toMatchObject(expected);
   });
+
+  test("is idempotent", () => {
+    expect(titleCase(titleCase("hello world"))).toBe("Hello World");
+  });
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/scule.test.ts` around lines 136 - 149, Add an idempotency assertion to
the titleCase test: for each (input, expected) case in the describe("titleCase")
table, after asserting expect(titleCase(input)).toMatchObject(expected), also
assert that calling titleCase again returns the same value (e.g.
expect(titleCase(titleCase(input))).toMatchObject(titleCase(input)) or
toMatchObject(expected)). Update the test block that references titleCase to
include this nested-call check so the function is verified to be idempotent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/scule.test.ts`:
- Around line 136-149: Add an idempotency assertion to the titleCase test: for
each (input, expected) case in the describe("titleCase") table, after asserting
expect(titleCase(input)).toMatchObject(expected), also assert that calling
titleCase again returns the same value (e.g.
expect(titleCase(titleCase(input))).toMatchObject(titleCase(input)) or
toMatchObject(expected)). Update the test block that references titleCase to
include this nested-call check so the function is verified to be idempotent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0699c0e2-3c39-41f8-ab14-06093d85bef6

📥 Commits

Reviewing files that changed from the base of the PR and between 5bc6804 and 64693c2.

📒 Files selected for processing (2)
  • src/index.ts
  • test/scule.test.ts

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.

titleCase insert extra space when convert a valid titleCase string

1 participant