Skip to content

Preserve camelCase brand names in capitalize()#72

Merged
max-rosenblattl merged 2 commits into
mainfrom
max-rosenblattl/preserve-camelcase-capitalize
May 5, 2026
Merged

Preserve camelCase brand names in capitalize()#72
max-rosenblattl merged 2 commits into
mainfrom
max-rosenblattl/preserve-camelcase-capitalize

Conversation

@max-rosenblattl

Copy link
Copy Markdown
Collaborator

Current situation

capitalize() (applied to every generated caption) blindly upper-cases the first alphabetic character, which mangles brand-style names whose first letter is intentionally lowercase. With a channel display name like iPhone distance, captions render as:

IPhone distance values had a mean of 63.6 m/hr, ranged from 0.0 to 1385.5, …

Fix: when the first alphabetic character is lowercase and the next character is uppercase (camelCase prefix — iPhone, eBay, iOS, tvOS, …), leave the text unchanged. Sentence-start lowercase words (the watch …, a stretch …) still get capitalized as before.

Verified against:

Input Output
iPhone distance values had a mean … iPhone distance values had a mean … (unchanged)
eBay-like eBay-like (unchanged)
iOS device iOS device (unchanged)
the watch recorded The watch recorded
iphone case (no second-uppercase signal) Iphone case
Already capitalized Already capitalized

Release Notes

  • Generated captions no longer mangle brand-style channel names like iPhone into IPhone.

Documentation

No documentation changes — pure behavior fix in util.capitalize.

Testing

Manual: ran util.capitalize over the cases above; all match expected output. No existing test covered capitalize directly.

Code of Conduct & Contributing Guidelines

@coderabbitai

coderabbitai Bot commented May 5, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The capitalize() utility function is enhanced to skip leading non-alphabetic characters, preserve camelCase patterns (e.g., iPhone, eBay), and only capitalize the first alphabetic character when appropriate.

Changes

Utility Function Enhancement

Layer / File(s) Summary
Core Logic
util.py
capitalize() now scans past leading non-alphabetic characters, detects and preserves camelCase patterns (lowercase followed by uppercase), and conditionally uppercases the first alphabetic character.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

🚥 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 summarizes the main change: preserving camelCase brand names in the capitalize() function, which directly addresses the core issue of avoiding mangling brand-style names like iPhone.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the problem, the solution, test cases, and release notes for the capitalize() modification.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch max-rosenblattl/preserve-camelcase-capitalize

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
util.py (1)

16-26: ⚡ Quick win

No automated tests added for the new branching logic

The PR description notes there are no existing tests covering capitalize(). Given that this function now has four distinct code paths (already uppercase, camelCase guard, capitalise, all non-alpha), at minimum a parametrised unit test covering the documented examples (including the corrected tvOS case) should accompany this change.

🧪 Suggested test skeleton
import pytest
from util import capitalize

`@pytest.mark.parametrize`("text, expected", [
    ("iPhone distance values had a mean", "iPhone distance values had a mean"),
    ("eBay-like", "eBay-like"),
    ("iOS device", "iOS device"),
    ("tvOS platform", "tvOS platform"),          # currently broken without the fix above
    ("the watch recorded", "The watch recorded"),
    ("iphone case", "Iphone case"),
    ("Already capitalized", "Already capitalized"),
    ("123abc", "123Abc"),
    ("", ""),
    ("a", "A"),
])
def test_capitalize(text, expected):
    assert capitalize(text) == expected
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@util.py` around lines 16 - 26, The new branching logic in capitalize() lacks
automated tests; add a parametrized unit test for the capitalize function that
covers all four paths (already uppercase, camelCase guard like
"iPhone"/"eBay"/"iOS"/"tvOS", normal capitalization, and all-non-alpha or
leading-digits cases). Create a pytest test (e.g., test_capitalize) using
pytest.mark.parametrize with cases from the PR comment ("iPhone distance values
had a mean", "eBay-like", "iOS device", "tvOS platform", "the watch recorded",
"iphone case", "Already capitalized", "123abc", "", "a") and assert
capitalize(text) == expected for each to ensure the corrected tvOS behavior and
other branches remain covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@util.py`:
- Around line 22-25: The camelCase-preservation guard currently only checks
text[i + 1] and misses multi-lowercase-prefixes like "tvOS"; update the logic in
the block that uses variables text, i, and c to scan forward from i+1 until a
non-alphabetic character or end-of-string and if any character in that scanned
segment is uppercase return text unchanged, otherwise proceed to return text[:i]
+ c.upper() + text[i + 1:]; ensure the scan stops on non-alpha characters and
uses the same variables (text, i, c) so other cases like "iPhone" and "eBay"
keep working.

