Skip to content

test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers#97805

Merged
vincentkoc merged 2 commits into
openclaw:mainfrom
dwc1997:fix/utf16-slice-tests
Jun 29, 2026
Merged

test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers#97805
vincentkoc merged 2 commits into
openclaw:mainfrom
dwc1997:fix/utf16-slice-tests

Conversation

@dwc1997

@dwc1997 dwc1997 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

The utf16-slice.ts module provides surrogate-safe UTF-16 string slicing helpers. However, this module lacked unit tests to verify the UTF-16 string slicing behavior, which could lead to regressions when the function is modified.

Why This Change Was Made

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions to verify UTF-16 string slicing behavior. This improves test coverage and prevents regressions.

Focused tests cover ASCII slicing, negative indices, out-of-bounds handling, surrogate pair preservation, and emoji handling.

User Impact

UTF-16 string slicing now has comprehensive test coverage, reducing the risk of regressions when the function is modified.

Evidence

Reproducibility: not applicable. This PR adds direct coverage for existing helper behavior rather than reporting a user-visible runtime bug. Source inspection confirms the helper behavior the tests target.

Direct behavior probe:

$ node --import tsx -e "import('./src/shared/utf16-slice.js').then(({ sliceUtf16Safe, truncateUtf16Safe }) => console.log(JSON.stringify([{ desc: 'sliceUtf16Safe slices ASCII string', input: 'hello world', start: 0, end: 5, result: sliceUtf16Safe('hello world', 0, 5), expected: 'hello' }, { desc: 'sliceUtf16Safe handles negative start', input: 'hello world', start: -5, result: sliceUtf16Safe('hello world', -5), expected: 'world' }, { desc: 'truncateUtf16Safe returns input when shorter than limit', input: 'hello', maxLen: 10, result: truncateUtf16Safe('hello', 10), expected: 'hello' }, { desc: 'truncateUtf16Safe truncates when longer than limit', input: 'hello world', maxLen: 5, result: truncateUtf16Safe('hello world', 5), expected: 'hello' }], null, 2)))"
[
  {
    "desc": "sliceUtf16Safe slices ASCII string",
    "input": "hello world",
    "start": 0,
    "end": 5,
    "result": "hello",
    "expected": "hello"
  },
  {
    "desc": "sliceUtf16Safe handles negative start",
    "input": "hello world",
    "start": -5,
    "result": "world",
    "expected": "world"
  },
  {
    "desc": "truncateUtf16Safe returns input when shorter than limit",
    "input": "hello",
    "maxLen": 10,
    "result": "hello",
    "expected": "hello"
  },
  {
    "desc": "truncateUtf16Safe truncates when longer than limit",
    "input": "hello world",
    "maxLen": 5,
    "result": "hello",
    "expected": "hello"
  }
]

Targeted test:

$ node scripts/run-vitest.mjs run src/shared/utf16-slice.test.ts

 RUN  v4.1.8 /home/0668001110/ZTEProject/openclaw-worktrees/pr-94335

 Test Files  1 passed (1)
      Tests  18 passed (18)
   Start at  22:06:58
   Duration  346ms (transform 62ms, setup 0ms, import 83ms, tests 8ms)

[test] passed 1 Vitest shard in 9.64s

Formatting:

$ npx oxfmt --check src/shared/utf16-slice.ts src/shared/utf16-slice.test.ts
Checking formatting...

All matched files use the correct format.
Finished in 65ms on 2 files using 8 threads.

Whitespace:

$ git diff --check

AI-assisted

Prepared with Codex. I reviewed the change, understand the touched code path, and kept the PR focused on the bug described above.

… helpers

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in
src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior.

Tests cover:
- sliceUtf16Safe slices ASCII string normally
- sliceUtf16Safe handles negative start/end
- sliceUtf16Safe handles start/end beyond length
- sliceUtf16Safe swaps start and end when start > end
- sliceUtf16Safe preserves emoji with surrogate pairs
- sliceUtf16Safe avoids splitting surrogate pair at start/end
- truncateUtf16Safe returns input when shorter than limit
- truncateUtf16Safe truncates when longer than limit
- truncateUtf16Safe handles zero/negative limit
- truncateUtf16Safe floors decimal limit
- truncateUtf16Safe preserves emoji with surrogate pairs
- truncateUtf16Safe avoids splitting surrogate pair
@clawsweeper

