summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/components/shared/RadioButtonSelect.test.tsx
blob: 4b36fe3ccf87578badd8fc6d5c7d166ad18651ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import { render } from 'ink-testing-library';
import {
  RadioButtonSelect,
  type RadioSelectItem,
} from './RadioButtonSelect.js';
import { describe, it, expect } from 'vitest';

const ITEMS: Array<RadioSelectItem<string>> = [
  { label: 'Option 1', value: 'one' },
  { label: 'Option 2', value: 'two' },
  { label: 'Option 3', value: 'three', disabled: true },
];

describe('<RadioButtonSelect />', () => {
  it('renders a list of items and matches snapshot', () => {
    const { lastFrame } = render(
      <RadioButtonSelect items={ITEMS} onSelect={() => {}} isFocused={true} />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders with the second item selected and matches snapshot', () => {
    const { lastFrame } = render(
      <RadioButtonSelect
        items={ITEMS}
        initialIndex={1}
        onSelect={() => {}}
        isFocused={true}
      />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders with numbers hidden and matches snapshot', () => {
    const { lastFrame } = render(
      <RadioButtonSelect
        items={ITEMS}
        onSelect={() => {}}
        isFocused={true}
        showNumbers={false}
      />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders with scroll arrows and matches snapshot', () => {
    const manyItems = Array.from({ length: 20 }, (_, i) => ({
      label: `Item ${i + 1}`,
      value: `item-${i + 1}`,
    }));
    const { lastFrame } = render(
      <RadioButtonSelect
        items={manyItems}
        onSelect={() => {}}
        isFocused={true}
        showScrollArrows={true}
        maxItemsToShow={5}
      />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders with special theme display and matches snapshot', () => {
    const themeItems: Array<RadioSelectItem<string>> = [
      {
        label: 'Theme A (Light)',
        value: 'a-light',
        themeNameDisplay: 'Theme A',
        themeTypeDisplay: '(Light)',
      },
      {
        label: 'Theme B (Dark)',
        value: 'b-dark',
        themeNameDisplay: 'Theme B',
        themeTypeDisplay: '(Dark)',
      },
    ];
    const { lastFrame } = render(
      <RadioButtonSelect
        items={themeItems}
        onSelect={() => {}}
        isFocused={true}
      />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders a list with >10 items and matches snapshot', () => {
    const manyItems = Array.from({ length: 12 }, (_, i) => ({
      label: `Item ${i + 1}`,
      value: `item-${i + 1}`,
    }));
    const { lastFrame } = render(
      <RadioButtonSelect
        items={manyItems}
        onSelect={() => {}}
        isFocused={true}
      />,
    );
    expect(lastFrame()).toMatchSnapshot();
  });

  it('renders nothing when no items are provided', () => {
    const { lastFrame } = render(
      <RadioButtonSelect items={[]} onSelect={() => {}} isFocused={true} />,
    );
    expect(lastFrame()).toBe('');
  });
});