---

Nitpick comments:
In `@util.py`:
- Around line 16-26: The new branching logic in capitalize() lacks automated
tests; add a parametrized unit test for the capitalize function that covers all
four paths (already uppercase, camelCase guard like
"iPhone"/"eBay"/"iOS"/"tvOS", normal capitalization, and all-non-alpha or
leading-digits cases). Create a pytest test (e.g., test_capitalize) using
pytest.mark.parametrize with cases from the PR comment ("iPhone distance values
had a mean", "eBay-like", "iOS device", "tvOS platform", "the watch recorded",
"iphone case", "Already capitalized", "123abc", "", "a") and assert
capitalize(text) == expected for each to ensure the corrected tvOS behavior and
other branches remain covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 799eb54b-7663-401e-82c1-c6d34ddc22db

📥 Commits

Reviewing files that changed from the base of the PR and between a276c8e and 285cae5.

📒 Files selected for processing (1)
  • util.py

Comment thread util.py
Comment on lines +22 to +25
# Preserve intentional lowercase-first names like iPhone, eBay, iOS.
if i + 1 < len(text) and text[i + 1].isupper():
return text
return text[:i] + c.upper() + text[i + 1:]

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

camelCase detection misses multi-lowercase-prefix brands (e.g., tvOS)

The guard on Line 23 only checks text[i + 1] — the single character immediately following the first alphabetic character. This correctly preserves iPhone, eBay, and iOS, but fails for tvOS: the first alpha is 't', the next character is 'v' (lowercase), so the guard is skipped and the result is "TvOS".

The PR description explicitly lists tvOS (and by extension any xy…Z prefix) as a target, so this is a functional gap.

Fix: scan forward through the word (stopping at non-alpha characters or end of string) and return early if any character in that word segment is uppercase.

🐛 Proposed fix
-        # Preserve intentional lowercase-first names like iPhone, eBay, iOS.
-        if i + 1 < len(text) and text[i + 1].isupper():
-            return text
-        return text[:i] + c.upper() + text[i + 1:]
+        # Preserve intentional lowercase-first names like iPhone, eBay, iOS, tvOS.
+        # Scan the rest of the word for any uppercase letter (camelCase signal).
+        j = i + 1
+        while j < len(text) and text[j].isalpha():
+            if text[j].isupper():
+                return text
+            j += 1
+        return text[:i] + c.upper() + text[i + 1:]

Behavior with this fix:

Input Before fix After fix
"tvOS device" "TvOS device" "tvOS device"
"iPhone data" "iPhone data" "iPhone data"
"eBay-like" "eBay-like" "eBay-like"
"the watch" "The watch" "The watch"
"iphone case" "Iphone case" "Iphone case"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@util.py` around lines 22 - 25, The camelCase-preservation guard currently
only checks text[i + 1] and misses multi-lowercase-prefixes like "tvOS"; update
the logic in the block that uses variables text, i, and c to scan forward from
i+1 until a non-alphabetic character or end-of-string and if any character in
that scanned segment is uppercase return text unchanged, otherwise proceed to
return text[:i] + c.upper() + text[i + 1:]; ensure the scan stops on non-alpha
characters and uses the same variables (text, i, c) so other cases like "iPhone"
and "eBay" keep working.

@max-rosenblattl max-rosenblattl merged commit a0d12c9 into main May 5, 2026
3 checks passed
@max-rosenblattl max-rosenblattl deleted the max-rosenblattl/preserve-camelcase-capitalize branch May 5, 2026 08:27
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.

1 participant