clawsweeper Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed June 29, 2026, 11:03 AM ET / 15:03 UTC.

Summary
The branch adds a colocated Vitest test file for sliceUtf16Safe and truncateUtf16Safe, covering normal slicing, index normalization, limits, and surrogate-boundary behavior.

PR surface: Tests +88. Total +88 across 1 file.

Reproducibility: not applicable. This PR adds regression tests for an existing helper rather than reporting a runtime bug. The expected helper contract is visible in src/shared/utf16-slice.ts.

Review metrics: none identified.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • none.

Next step before merge

  • No ClawSweeper repair lane is needed; the remaining action is normal maintainer review and CI gating for the open PR.

Security
Cleared: The diff adds only a colocated Vitest test file and introduces no dependency, workflow, script, package, secret, or runtime execution surface.

Review details

Best possible solution:

Land the focused helper test coverage after ordinary maintainer and CI review, while keeping the production helper behavior unchanged.

Do we have a high-confidence way to reproduce the issue?

Not applicable; this PR adds regression tests for an existing helper rather than reporting a runtime bug. The expected helper contract is visible in src/shared/utf16-slice.ts.

Is this the best way to solve the issue?

Yes; a colocated Vitest file is the narrowest maintainable layer for direct helper coverage, and current main does not already have equivalent shared-helper tests.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 86b9b88f4066.

Label changes

Label changes:

  • add rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal output for a direct helper behavior probe and the targeted Vitest run for the added test file after the assertion fix.
  • remove rating: 🦐 gold shrimp: Current PR rating is rating: 🐚 platinum hermit, so this older rating label is no longer current.
  • remove status: ⏳ waiting on author: Current PR status label is status: 👀 ready for maintainer look.

Label justifications:

  • P3: This is a low-risk test coverage cleanup for an existing shared helper with no production behavior, config, migration, or user-facing surface change.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (terminal): The PR body includes terminal output for a direct helper behavior probe and the targeted Vitest run for the added test file after the assertion fix.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes terminal output for a direct helper behavior probe and the targeted Vitest run for the added test file after the assertion fix.
Evidence reviewed

PR surface:

Tests +88. Total +88 across 1 file.

View PR surface stats
Area Files Added Removed Net
Source 0 0 0 0
Tests 1 88 0 +88
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 1 88 0 +88

What I checked:

