tty-prompt 0.19.0 → 0.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +81 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +485 -233
  5. data/lib/tty-prompt.rb +1 -2
  6. data/lib/tty/prompt.rb +159 -147
  7. data/lib/tty/prompt/answers_collector.rb +5 -5
  8. data/lib/tty/prompt/block_paginator.rb +1 -1
  9. data/lib/tty/prompt/choice.rb +31 -13
  10. data/lib/tty/prompt/choices.rb +30 -12
  11. data/lib/tty/prompt/confirm_question.rb +42 -16
  12. data/lib/tty/prompt/const.rb +17 -0
  13. data/lib/tty/prompt/converter_dsl.rb +6 -7
  14. data/lib/tty/prompt/converter_registry.rb +31 -26
  15. data/lib/tty/prompt/converters.rb +139 -32
  16. data/lib/tty/prompt/enum_list.rb +58 -25
  17. data/lib/tty/prompt/errors.rb +31 -0
  18. data/lib/tty/prompt/evaluator.rb +2 -2
  19. data/lib/tty/prompt/expander.rb +27 -15
  20. data/lib/tty/prompt/keypress.rb +5 -3
  21. data/lib/tty/prompt/list.rb +101 -38
  22. data/lib/tty/prompt/mask_question.rb +9 -5
  23. data/lib/tty/prompt/multi_list.rb +108 -29
  24. data/lib/tty/prompt/multiline.rb +9 -7
  25. data/lib/tty/prompt/paginator.rb +1 -1
  26. data/lib/tty/prompt/question.rb +67 -36
  27. data/lib/tty/prompt/question/checks.rb +20 -2
  28. data/lib/tty/prompt/question/modifier.rb +4 -2
  29. data/lib/tty/prompt/question/validation.rb +3 -3
  30. data/lib/tty/prompt/selected_choices.rb +77 -0
  31. data/lib/tty/prompt/slider.rb +110 -23
  32. data/lib/tty/prompt/statement.rb +3 -3
  33. data/lib/tty/prompt/suggestion.rb +7 -6
  34. data/lib/tty/prompt/symbols.rb +58 -58
  35. data/lib/tty/prompt/test.rb +36 -0
  36. data/lib/tty/prompt/utils.rb +1 -3
  37. data/lib/tty/prompt/version.rb +1 -1
  38. metadata +27 -196
  39. data/Rakefile +0 -8
  40. data/examples/ask.rb +0 -7
  41. data/examples/ask_blank.rb +0 -9
  42. data/examples/ask_valid.rb +0 -12
  43. data/examples/collect.rb +0 -21
  44. data/examples/echo.rb +0 -11
  45. data/examples/enum_select.rb +0 -7
  46. data/examples/enum_select_disabled.rb +0 -16
  47. data/examples/enum_select_paged.rb +0 -9
  48. data/examples/enum_select_wrapped.rb +0 -15
  49. data/examples/expand.rb +0 -29
  50. data/examples/expand_auto.rb +0 -29
  51. data/examples/in.rb +0 -9
  52. data/examples/inputs.rb +0 -10
  53. data/examples/key_events.rb +0 -15
  54. data/examples/keypress.rb +0 -9
  55. data/examples/mask.rb +0 -13
  56. data/examples/multi_select.rb +0 -8
  57. data/examples/multi_select_disabled.rb +0 -17
  58. data/examples/multi_select_disabled_paged.rb +0 -22
  59. data/examples/multi_select_paged.rb +0 -9
  60. data/examples/multi_select_wrapped.rb +0 -15
  61. data/examples/multiline.rb +0 -9
  62. data/examples/pause.rb +0 -9
  63. data/examples/select.rb +0 -24
  64. data/examples/select_disabled.rb +0 -18
  65. data/examples/select_disabled_paged.rb +0 -22
  66. data/examples/select_enum.rb +0 -8
  67. data/examples/select_filtered.rb +0 -11
  68. data/examples/select_paginated.rb +0 -11
  69. data/examples/select_wrapped.rb +0 -15
  70. data/examples/slider.rb +0 -6
  71. data/examples/validation.rb +0 -9
  72. data/examples/yes_no.rb +0 -7
  73. data/lib/tty/prompt/messages.rb +0 -49
  74. data/lib/tty/test_prompt.rb +0 -20
  75. data/spec/spec_helper.rb +0 -61
  76. data/spec/unit/ask_spec.rb +0 -173
  77. data/spec/unit/block_paginator_spec.rb +0 -84
  78. data/spec/unit/choice/eql_spec.rb +0 -22
  79. data/spec/unit/choice/from_spec.rb +0 -112
  80. data/spec/unit/choices/add_spec.rb +0 -12
  81. data/spec/unit/choices/each_spec.rb +0 -13
  82. data/spec/unit/choices/find_by_spec.rb +0 -10
  83. data/spec/unit/choices/new_spec.rb +0 -10
  84. data/spec/unit/choices/pluck_spec.rb +0 -9
  85. data/spec/unit/collect_spec.rb +0 -96
  86. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  87. data/spec/unit/converters/convert_char_spec.rb +0 -11
  88. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  89. data/spec/unit/converters/convert_date_spec.rb +0 -34
  90. data/spec/unit/converters/convert_file_spec.rb +0 -18
  91. data/spec/unit/converters/convert_number_spec.rb +0 -39
  92. data/spec/unit/converters/convert_path_spec.rb +0 -15
  93. data/spec/unit/converters/convert_range_spec.rb +0 -22
  94. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  95. data/spec/unit/converters/convert_string_spec.rb +0 -21
  96. data/spec/unit/converters/on_error_spec.rb +0 -9
  97. data/spec/unit/distance/distance_spec.rb +0 -73
  98. data/spec/unit/enum_select_spec.rb +0 -518
  99. data/spec/unit/error_spec.rb +0 -20
  100. data/spec/unit/evaluator_spec.rb +0 -67
  101. data/spec/unit/expand_spec.rb +0 -290
  102. data/spec/unit/keypress_spec.rb +0 -66
  103. data/spec/unit/mask_spec.rb +0 -140
  104. data/spec/unit/multi_select_spec.rb +0 -741
  105. data/spec/unit/multiline_spec.rb +0 -77
  106. data/spec/unit/new_spec.rb +0 -20
  107. data/spec/unit/ok_spec.rb +0 -10
  108. data/spec/unit/paginator_spec.rb +0 -92
  109. data/spec/unit/question/checks_spec.rb +0 -97
  110. data/spec/unit/question/default_spec.rb +0 -31
  111. data/spec/unit/question/echo_spec.rb +0 -38
  112. data/spec/unit/question/in_spec.rb +0 -115
  113. data/spec/unit/question/initialize_spec.rb +0 -12
  114. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  115. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  116. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  117. data/spec/unit/question/modify_spec.rb +0 -41
  118. data/spec/unit/question/required_spec.rb +0 -92
  119. data/spec/unit/question/validate_spec.rb +0 -115
  120. data/spec/unit/question/validation/call_spec.rb +0 -31
  121. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  122. data/spec/unit/result_spec.rb +0 -40
  123. data/spec/unit/say_spec.rb +0 -67
  124. data/spec/unit/select_spec.rb +0 -942
  125. data/spec/unit/slider_spec.rb +0 -142
  126. data/spec/unit/statement/initialize_spec.rb +0 -15
  127. data/spec/unit/subscribe_spec.rb +0 -22
  128. data/spec/unit/suggest_spec.rb +0 -28
  129. data/spec/unit/timer_spec.rb +0 -29
  130. data/spec/unit/warn_spec.rb +0 -21
  131. data/spec/unit/yes_no_spec.rb +0 -251
  132. data/tasks/console.rake +0 -11
  133. data/tasks/coverage.rake +0 -11
  134. data/tasks/spec.rake +0 -29
  135. data/tty-prompt.gemspec +0 -31
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert path' do
4
- subject(:prompt) { TTY::TestPrompt.new }
5
-
6
- it "converts pathname" do
7
- path = Pathname.new(::File.join(Dir.pwd, 'spec/unit'))
8
- prompt.input << "spec/unit"
9
- prompt.input.rewind
10
-
11
- answer = prompt.ask('File location?', convert: :path)
12
-
13
- expect(answer).to eql(path)
14
- end
15
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert range' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new}
6
-
7
- it 'converts with valid range' do
8
- prompt.input << "20-30"
9
- prompt.input.rewind
10
- answer = prompt.ask("Which age group?", convert: :range)
11
- expect(answer).to be_a(Range)
12
- expect(answer).to eq(20..30)
13
- end
14
-
15
- it "fails to convert to range" do
16
- prompt.input << "abcd"
17
- prompt.input.rewind
18
- expect {
19
- prompt.ask('Which age group?', convert: :range)
20
- }.to raise_error(TTY::Prompt::ConversionError)
21
- end
22
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert regexp' do
4
- it "converts regex" do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << "[a-z]*"
7
- prompt.input.rewind
8
- answer = prompt.ask("Regex?", convert: :regexp)
9
- expect(answer).to be_a(Regexp)
10
- expect(answer).to eq(/[a-z]*/)
11
- end
12
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Question, 'convert string' do
4
- it 'converts string' do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << 'Piotr'
7
- prompt.input.rewind
8
- answer = prompt.ask("What is your name?", convert: :string)
9
- expect(answer).to be_a(String)
10
- expect(answer).to eq('Piotr')
11
- end
12
-
13
- it "converts symbol" do
14
- prompt = TTY::TestPrompt.new
15
- prompt.input << 'Piotr'
16
- prompt.input.rewind
17
- answer = prompt.ask("What is your name?", convert: :symbol)
18
- expect(answer).to be_a(Symbol)
19
- expect(answer).to eq(:Piotr)
20
- end
21
- end
@@ -1,9 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Converters do
4
- it "enforces block argument" do
5
- expect {
6
- TTY::Prompt::Converters.on_error
7
- }.to raise_error(ArgumentError, 'You need to provide a block argument.')
8
- end
9
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt::Distance, '.distance' do
4
- let(:object) { described_class.new }
5
-
6
- subject(:distance) { object.distance(*strings) }
7
-
8
- context 'when nil' do
9
- let(:strings) { [nil, nil] }
10
-
11
- it { is_expected.to eql(0) }
12
- end
13
-
14
- context 'when empty' do
15
- let(:strings) { ['', ''] }
16
-
17
- it { is_expected.to eql(0) }
18
- end
19
-
20
- context 'with one non empty' do
21
- let(:strings) { ['abc', ''] }
22
-
23
- it { is_expected.to eql(3) }
24
- end
25
-
26
- context 'when single char' do
27
- let(:strings) { ['a', 'abc'] }
28
-
29
- it { is_expected.to eql(2) }
30
- end
31
-
32
- context 'when similar' do
33
- let(:strings) { ['abc', 'abc'] }
34
-
35
- it { is_expected.to eql(0) }
36
- end
37
-
38
- context 'when similar' do
39
- let(:strings) { ['abc', 'acb'] }
40
-
41
- it { is_expected.to eql(1) }
42
- end
43
-
44
- context 'when end similar' do
45
- let(:strings) { ['saturday', 'sunday'] }
46
-
47
- it { is_expected.to eql(3) }
48
- end
49
-
50
- context 'when contain similar' do
51
- let(:strings) { ['which', 'witch'] }
52
-
53
- it { is_expected.to eql(2) }
54
- end
55
-
56
- context 'when prefix' do
57
- let(:strings) { ['sta', 'status'] }
58
-
59
- it { is_expected.to eql(3) }
60
- end
61
-
62
- context 'when similar' do
63
- let(:strings) { ['smellyfish','jellyfish'] }
64
-
65
- it { is_expected.to eql(2) }
66
- end
67
-
68
- context 'when unicode' do
69
- let(:strings) { ['マラソン五輪代表', 'ララソン五輪代表'] }
70
-
71
- it { is_expected.to eql(1) }
72
- end
73
- end
@@ -1,518 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe TTY::Prompt do
4
- let(:symbols) { TTY::Prompt::Symbols.symbols }
5
-
6
- def output_helper(prompt, choices, active, options = {})
7
- enum = options.fetch(:enum, ')')
8
- input = options[:input]
9
- error = options[:error]
10
- default = options.fetch(:default, 1)
11
-
12
- out = []
13
- out << prompt << " \n"
14
- out << choices.map.with_index do |c, i|
15
- name = c.is_a?(Hash) ? c[:name] : c
16
- disabled = c.is_a?(Hash) ? c[:disabled] : false
17
- num = (i + 1).to_s + enum
18
- if disabled
19
- "\e[31m#{symbols[:cross]}\e[0m #{num} #{name} #{disabled}"
20
- elsif name == active
21
- " \e[32m#{num} #{name}\e[0m"
22
- else
23
- " #{num} #{name}"
24
- end
25
- end.join("\n")
26
- out << "\n"
27
- choice = " Choose 1-#{choices.count} [#{default}]: "
28
- choice = choice + input.to_s if input
29
- out << choice
30
- if error
31
- out << "\n"
32
- out << "\e[31m>>\e[0m #{error}"
33
- out << "\e[A\e[1G\e[#{choice.size}C"
34
- end
35
- out << "\e[2K\e[1G\e[1A" * (choices.count + 1)
36
- out << "\e[2K\e[1G\e[J"
37
- out.join
38
- end
39
-
40
- def exit_message(prompt, choice)
41
- "#{prompt} \e[32m#{choice}\e[0m\n"
42
- end
43
-
44
- it "raises configuration error when wrong default" do
45
- prompt = TTY::TestPrompt.new
46
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
47
-
48
- expect {
49
- prompt.enum_select("Select an editor?", choices, default: 100)
50
- }.to raise_error(TTY::Prompt::ConfigurationError,
51
- /default index 100 out of range \(1 - 3\)/)
52
- end
53
-
54
- it "selects default option when return pressed immediately" do
55
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
56
- prompt = TTY::TestPrompt.new
57
- prompt.input << "\n"
58
- prompt.input.rewind
59
-
60
- answer = prompt.enum_select("Select an editor?", choices)
61
- expect(answer).to eq('/bin/nano')
62
-
63
- expected_output = [
64
- output_helper("Select an editor?", choices, "/bin/nano"),
65
- exit_message("Select an editor?", "/bin/nano")
66
- ].join
67
-
68
- expect(prompt.output.string).to eq(expected_output)
69
- end
70
-
71
- it "selects option by index from the list" do
72
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
73
- prompt = TTY::TestPrompt.new
74
- prompt.input << "3\n"
75
- prompt.input.rewind
76
-
77
- answer = prompt.enum_select("Select an editor?", choices, default: 2)
78
- expect(answer).to eq('/usr/bin/vim.tiny')
79
-
80
- expected_output = [
81
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", default: 2),
82
- output_helper("Select an editor?", choices, "/usr/bin/vim.tiny", default: 2, input: '3'),
83
- exit_message("Select an editor?", "/usr/bin/vim.tiny")
84
- ].join
85
-
86
- expect(prompt.output.string).to eq(expected_output)
87
- end
88
-
89
- it "selects option through DSL" do
90
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
91
- prompt = TTY::TestPrompt.new
92
- prompt.input << "1\n"
93
- prompt.input.rewind
94
- answer = prompt.enum_select("Select an editor?") do |menu|
95
- menu.default 2
96
- menu.enum '.'
97
-
98
- menu.choice "/bin/nano"
99
- menu.choice "/usr/bin/vim.basic"
100
- menu.choice "/usr/bin/vim.tiny"
101
- end
102
- expect(answer).to eq('/bin/nano')
103
-
104
- expected_output = [
105
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", default: 2, enum: '.'),
106
- output_helper("Select an editor?", choices, "/bin/nano", default: 2, enum: '.', input: 1),
107
- exit_message("Select an editor?", "/bin/nano")
108
- ].join
109
-
110
- expect(prompt.output.string).to eq(expected_output)
111
- end
112
-
113
- it "selects option through DSL with key and value" do
114
- choices = %w(nano vim emacs)
115
- prompt = TTY::TestPrompt.new
116
- prompt.input << "\n"
117
- prompt.input.rewind
118
-
119
- answer = prompt.enum_select("Select an editor?") do |menu|
120
- menu.default 2
121
-
122
- menu.choice :nano, '/bin/nano'
123
- menu.choice :vim, '/usr/bin/vim'
124
- menu.choice :emacs, '/usr/bin/emacs'
125
- end
126
-
127
- expect(answer).to eq('/usr/bin/vim')
128
-
129
- expected_output = [
130
- output_helper("Select an editor?", choices, "vim", default: 2),
131
- exit_message("Select an editor?", "vim")
132
- ].join
133
-
134
- expect(prompt.output.string).to eq(expected_output)
135
- end
136
-
137
- it "changes colors for selection, hint and error" do
138
- prompt = TTY::TestPrompt.new
139
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
140
- prompt.input << "\n"
141
- prompt.input.rewind
142
- options = {active_color: :red, help_color: :blue, error_color: :green}
143
-
144
- answer = prompt.enum_select("Select an editor?", choices, options)
145
-
146
- expect(answer).to eq('/bin/nano')
147
-
148
- expected_output = [
149
- "Select an editor? \n",
150
- " \e[31m1) /bin/nano\e[0m\n",
151
- " 2) /usr/bin/vim.basic\n",
152
- " 3) /usr/bin/vim.tiny\n",
153
- " Choose 1-3 [1]: ",
154
- "\e[2K\e[1G\e[1A" * 4,
155
- "\e[2K\e[1G\e[J",
156
- "Select an editor? \e[31m/bin/nano\e[0m\n"
157
- ].join
158
-
159
- expect(prompt.output.string).to eq(expected_output)
160
- end
161
-
162
- it "changes global symbols" do
163
- prompt = TTY::TestPrompt.new(symbols: {cross: 'x'})
164
- choices = ['A', {name: 'B', disabled: '(out)'}, 'C']
165
- prompt.input << "\n"
166
- prompt.input.rewind
167
- answer = prompt.enum_select("What letter?", choices)
168
- expect(answer).to eq("A")
169
-
170
- expected_output = [
171
- "What letter? \n",
172
- " \e[32m1) A\e[0m\n",
173
- "\e[31mx\e[0m 2) B (out)\n",
174
- " 3) C\n",
175
- " Choose 1-3 [1]: ",
176
- "\e[2K\e[1G\e[1A" * 4,
177
- "\e[2K\e[1G\e[J",
178
- "What letter? \e[32mA\e[0m\n",
179
- ].join
180
-
181
- expect(prompt.output.string).to eq(expected_output)
182
- end
183
-
184
- it "changes global symbols through DSL" do
185
- prompt = TTY::TestPrompt.new
186
- choices = ['A', {name: 'B', disabled: '(out)'}, 'C']
187
- prompt.input << "\n"
188
- prompt.input.rewind
189
- answer = prompt.enum_select("What letter?", choices) do |menu|
190
- menu.symbols cross: 'x'
191
- menu.choices choices
192
- end
193
- expect(answer).to eq("A")
194
-
195
- expected_output = [
196
- "What letter? \n",
197
- " \e[32m1) A\e[0m\n",
198
- "\e[31mx\e[0m 2) B (out)\n",
199
- " 3) C\n",
200
- " Choose 1-3 [1]: ",
201
- "\e[2K\e[1G\e[1A" * 4,
202
- "\e[2K\e[1G\e[J",
203
- "What letter? \e[32mA\e[0m\n",
204
- ].join
205
-
206
- expect(prompt.output.string).to eq(expected_output)
207
- end
208
-
209
- it "displays error with unrecognized input" do
210
- choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
211
- prompt = TTY::TestPrompt.new
212
- prompt.input << "11\n2\n"
213
- prompt.input.rewind
214
-
215
- answer = prompt.enum_select("Select an editor?", choices)
216
- expect(answer).to eq('/usr/bin/vim.basic')
217
-
218
- expected_output = [
219
- output_helper("Select an editor?", choices, "/bin/nano"),
220
- output_helper("Select an editor?", choices, "/bin/nano", input: '1'),
221
- output_helper("Select an editor?", choices, "/bin/nano", input: '11'),
222
- output_helper("Select an editor?", choices, "/bin/nano", error: 'Please enter a valid number', input: ''),
223
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", error: 'Please enter a valid number', input: '2'),
224
- exit_message("Select an editor?", "/usr/bin/vim.basic")
225
- ].join
226
-
227
- expect(prompt.output.string).to eq(expected_output)
228
- end
229
-
230
- it "paginates long selections" do
231
- choices = %w(A B C D E F G H)
232
- prompt = TTY::TestPrompt.new
233
- prompt.input << "\n"
234
- prompt.input.rewind
235
-
236
- answer = prompt.enum_select("What letter?", choices, per_page: 3, default: 4)
237
- expect(answer).to eq('D')
238
-
239
- expect(prompt.output.string).to eq([
240
- "What letter? \n",
241
- " \e[32m4) D\e[0m\n",
242
- " 5) E\n",
243
- " 6) F\n",
244
- " Choose 1-8 [4]: ",
245
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
246
- "\e[A\e[1G\e[18C",
247
- "\e[2K\e[1G\e[1A" * 4,
248
- "\e[2K\e[1G\e[J",
249
- "What letter? \e[32mD\e[0m\n"
250
- ].join)
251
- end
252
-
253
- it "doesn't paginate short selections" do
254
- choices = %i(A B C D)
255
- prompt = TTY::TestPrompt.new
256
- prompt.input << "\r"
257
- prompt.input.rewind
258
-
259
- answer = prompt.enum_select("What letter?", choices, per_page: 4, default: 1)
260
- expect(answer).to eq(:A)
261
-
262
- expected_output =
263
- output_helper("What letter?", choices, :A) +
264
- exit_message("What letter?", :A)
265
-
266
- expect(prompt.output.string).to eq(expected_output)
267
- end
268
-
269
- it "shows pages matching input" do
270
- prompt = TTY::TestPrompt.new
271
- choices = %w(A B C D E F G H)
272
- prompt.input << "11\n\b\n"
273
- prompt.input.rewind
274
- value = prompt.enum_select("What letter?", choices, per_page: 3)
275
- expect(value).to eq('A')
276
- expect(prompt.output.string).to eq([
277
- "What letter? \n",
278
- " \e[32m1) A\e[0m\n",
279
- " 2) B\n",
280
- " 3) C\n",
281
- " Choose 1-8 [1]: ",
282
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
283
- "\e[A\e[1G\e[18C",
284
- "\e[2K\e[1G\e[1A" * 4,
285
- "\e[2K\e[1G\e[J",
286
- "What letter? \n",
287
- " \e[32m1) A\e[0m\n",
288
- " 2) B\n",
289
- " 3) C\n",
290
- " Choose 1-8 [1]: 1",
291
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
292
- "\e[A\e[1G\e[19C",
293
- "\e[2K\e[1G\e[1A" * 4,
294
- "\e[2K\e[1G\e[J",
295
- "What letter? \n",
296
- " \e[32m1) A\e[0m\n",
297
- " 2) B\n",
298
- " 3) C\n",
299
- " Choose 1-8 [1]: 11",
300
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
301
- "\e[A\e[1G\e[20C",
302
- "\e[2K\e[1G\e[1A" * 4,
303
- "\e[2K\e[1G\e[J",
304
- "What letter? \n",
305
- " \e[32m1) A\e[0m\n",
306
- " 2) B\n",
307
- " 3) C\n",
308
- " Choose 1-8 [1]: \n",
309
- "\e[31m>>\e[0m Please enter a valid number",
310
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
311
- "\e[A\e[1G\e[A\e[1G\e[18C",
312
- "\e[2K\e[1G\e[1A" * 4,
313
- "\e[2K\e[1G\e[J",
314
- "What letter? \n",
315
- " \e[32m1) A\e[0m\n",
316
- " 2) B\n",
317
- " 3) C\n",
318
- " Choose 1-8 [1]: \n",
319
- "\e[31m>>\e[0m Please enter a valid number",
320
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
321
- "\e[A\e[1G\e[A\e[1G\e[18C",
322
- "\e[2K\e[1G\e[1A" * 4,
323
- "\e[2K\e[1G\e[J",
324
- "What letter? \e[32mA\e[0m\n"
325
- ].join)
326
- end
327
-
328
- it "switches through pages with tab key" do
329
- prompt = TTY::TestPrompt.new
330
- choices = %w(A B C D E F G H)
331
- prompt.input << "\t\n"
332
- prompt.input.rewind
333
- value = prompt.enum_select("What letter?") do |menu|
334
- menu.default 4
335
- menu.per_page 3
336
- menu.choices choices
337
- end
338
- expect(value).to eq('D')
339
- expect(prompt.output.string).to eq([
340
- "What letter? \n",
341
- " \e[32m4) D\e[0m\n",
342
- " 5) E\n",
343
- " 6) F\n",
344
- " Choose 1-8 [4]: ",
345
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
346
- "\e[A\e[1G\e[18C",
347
- "\e[2K\e[1G\e[1A" * 4,
348
- "\e[2K\e[1G\e[J",
349
- "What letter? \n",
350
- " 7) G\n",
351
- " 8) H\n",
352
- " Choose 1-8 [4]: ",
353
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
354
- "\e[A\e[1G\e[18C",
355
- "\e[2K\e[1G\e[1A" * 3,
356
- "\e[2K\e[1G\e[J",
357
- "What letter? \e[32mD\e[0m\n"
358
- ].join)
359
- end
360
-
361
- it "doesn't cycle around by default" do
362
- prompt = TTY::TestPrompt.new
363
- choices = %w(A B C D E F)
364
- prompt.input << "\t" << "\t" << "\n"
365
- prompt.input.rewind
366
- value = prompt.enum_select("What letter?") do |menu|
367
- menu.default 1
368
- menu.per_page 3
369
- menu.choices choices
370
- end
371
- expect(value).to eq("A")
372
- expect(prompt.output.string).to eq([
373
- "What letter? \n",
374
- " \e[32m1) A\e[0m\n",
375
- " 2) B\n",
376
- " 3) C\n",
377
- " Choose 1-6 [1]: ",
378
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
379
- "\e[A\e[1G\e[18C",
380
- "\e[2K\e[1G\e[1A" * 4,
381
- "\e[2K\e[1G\e[J",
382
- "What letter? \n",
383
- " 4) D\n",
384
- " 5) E\n",
385
- " 6) F\n",
386
- " Choose 1-6 [1]: ",
387
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
388
- "\e[A\e[1G\e[18C",
389
- "\e[2K\e[1G\e[1A" * 4,
390
- "\e[2K\e[1G\e[J",
391
- "What letter? \n",
392
- " 4) D\n",
393
- " 5) E\n",
394
- " 6) F\n",
395
- " Choose 1-6 [1]: ",
396
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
397
- "\e[A\e[1G\e[18C",
398
- "\e[2K\e[1G\e[1A" * 4,
399
- "\e[2K\e[1G\e[J",
400
- "What letter? \e[32mA\e[0m\n"
401
- ].join)
402
- end
403
-
404
- it "cycles around when configured to do so" do
405
- prompt = TTY::TestPrompt.new
406
- choices = %w(A B C D E F)
407
- prompt.input << "\t" << "\t" << "\n"
408
- prompt.input.rewind
409
- value = prompt.enum_select("What letter?", cycle: true) do |menu|
410
- menu.default 1
411
- menu.per_page 3
412
- menu.choices choices
413
- end
414
- expect(value).to eq("A")
415
-
416
- expect(prompt.output.string).to eq([
417
- "What letter? \n",
418
- " \e[32m1) A\e[0m\n",
419
- " 2) B\n",
420
- " 3) C\n",
421
- " Choose 1-6 [1]: ",
422
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
423
- "\e[A\e[1G\e[18C",
424
- "\e[2K\e[1G\e[1A" * 4,
425
- "\e[2K\e[1G\e[J",
426
- "What letter? \n",
427
- " 4) D\n",
428
- " 5) E\n",
429
- " 6) F\n",
430
- " Choose 1-6 [1]: ",
431
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
432
- "\e[A\e[1G\e[18C",
433
- "\e[2K\e[1G\e[1A" * 4,
434
- "\e[2K\e[1G\e[J",
435
- "What letter? \n",
436
- " \e[32m1) A\e[0m\n",
437
- " 2) B\n",
438
- " 3) C\n",
439
- " Choose 1-6 [1]: ",
440
- "\n\e[90m(Press tab/right or left to reveal more choices)\e[0m",
441
- "\e[A\e[1G\e[18C",
442
- "\e[2K\e[1G\e[1A" * 4,
443
- "\e[2K\e[1G\e[J",
444
- "What letter? \e[32mA\e[0m\n"
445
- ].join)
446
- end
447
-
448
- context "with :disabled choice" do
449
- it "fails when active item is also disabled" do
450
- prompt = TTY::TestPrompt.new
451
- choices = [{name: 'A', disabled: true}, 'B', 'C', 'D', 'E']
452
- expect {
453
- prompt.enum_select("What letter?", choices, default: 1)
454
- }.to raise_error(TTY::Prompt::ConfigurationError,
455
- /default index 1 matches disabled choice item/)
456
- end
457
-
458
- it "finds first non-disabled index" do
459
- prompt = TTY::TestPrompt.new
460
- choices = [{name: 'A', disabled: true}, {name:'B', disabled: true}, 'C', 'D']
461
- prompt = TTY::TestPrompt.new
462
- prompt.input << "\n"
463
- prompt.input.rewind
464
-
465
- answer = prompt.enum_select("What letter?", choices)
466
- expect(answer).to eq('C')
467
- end
468
-
469
- it "doesn't allow to choose disabled choice and defaults" do
470
- choices = ['A', {name: 'B', disabled: '(out)'}, 'C', 'D', 'E', 'F']
471
- prompt = TTY::TestPrompt.new
472
- prompt.input << "2" << "\n" << "3" << "\n"
473
- prompt.input.rewind
474
-
475
- answer = prompt.enum_select("What letter?", choices)
476
- expect(answer).to eq("C")
477
-
478
- expected_output = [
479
- output_helper("What letter?", choices, 'A'),
480
- output_helper("What letter?", choices, 'A', input: '2'),
481
- output_helper("What letter?", choices, 'A', input: '', error: 'Please enter a valid number'),
482
- output_helper("What letter?", choices, 'C', input: '3', error: 'Please enter a valid number'),
483
- exit_message("What letter?", "C")
484
- ].join
485
-
486
- expect(prompt.output.string).to eq(expected_output)
487
- end
488
-
489
- it "omits disabled choice when navigating with numbers" do
490
- choices = [
491
- {name: 'A'},
492
- {name: 'B', disabled: '(out)'},
493
- {name: 'C', disabled: '(out)'},
494
- {name: 'D'},
495
- {name: 'E'}
496
- ]
497
- prompt = TTY::TestPrompt.new
498
- prompt.on(:keypress) { |e| prompt.trigger(:keydelete) if e.value == "B"}
499
- prompt.input << "2" << "\u007F" << "3" << "\u007F" << '4' << "\n"
500
- prompt.input.rewind
501
-
502
- answer = prompt.enum_select("What letter?", choices)
503
- expect(answer).to eq("D")
504
-
505
- expected_output = [
506
- output_helper("What letter?", choices, 'A'),
507
- output_helper("What letter?", choices, 'A', input: '2'),
508
- output_helper("What letter?", choices, 'A', input: ''),
509
- output_helper("What letter?", choices, 'A', input: '3'),
510
- output_helper("What letter?", choices, 'A', input: ''),
511
- output_helper("What letter?", choices, 'D', input: '4'),
512
- exit_message("What letter?", "D")
513
- ].join
514
-
515
- expect(prompt.output.string).to eq(expected_output)
516
- end
517
- end
518
- end