Skip to content

test: session/summary — unquoteGitPath decoding for non-ASCII filenames#393

Closed
anandgupta42 wants to merge 1 commit intomainfrom
claude/test-summary-unquote-git-path-01W2Wz83z7cdDwq3pjtn6G3d
Closed

test: session/summary — unquoteGitPath decoding for non-ASCII filenames#393
anandgupta42 wants to merge 1 commit intomainfrom
claude/test-summary-unquote-git-path-01W2Wz83z7cdDwq3pjtn6G3d

Conversation

@anandgupta42
Copy link
Contributor

@anandgupta42 anandgupta42 commented Mar 23, 2026

What does this PR do?

1. unquoteGitPathsrc/session/summary.ts:14-68 (11 new tests)

This private function decodes git's C-style quoted file paths back to readable UTF-8 strings. Git quotes any path containing non-ASCII characters, spaces, or special characters using octal byte escapes (e.g., \303\251 for é). The function is called on every file path returned by git diff --name-status and feeds directly into the TUI diff view.

Why it was untested: The function is private to the SessionSummary namespace and not exported, so it was overlooked. Zero tests existed.

Why it matters: A bug in octal escape decoding would produce garbled filenames in the TUI diff view for any non-English-speaking user, or any project with non-ASCII characters in filenames (CJK characters, accented characters, emoji, spaces). This is a high-visibility regression risk since the TUI is the primary user interface.

