tty-prompt 0.19.0 → 0.23.1

Sign up to get free protection for your applications and to get access to all the features.
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