summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx
diff options
context:
space:
mode:
authorJacob Richman <[email protected]>2025-08-14 16:48:54 -0700
committerGitHub <[email protected]>2025-08-14 23:48:54 +0000
commit6037cb5d60b8e31b92315dd86fc65dbc57316376 (patch)
treea1e241df4c9e619f3f920b73790a2e225ba702b4 /packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx
parenta5c81e3fe07d264dd467d9d2aebb8ae0bc32bfb3 (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.tsx104
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');
+ });
+ });
+});