Specific scenarios covered:

  • Passthrough for unquoted paths (no-op)
  • Passthrough for malformed quotes (only opening quote)
  • Simple quoted paths with spaces
  • 2-byte UTF-8 octal decoding (accented characters: café.txt)
  • 3-byte UTF-8 octal decoding (CJK characters: 日本.txt)
  • 4-byte UTF-8 octal decoding (emoji: 🎉.txt)
  • Mixed ASCII and octal escapes (résumé.pdf)
  • Standard escape sequences (\n, \t, \\, \")
  • Trailing backslash edge case (body ends with lone \)

Type of change

  • New feature (non-breaking change which adds functionality)

Issue for this PR

N/A — proactive test coverage from automated test discovery

How did you verify your code works?

bun test test/session/summary.test.ts       # 11 pass, 0 fail

Checklist

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

https://claude.ai/code/session_01W2Wz83z7cdDwq3pjtn6G3d

Summary by CodeRabbit

  • Tests
    • Added test coverage for path handling to validate proper processing of quoted paths and escape sequences, including UTF-8 character decoding and special character handling.

Adds 11 tests for the private unquoteGitPath function that decodes git's
C-style quoted paths. Without this coverage, bugs in octal escape handling
would silently produce garbled filenames in the TUI diff view for non-English
users (CJK, accented chars, emoji).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

https://claude.ai/code/session_01W2Wz83z7cdDwq3pjtn6G3d
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link

coderabbitai bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

A new Bun test file is added that validates the unquoteGitPath function from the session summary module. The test suite covers multiple scenarios including unquoted paths, quoted paths, escaped characters, octal-encoded UTF-8 sequences, and various edge cases.

Changes

Cohort / File(s) Summary
Test Suite for unquoteGitPath
packages/opencode/test/session/summary.test.ts
New test file with comprehensive test cases validating path unquoting behavior, including handling of quotes, escaped characters, octal-encoded UTF-8 sequences, and emoji characters.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

contributor

Poem

🐰 A rabbit hops through quoted paths,
Testing each twist, each turn,
Octal sequences and UTF-8 baths,
With emojis, the functions will learn!
✨ 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description provides comprehensive context covering what changed, why it matters, specific test scenarios, and verification steps, but does not follow the template's structured format (Summary, Test Plan, Checklist sections). Reformat the description to explicitly use the repository's template sections: Summary, Test Plan, and Checklist, while retaining the detailed technical content provided.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding test coverage for the unquoteGitPath function's decoding of non-ASCII filenames, which is the core focus of this PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 claude/test-summary-unquote-git-path-01W2Wz83z7cdDwq3pjtn6G3d

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

@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 (2)
packages/opencode/test/session/summary.test.ts (2)

67-69: Optional: Consider adding a few more edge cases.

For completeness, you might add tests for:

  • Only closing quote: 'src/index.ts"' → should return unchanged
  • Empty quoted string: '""' → should return empty string
  • Other implemented escapes: \r, \b, \f, \v

These are minor gaps and can be deferred if not critical.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/session/summary.test.ts` around lines 67 - 69, Add
additional unit tests to the existing summary.test.ts suite covering more edge
cases for unquoteGitPath: add tests for a string with only a closing quote
(e.g., '"src/index.ts"\' to ensure it returns unchanged), an empty quoted string
('""' should return an empty string), and separate tests for other escape
sequences that unquoteGitPath supports (e.g., '\r', '\b', '\f', '\v') to assert
they are unescaped correctly; place these alongside the existing test case for
the opening-quote-only scenario so the unquoteGitPath behavior is fully covered.

3-60: Consider adding a verification mechanism to prevent drift between the source and test implementations.

The source at src/session/summary.ts:14-68 is private to the SessionSummary namespace, so copying it for testing is reasonable. However, without automated verification, changes to the source can go undetected if the test copy isn't updated. Currently both are in sync, but the "keep in sync" comment relies on manual discipline.

Consider:

  • Exporting the function (even as /** @internal */ for testing)
  • Adding a comment in the source linking to this test file
  • Adding a verification script that compares both implementations
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/opencode/test/session/summary.test.ts` around lines 3 - 60, The test
copies the private function unquoteGitPath from src/session/summary.ts which
risks drift; add an automated verification by exporting the implementation (mark
as `@internal`) or adding a small build/test-time comparator that asserts the test
copy and the source implementation are byte-for-byte identical; update either
src/session/summary.ts to export (or provide an internal helper) named
unquoteGitPath and modify the test to import that symbol, or add a CI
step/script that reads both the source and test copies and fails if they differ,
referencing the symbol name unquoteGitPath to locate the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/opencode/test/session/summary.test.ts`:
- Around line 67-69: Add additional unit tests to the existing summary.test.ts
suite covering more edge cases for unquoteGitPath: add tests for a string with
only a closing quote (e.g., '"src/index.ts"\' to ensure it returns unchanged),
an empty quoted string ('""' should return an empty string), and separate tests
for other escape sequences that unquoteGitPath supports (e.g., '\r', '\b', '\f',
'\v') to assert they are unescaped correctly; place these alongside the existing
test case for the opening-quote-only scenario so the unquoteGitPath behavior is
fully covered.
- Around line 3-60: The test copies the private function unquoteGitPath from
src/session/summary.ts which risks drift; add an automated verification by
exporting the implementation (mark as `@internal`) or adding a small
build/test-time comparator that asserts the test copy and the source
implementation are byte-for-byte identical; update either src/session/summary.ts
to export (or provide an internal helper) named unquoteGitPath and modify the
test to import that symbol, or add a CI step/script that reads both the source
and test copies and fails if they differ, referencing the symbol name
unquoteGitPath to locate the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a6d47bc1-4feb-4bf3-9070-676f4ba11c3e

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb13d4 and d1926cf.

📒 Files selected for processing (1)
  • packages/opencode/test/session/summary.test.ts

anandgupta42 added a commit that referenced this pull request Mar 23, 2026
Merges 9 test PRs (#390, #394, #395, #396, #397, #398, #399, #401, #387)
into a single PR, discarding 4 duplicates (#391, #392, #393, #400).

**New test coverage:**
- `id.test.ts` — 14 tests: Identifier generation, monotonic ordering, timestamp extraction, Zod schema
- `shell.test.ts` — 9 tests: shell blacklist enforcement for fish/nu, cache reset, fallback
- `path-traversal.test.ts` — 7 tests (new): `Protected.isSensitiveWrite` for .pem/.key, .gnupg, .env variants
- `ignore.test.ts` — 7 tests (new): `FileIgnore.match` directory patterns, globs, whitelist overrides
- `paths-parsetext.test.ts` — 16 tests: `ConfigPaths.parseText` env/file substitution, JSONC parsing
- `finops-formatting.test.ts` — 14 tests: `formatBytes`/`truncateQuery` edge cases
- `finops-role-access.test.ts` — 10 tests: RBAC `formatGrants`/`formatHierarchy`/`formatUserRoles`
- `tool-lookup.test.ts` — 4 tests: Zod schema introspection for tool parameters
- `summary-git-path.test.ts` — 10 tests: `unquoteGitPath` decoding for non-ASCII filenames
- `tracing.test.ts` — 2 tests (added): Recap loop detection boundaries
- `patch.test.ts` — 9 tests (added): `maybeParseApplyPatchVerified` entry point coverage
- `instruction.test.ts` — 13 tests (new): `InstructionPrompt.loaded()` dedup guards
- `message-v2.test.ts` — 23 tests (new): `MessageV2.filterCompacted()` boundary detection

**Bug fixes (discovered during testing):**
- `finops-formatting.ts`: fix `formatBytes` crash on negative/NaN/fractional inputs
- `finops-formatting.ts`: fix `truncateQuery` returning empty for whitespace-only, exceeding `maxLen` when < 4
- `training-import.test.ts`: fix pre-existing typecheck errors (missing `context`/`rule` mock keys)
- `instruction.test.ts`, `message-v2.test.ts`: fix `MessageV2.Part` cast and branded ID type errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@anandgupta42
Copy link
Contributor Author

Consolidated into #403

@anandgupta42 anandgupta42 deleted the claude/test-summary-unquote-git-path-01W2Wz83z7cdDwq3pjtn6G3d branch March 23, 2026 17:11
anandgupta42 added a commit that referenced this pull request Mar 23, 2026
* test: consolidated test coverage across 9 modules (133 new tests)

Merges 9 test PRs (#390, #394, #395, #396, #397, #398, #399, #401, #387)
into a single PR, discarding 4 duplicates (#391, #392, #393, #400).

**New test coverage:**
- `id.test.ts` — 14 tests: Identifier generation, monotonic ordering, timestamp extraction, Zod schema
- `shell.test.ts` — 9 tests: shell blacklist enforcement for fish/nu, cache reset, fallback
- `path-traversal.test.ts` — 7 tests (new): `Protected.isSensitiveWrite` for .pem/.key, .gnupg, .env variants
- `ignore.test.ts` — 7 tests (new): `FileIgnore.match` directory patterns, globs, whitelist overrides
- `paths-parsetext.test.ts` — 16 tests: `ConfigPaths.parseText` env/file substitution, JSONC parsing
- `finops-formatting.test.ts` — 14 tests: `formatBytes`/`truncateQuery` edge cases
- `finops-role-access.test.ts` — 10 tests: RBAC `formatGrants`/`formatHierarchy`/`formatUserRoles`
- `tool-lookup.test.ts` — 4 tests: Zod schema introspection for tool parameters
- `summary-git-path.test.ts` — 10 tests: `unquoteGitPath` decoding for non-ASCII filenames
- `tracing.test.ts` — 2 tests (added): Recap loop detection boundaries
- `patch.test.ts` — 9 tests (added): `maybeParseApplyPatchVerified` entry point coverage
- `instruction.test.ts` — 13 tests (new): `InstructionPrompt.loaded()` dedup guards
- `message-v2.test.ts` — 23 tests (new): `MessageV2.filterCompacted()` boundary detection

**Bug fixes (discovered during testing):**
- `finops-formatting.ts`: fix `formatBytes` crash on negative/NaN/fractional inputs
- `finops-formatting.ts`: fix `truncateQuery` returning empty for whitespace-only, exceeding `maxLen` when < 4
- `training-import.test.ts`: fix pre-existing typecheck errors (missing `context`/`rule` mock keys)
- `instruction.test.ts`, `message-v2.test.ts`: fix `MessageV2.Part` cast and branded ID type errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address code review findings — test artifact leakage and cleanup

- summary-git-path.test.ts: use tmpdir() instead of projectRoot to prevent
  Storage.write() from polluting the developer's .opencode/storage/ directory
- finops-role-access.test.ts: consolidate duplicate afterAll hooks to ensure
  ALTIMATE_TELEMETRY_DISABLED env var is cleaned up after tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants