Skip to content

feat: add string utility functions - #39

Open
CristianAmbrosini wants to merge 1 commit into
mainfrom
test/gessie-telemetry-validation
Open

feat: add string utility functions#39
CristianAmbrosini wants to merge 1 commit into
mainfrom
test/gessie-telemetry-validation

Conversation

@CristianAmbrosini

Copy link
Copy Markdown
Owner

Summary

Add a new string_utils.py module with common string manipulation functions:

  • reverse_words — reverse word order in a sentence
  • count_vowels — count vowels in text
  • truncate — truncate text with configurable suffix
  • to_snake_case — convert camelCase to snake_case
  • is_palindrome — check if text is a palindrome

Purpose

Test PR to validate Gessie telemetry events are firing correctly after the metadata.source fix.

@sonar-review-dev18

sonar-review-dev18 Bot commented Apr 27, 2026

Copy link
Copy Markdown

Summary

This PR adds a new string_utils.py module with five utility functions: reverse_words, count_vowels, truncate, to_snake_case, and is_palindrome. The functions are straightforward implementations with type hints.

This is a test PR designed to validate that Gessie telemetry events fire correctly following the metadata.source fix. The utility functions themselves are intentionally simple; the focus is on confirming telemetry instrumentation is working properly.

What reviewers should know

For reviewers:

  • This PR's primary goal is telemetry validation, not utility function features
  • The code is clean and syntactically correct — check it as you would any new module, but don't focus heavily on implementation details
  • Verify telemetry events are being captured for this change (check Gessie logs or telemetry dashboard per your team's process)
  • All five functions include type hints and the module has a docstring

Key files:

  • string_utils.py — the only change, a new 29-line module with no dependencies

  • Generate Walkthrough
  • Generate Diagram

🗣️ Give feedback

@sonarqube-cloud-dev18

Copy link
Copy Markdown

SonarQube reviewer guide

Review in SonarQube

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

@sonar-review-dev18 sonar-review-dev18 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.

The new functions are logically sound for typical inputs, but there's a real bug in truncate and all five public functions are missing docstrings, which violates the org guideline requiring docstrings on all public functions.

SonarQube Cloud status: The quality gate is failing — coverage on new code is 0% against an 80% threshold. See the reviewer guide above for details.

🗣️ Give feedback

Comment thread string_utils.py
Comment on lines +12 to +15
def truncate(text: str, max_length: int, suffix: str = "...") -> str:
if len(text) <= max_length:
return text
return text[: max_length - len(suffix)] + suffix

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: When max_length is smaller than len(suffix), max_length - len(suffix) is negative. Python interprets a negative slice index as an offset from the end of the string, so text[:-1] silently returns nearly the full string and the result exceeds max_length.

Example: truncate("hello", 2, "...")max_length - len(suffix) = -1 → "hell" + "..." = "hell..." (7 chars), not 2.

Add a guard at the top of the function:

Suggested change
def truncate(text: str, max_length: int, suffix: str = "...") -> str:
if len(text) <= max_length:
return text
return text[: max_length - len(suffix)] + suffix
def truncate(text: str, max_length: int, suffix: str = "...") -> str:
if max_length < len(suffix):
raise ValueError(f"max_length ({max_length}) must be >= len(suffix) ({len(suffix)})")
if len(text) <= max_length:
return text
return text[: max_length - len(suffix)] + suffix
  • Mark as noise

Comment thread string_utils.py
def truncate(text: str, max_length: int, suffix: str = "...") -> str:
if len(text) <= max_length:
return text
return text[: max_length - len(suffix)] + suffix

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing test coverage: No test covers the edge case where max_length < len(suffix). Without a test, the silent wrong-output bug described above will go undetected. A unit test asserting that truncate("hello", 2, "...") raises ValueError (after the fix) would catch regressions here.

  • Mark as noise

Comment thread string_utils.py
"""String utility functions."""


def reverse_words(sentence: str) -> str:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing docstring: reverse_words is a public function and must have a docstring describing what it does, its parameters, and its return value (org guideline).

def reverse_words(sentence: str) -> str:
    """Reverse the order of words in a sentence.

    Args:
        sentence: The input string whose words will be reversed.

    Returns:
        A string with the words in reversed order.
    """
  • Mark as noise

Comment thread string_utils.py
return " ".join(sentence.split()[::-1])


def count_vowels(text: str) -> int:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing docstring: count_vowels is a public function and must have a docstring (org guideline). Describe that it counts ASCII vowels (a, e, i, o, u) case-insensitively, so callers know accented vowels are not counted.

  • Mark as noise

Comment thread string_utils.py
return sum(1 for c in text.lower() if c in "aeiou")


def truncate(text: str, max_length: int, suffix: str = "...") -> str:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing docstring: truncate is a public function and must have a docstring (org guideline). Document the suffix default, the max_length constraint relative to suffix length, and the return value.

  • Mark as noise

Comment thread string_utils.py
return text[: max_length - len(suffix)] + suffix


def to_snake_case(text: str) -> str:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing docstring: to_snake_case is a public function and must have a docstring (org guideline). Worth noting that consecutive uppercase sequences (e.g. HTMLParser) are treated character-by-character (h_t_m_l_parser), so callers are not surprised by that behaviour.

  • Mark as noise

Comment thread string_utils.py
result.append(char.lower())
return "".join(result)


Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing docstring: is_palindrome is a public function and must have a docstring (org guideline). Document that non-alphanumeric characters are stripped and comparison is case-insensitive.

  • Mark as noise

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