diff options
| author | Jacob Richman <[email protected]> | 2025-08-14 16:48:54 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-14 23:48:54 +0000 |
| commit | 6037cb5d60b8e31b92315dd86fc65dbc57316376 (patch) | |
| tree | a1e241df4c9e619f3f920b73790a2e225ba702b4 /packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx | |
| parent | a5c81e3fe07d264dd467d9d2aebb8ae0bc32bfb3 (diff) | |
Fix bug where RadioButtonSelect treated an omitted isFocus parameter (#6274)
Diffstat (limited to 'packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx')
| -rw-r--r-- | packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx | 104 |
1 files changed, 85 insertions, 19 deletions
diff --git a/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx b/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx index 4b36fe3c..d4c13ba5 100644 --- a/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx +++ b/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx @@ -5,11 +5,12 @@ */ import { render } from 'ink-testing-library'; +import { waitFor } from '@testing-library/react'; import { RadioButtonSelect, type RadioSelectItem, } from './RadioButtonSelect.js'; -import { describe, it, expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; const ITEMS: Array<RadioSelectItem<string>> = [ { label: 'Option 1', value: 'one' }, @@ -27,12 +28,7 @@ describe('<RadioButtonSelect />', () => { it('renders with the second item selected and matches snapshot', () => { const { lastFrame } = render( - <RadioButtonSelect - items={ITEMS} - initialIndex={1} - onSelect={() => {}} - isFocused={true} - />, + <RadioButtonSelect items={ITEMS} initialIndex={1} onSelect={() => {}} />, ); expect(lastFrame()).toMatchSnapshot(); }); @@ -42,7 +38,6 @@ describe('<RadioButtonSelect />', () => { <RadioButtonSelect items={ITEMS} onSelect={() => {}} - isFocused={true} showNumbers={false} />, ); @@ -58,7 +53,6 @@ describe('<RadioButtonSelect />', () => { <RadioButtonSelect items={manyItems} onSelect={() => {}} - isFocused={true} showScrollArrows={true} maxItemsToShow={5} />, @@ -82,11 +76,7 @@ describe('<RadioButtonSelect />', () => { }, ]; const { lastFrame } = render( - <RadioButtonSelect - items={themeItems} - onSelect={() => {}} - isFocused={true} - />, + <RadioButtonSelect items={themeItems} onSelect={() => {}} />, ); expect(lastFrame()).toMatchSnapshot(); }); @@ -97,11 +87,7 @@ describe('<RadioButtonSelect />', () => { value: `item-${i + 1}`, })); const { lastFrame } = render( - <RadioButtonSelect - items={manyItems} - onSelect={() => {}} - isFocused={true} - />, + <RadioButtonSelect items={manyItems} onSelect={() => {}} />, ); expect(lastFrame()).toMatchSnapshot(); }); @@ -113,3 +99,83 @@ describe('<RadioButtonSelect />', () => { expect(lastFrame()).toBe(''); }); }); + +describe('keyboard navigation', () => { + it('should call onSelect when "enter" is pressed', () => { + const onSelect = vi.fn(); + const { stdin } = render( + <RadioButtonSelect items={ITEMS} onSelect={onSelect} />, + ); + + stdin.write('\r'); + + expect(onSelect).toHaveBeenCalledWith('one'); + }); + + describe('when isFocused is false', () => { + it('should not handle any keyboard input', () => { + const onSelect = vi.fn(); + const { stdin } = render( + <RadioButtonSelect + items={ITEMS} + onSelect={onSelect} + isFocused={false} + />, + ); + + stdin.write('\u001B[B'); // Down arrow + stdin.write('\u001B[A'); // Up arrow + stdin.write('\r'); // Enter + + expect(onSelect).not.toHaveBeenCalled(); + }); + }); + + describe.each([ + { description: 'when isFocused is true', isFocused: true }, + { description: 'when isFocused is omitted', isFocused: undefined }, + ])('$description', ({ isFocused }) => { + it('should navigate down with arrow key and select with enter', async () => { + const onSelect = vi.fn(); + const { stdin, lastFrame } = render( + <RadioButtonSelect + items={ITEMS} + onSelect={onSelect} + isFocused={isFocused} + />, + ); + + stdin.write('\u001B[B'); // Down arrow + + await waitFor(() => { + expect(lastFrame()).toContain('● 2. Option 2'); + }); + + stdin.write('\r'); + + expect(onSelect).toHaveBeenCalledWith('two'); + }); + + it('should navigate up with arrow key and select with enter', async () => { + const onSelect = vi.fn(); + const { stdin, lastFrame } = render( + <RadioButtonSelect + items={ITEMS} + onSelect={onSelect} + initialIndex={1} + isFocused={isFocused} + />, + ); + + stdin.write('\u001B[A'); // Up arrow + + await waitFor(() => { + expect(lastFrame()).toContain('● 1. Option 1'); + }); + + stdin.write('\r'); + + expect(onSelect).toHaveBeenCalledWith('one'); + }); + }); +}); |