Likely related people:

  • llagy009: Current blame and git log -S tie the shared UTF-16 helper implementation to the merged Tlon boundary fix commit. (role: introduced behavior; confidence: high; commits: 6299b679c05f; files: src/shared/utf16-slice.ts, src/utils.ts, src/plugin-sdk/text-utility-runtime.ts)
  • vincentkoc: Live PR metadata shows this person merged the PR that introduced the shared helper now being tested. (role: merger signal; confidence: medium; commits: 6299b679c05f; files: src/shared/utf16-slice.ts)
  • zenglingbiao: Recent merged shared UTF-16 truncation work touched adjacent shared formatting and assistant-error paths that use this helper contract. (role: recent adjacent contributor; confidence: medium; files: src/shared/subagents-format.ts, src/shared/subagents-format.test.ts, src/shared/assistant-error-format.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. labels Jun 29, 2026
Replace vague 'result.length >= 0' assertions with exact expected output
checks for surrogate pair boundary cases. The helper returns empty string
when slicing at surrogate pair boundaries.
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jun 29, 2026
@vincentkoc
vincentkoc merged commit f92ec2d into openclaw:main Jun 29, 2026
112 of 116 checks passed
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jun 30, 2026
… helpers (openclaw#97805)

* test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in
src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior.

Tests cover:
- sliceUtf16Safe slices ASCII string normally
- sliceUtf16Safe handles negative start/end
- sliceUtf16Safe handles start/end beyond length
- sliceUtf16Safe swaps start and end when start > end
- sliceUtf16Safe preserves emoji with surrogate pairs
- sliceUtf16Safe avoids splitting surrogate pair at start/end
- truncateUtf16Safe returns input when shorter than limit
- truncateUtf16Safe truncates when longer than limit
- truncateUtf16Safe handles zero/negative limit
- truncateUtf16Safe floors decimal limit
- truncateUtf16Safe preserves emoji with surrogate pairs
- truncateUtf16Safe avoids splitting surrogate pair

* fix: replace tautological surrogate assertions with exact output checks

Replace vague 'result.length >= 0' assertions with exact expected output
checks for surrogate pair boundary cases. The helper returns empty string
when slicing at surrogate pair boundaries.
QiuYuang pushed a commit to QiuYuang/openclaw that referenced this pull request Jul 1, 2026
… helpers (openclaw#97805)

* test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in
src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior.

Tests cover:
- sliceUtf16Safe slices ASCII string normally
- sliceUtf16Safe handles negative start/end
- sliceUtf16Safe handles start/end beyond length
- sliceUtf16Safe swaps start and end when start > end
- sliceUtf16Safe preserves emoji with surrogate pairs
- sliceUtf16Safe avoids splitting surrogate pair at start/end
- truncateUtf16Safe returns input when shorter than limit
- truncateUtf16Safe truncates when longer than limit
- truncateUtf16Safe handles zero/negative limit
- truncateUtf16Safe floors decimal limit
- truncateUtf16Safe preserves emoji with surrogate pairs
- truncateUtf16Safe avoids splitting surrogate pair

* fix: replace tautological surrogate assertions with exact output checks

Replace vague 'result.length >= 0' assertions with exact expected output
checks for surrogate pair boundary cases. The helper returns empty string
when slicing at surrogate pair boundaries.
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 1, 2026
… helpers (openclaw#97805)

* test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in
src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior.

Tests cover:
- sliceUtf16Safe slices ASCII string normally
- sliceUtf16Safe handles negative start/end
- sliceUtf16Safe handles start/end beyond length
- sliceUtf16Safe swaps start and end when start > end
- sliceUtf16Safe preserves emoji with surrogate pairs
- sliceUtf16Safe avoids splitting surrogate pair at start/end
- truncateUtf16Safe returns input when shorter than limit
- truncateUtf16Safe truncates when longer than limit
- truncateUtf16Safe handles zero/negative limit
- truncateUtf16Safe floors decimal limit
- truncateUtf16Safe preserves emoji with surrogate pairs
- truncateUtf16Safe avoids splitting surrogate pair

* fix: replace tautological surrogate assertions with exact output checks

Replace vague 'result.length >= 0' assertions with exact expected output
checks for surrogate pair boundary cases. The helper returns empty string
when slicing at surrogate pair boundaries.
chenyangjun-xy pushed a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 3, 2026
… helpers (openclaw#97805)

* test(shared): add unit tests for surrogate-safe UTF-16 string slicing helpers

Add unit tests for sliceUtf16Safe and truncateUtf16Safe functions in
src/shared/utf16-slice.ts to verify UTF-16 string slicing behavior.

Tests cover:
- sliceUtf16Safe slices ASCII string normally
- sliceUtf16Safe handles negative start/end
- sliceUtf16Safe handles start/end beyond length
- sliceUtf16Safe swaps start and end when start > end
- sliceUtf16Safe preserves emoji with surrogate pairs
- sliceUtf16Safe avoids splitting surrogate pair at start/end
- truncateUtf16Safe returns input when shorter than limit
- truncateUtf16Safe truncates when longer than limit
- truncateUtf16Safe handles zero/negative limit
- truncateUtf16Safe floors decimal limit
- truncateUtf16Safe preserves emoji with surrogate pairs
- truncateUtf16Safe avoids splitting surrogate pair

* fix: replace tautological surrogate assertions with exact output checks

Replace vague 'result.length >= 0' assertions with exact expected output
checks for surrogate pair boundary cases. The helper returns empty string
when slicing at surrogate pair boundaries.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P3 Low-priority cleanup, docs, polish, ergonomics, or speculative work. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants