hermes-agent/ui-tui/src/__tests__/textInputRightClick.test.ts
Wesley Simplicio a2920b1762 fix(tui): right-click copies selection, only pastes when no selection
Sub-issue 5 of #22034.

Right-click on the composer always pasted from the clipboard, even when
the user had highlighted text — diverging from terminal-native behavior
(xterm/iTerm/gnome-terminal) where right-click copies an active selection
and only pastes when nothing is selected.

Extract a small pure helper, decideRightClickAction(value, range), and
route the existing onMouseDown right-click branch through it. Selection
present and non-empty -> writeClipboardText(slice). Otherwise fall back
to the existing emitPaste path.
2026-05-10 16:06:33 -07:00

48 lines
1.4 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { decideRightClickAction } from '../components/textInput.js'
describe('decideRightClickAction', () => {
it('returns paste when there is no selection', () => {
expect(decideRightClickAction('hello world', null)).toEqual({ action: 'paste' })
})
it('returns paste for a collapsed (empty) range', () => {
expect(decideRightClickAction('hello world', { end: 5, start: 5 })).toEqual({
action: 'paste'
})
})
it('copies the slice when range covers non-empty text', () => {
expect(decideRightClickAction('hello world', { end: 5, start: 0 })).toEqual({
action: 'copy',
text: 'hello'
})
})
it('copies a middle slice', () => {
expect(decideRightClickAction('hello world', { end: 11, start: 6 })).toEqual({
action: 'copy',
text: 'world'
})
})
it('falls back to paste when slice is empty (out-of-range indices)', () => {
expect(decideRightClickAction('', { end: 5, start: 0 })).toEqual({ action: 'paste' })
})
it('handles unicode (emoji, CJK) in the slice', () => {
const value = 'hi 你好 🎉'
expect(decideRightClickAction(value, { end: 5, start: 3 })).toEqual({
action: 'copy',
text: '你好'
})
})
it('preserves leading/trailing whitespace in the copied slice', () => {
expect(decideRightClickAction(' spaced ', { end: 10, start: 0 })).toEqual({
action: 'copy',
text: ' spaced '
})
})
})