tty-prompt 0.16.1 → 0.17.0
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/tty/prompt/messages.rb +49 -0
- data/lib/tty/prompt/version.rb +1 -3
- data/spec/spec_helper.rb +45 -0
- data/spec/unit/ask_spec.rb +132 -0
- data/spec/unit/choice/eql_spec.rb +22 -0
- data/spec/unit/choice/from_spec.rb +96 -0
- data/spec/unit/choices/add_spec.rb +12 -0
- data/spec/unit/choices/each_spec.rb +13 -0
- data/spec/unit/choices/find_by_spec.rb +10 -0
- data/spec/unit/choices/new_spec.rb +10 -0
- data/spec/unit/choices/pluck_spec.rb +9 -0
- data/spec/unit/collect_spec.rb +96 -0
- data/spec/unit/converters/convert_bool_spec.rb +58 -0
- data/spec/unit/converters/convert_char_spec.rb +11 -0
- data/spec/unit/converters/convert_custom_spec.rb +14 -0
- data/spec/unit/converters/convert_date_spec.rb +34 -0
- data/spec/unit/converters/convert_file_spec.rb +18 -0
- data/spec/unit/converters/convert_number_spec.rb +39 -0
- data/spec/unit/converters/convert_path_spec.rb +15 -0
- data/spec/unit/converters/convert_range_spec.rb +22 -0
- data/spec/unit/converters/convert_regex_spec.rb +12 -0
- data/spec/unit/converters/convert_string_spec.rb +21 -0
- data/spec/unit/converters/on_error_spec.rb +9 -0
- data/spec/unit/distance/distance_spec.rb +73 -0
- data/spec/unit/enum_paginator_spec.rb +75 -0
- data/spec/unit/enum_select_spec.rb +446 -0
- data/spec/unit/error_spec.rb +20 -0
- data/spec/unit/evaluator_spec.rb +67 -0
- data/spec/unit/expand_spec.rb +198 -0
- data/spec/unit/keypress_spec.rb +72 -0
- data/spec/unit/mask_spec.rb +132 -0
- data/spec/unit/multi_select_spec.rb +495 -0
- data/spec/unit/multiline_spec.rb +77 -0
- data/spec/unit/new_spec.rb +20 -0
- data/spec/unit/ok_spec.rb +10 -0
- data/spec/unit/paginator_spec.rb +73 -0
- data/spec/unit/question/checks_spec.rb +97 -0
- data/spec/unit/question/default_spec.rb +31 -0
- data/spec/unit/question/echo_spec.rb +38 -0
- data/spec/unit/question/in_spec.rb +115 -0
- data/spec/unit/question/initialize_spec.rb +12 -0
- data/spec/unit/question/modifier/apply_to_spec.rb +24 -0
- data/spec/unit/question/modifier/letter_case_spec.rb +41 -0
- data/spec/unit/question/modifier/whitespace_spec.rb +51 -0
- data/spec/unit/question/modify_spec.rb +41 -0
- data/spec/unit/question/required_spec.rb +92 -0
- data/spec/unit/question/validate_spec.rb +115 -0
- data/spec/unit/question/validation/call_spec.rb +31 -0
- data/spec/unit/question/validation/coerce_spec.rb +30 -0
- data/spec/unit/result_spec.rb +40 -0
- data/spec/unit/say_spec.rb +67 -0
- data/spec/unit/select_spec.rb +624 -0
- data/spec/unit/slider_spec.rb +100 -0
- data/spec/unit/statement/initialize_spec.rb +15 -0
- data/spec/unit/subscribe_spec.rb +20 -0
- data/spec/unit/suggest_spec.rb +28 -0
- data/spec/unit/warn_spec.rb +21 -0
- data/spec/unit/yes_no_spec.rb +235 -0
- data/tty-prompt.gemspec +4 -6
- metadata +120 -15
- data/.gitignore +0 -16
- data/.rspec +0 -3
- data/.travis.yml +0 -27
- data/CHANGELOG.md +0 -289
- data/CODE_OF_CONDUCT.md +0 -49
- data/Gemfile +0 -21
- data/appveyor.yml +0 -22
- data/benchmarks/speed.rb +0 -27
@@ -0,0 +1,495 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Prompt do
|
4
|
+
let(:symbols) { TTY::Prompt::Symbols.symbols }
|
5
|
+
|
6
|
+
def output_helper(prompt, choices, active, selected, options = {})
|
7
|
+
raise ":init requires :hint" if options[:init] && options[:hint].nil?
|
8
|
+
hint = options[:hint]
|
9
|
+
init = options.fetch(:init, false)
|
10
|
+
enum = options[:enum]
|
11
|
+
|
12
|
+
out = ""
|
13
|
+
out << "\e[?25l" if init
|
14
|
+
out << prompt << " "
|
15
|
+
out << selected.join(', ')
|
16
|
+
out << "\e[90m" if init
|
17
|
+
out << (init ? "(#{hint})\e[0m" : " (#{hint})") if hint
|
18
|
+
out << "\n"
|
19
|
+
out << choices.map.with_index do |choice, i|
|
20
|
+
name = choice.is_a?(Hash) ? choice[:name] : choice
|
21
|
+
disabled = choice.is_a?(Hash) ? choice[:disabled] : false
|
22
|
+
num = (i + 1).to_s + enum if enum
|
23
|
+
|
24
|
+
prefix = name == active ? "#{symbols[:pointer]} " : " "
|
25
|
+
prefix += if disabled
|
26
|
+
"\e[31m#{symbols[:cross]}\e[0m #{num}#{name} #{disabled}"
|
27
|
+
elsif selected.include?(name)
|
28
|
+
"\e[32m#{symbols[:radio_on]}\e[0m #{num}#{name}"
|
29
|
+
else
|
30
|
+
"#{symbols[:radio_off]} #{num}#{name}"
|
31
|
+
end
|
32
|
+
prefix
|
33
|
+
end.join("\n")
|
34
|
+
out << "\e[2K\e[1G\e[1A" * choices.count
|
35
|
+
out << "\e[2K\e[1G"
|
36
|
+
out
|
37
|
+
end
|
38
|
+
|
39
|
+
def exit_message(prompt, choices)
|
40
|
+
"#{prompt} \e[32m#{choices.join(', ')}\e[0m\n\e[?25h"
|
41
|
+
end
|
42
|
+
|
43
|
+
# Ensure a wide prompt on CI
|
44
|
+
before { allow(TTY::Screen).to receive(:width).and_return(200) }
|
45
|
+
|
46
|
+
it "selects nothing when return pressed immediately" do
|
47
|
+
prompt = TTY::TestPrompt.new
|
48
|
+
choices = %w(vodka beer wine whisky bourbon)
|
49
|
+
prompt.input << "\r"
|
50
|
+
prompt.input.rewind
|
51
|
+
expect(prompt.multi_select("Select drinks?", choices)). to eq([])
|
52
|
+
expect(prompt.output.string).to eq([
|
53
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
54
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
55
|
+
" #{symbols[:radio_off]} beer\n",
|
56
|
+
" #{symbols[:radio_off]} wine\n",
|
57
|
+
" #{symbols[:radio_off]} whisky\n",
|
58
|
+
" #{symbols[:radio_off]} bourbon",
|
59
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
60
|
+
"Select drinks? \n\e[?25h"
|
61
|
+
].join)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "selects item when space pressed" do
|
65
|
+
prompt = TTY::TestPrompt.new
|
66
|
+
choices = %w(vodka beer wine whisky bourbon)
|
67
|
+
prompt.input << " \r"
|
68
|
+
prompt.input.rewind
|
69
|
+
expect(prompt.multi_select("Select drinks?", choices)). to eq(['vodka'])
|
70
|
+
expect(prompt.output.string).to eq([
|
71
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
72
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
73
|
+
" #{symbols[:radio_off]} beer\n",
|
74
|
+
" #{symbols[:radio_off]} wine\n",
|
75
|
+
" #{symbols[:radio_off]} whisky\n",
|
76
|
+
" #{symbols[:radio_off]} bourbon",
|
77
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
78
|
+
"Select drinks? vodka\n",
|
79
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
|
80
|
+
" #{symbols[:radio_off]} beer\n",
|
81
|
+
" #{symbols[:radio_off]} wine\n",
|
82
|
+
" #{symbols[:radio_off]} whisky\n",
|
83
|
+
" #{symbols[:radio_off]} bourbon",
|
84
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
85
|
+
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
|
86
|
+
].join)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "selects item when space pressed but doesn't echo item if echo: false" do
|
90
|
+
prompt = TTY::TestPrompt.new
|
91
|
+
choices = %w(vodka beer wine whisky bourbon)
|
92
|
+
prompt.input << " \r"
|
93
|
+
prompt.input.rewind
|
94
|
+
expect(prompt.multi_select("Select drinks?", choices, echo: false)). to eq(['vodka'])
|
95
|
+
expect(prompt.output.string).to eq([
|
96
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
97
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
98
|
+
" #{symbols[:radio_off]} beer\n",
|
99
|
+
" #{symbols[:radio_off]} wine\n",
|
100
|
+
" #{symbols[:radio_off]} whisky\n",
|
101
|
+
" #{symbols[:radio_off]} bourbon",
|
102
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
103
|
+
"Select drinks? \n",
|
104
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
|
105
|
+
" #{symbols[:radio_off]} beer\n",
|
106
|
+
" #{symbols[:radio_off]} wine\n",
|
107
|
+
" #{symbols[:radio_off]} whisky\n",
|
108
|
+
" #{symbols[:radio_off]} bourbon",
|
109
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
110
|
+
"Select drinks? \n\e[?25h"
|
111
|
+
].join)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "sets choice custom values" do
|
115
|
+
prompt = TTY::TestPrompt.new
|
116
|
+
choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
|
117
|
+
prompt.input << " \r"
|
118
|
+
prompt.input.rewind
|
119
|
+
expect(prompt.multi_select("Select drinks?", choices)).to eq([1])
|
120
|
+
expect(prompt.output.string).to eq([
|
121
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
122
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
123
|
+
" #{symbols[:radio_off]} beer\n",
|
124
|
+
" #{symbols[:radio_off]} wine\n",
|
125
|
+
" #{symbols[:radio_off]} whisky\n",
|
126
|
+
" #{symbols[:radio_off]} bourbon",
|
127
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
128
|
+
"Select drinks? vodka\n",
|
129
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
|
130
|
+
" #{symbols[:radio_off]} beer\n",
|
131
|
+
" #{symbols[:radio_off]} wine\n",
|
132
|
+
" #{symbols[:radio_off]} whisky\n",
|
133
|
+
" #{symbols[:radio_off]} bourbon",
|
134
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
135
|
+
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
|
136
|
+
].join)
|
137
|
+
end
|
138
|
+
|
139
|
+
it "sets choice name and value through DSL" do
|
140
|
+
prompt = TTY::TestPrompt.new
|
141
|
+
prompt.input << " \r"
|
142
|
+
prompt.input.rewind
|
143
|
+
value = prompt.multi_select("Select drinks?") do |menu|
|
144
|
+
menu.enum ')'
|
145
|
+
|
146
|
+
menu.choice :vodka, {score: 1}
|
147
|
+
menu.choice :beer, 2
|
148
|
+
menu.choice :wine, 3
|
149
|
+
menu.choices whisky: 4, bourbon: 5
|
150
|
+
end
|
151
|
+
expect(value).to eq([{score: 1}])
|
152
|
+
expect(prompt.output.string).to eq([
|
153
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow or number (1-5) keys, press Space to select and Enter to finish)\e[0m\n",
|
154
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} 1) vodka\n",
|
155
|
+
" #{symbols[:radio_off]} 2) beer\n",
|
156
|
+
" #{symbols[:radio_off]} 3) wine\n",
|
157
|
+
" #{symbols[:radio_off]} 4) whisky\n",
|
158
|
+
" #{symbols[:radio_off]} 5) bourbon",
|
159
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
160
|
+
"Select drinks? vodka\n",
|
161
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m 1) vodka\n",
|
162
|
+
" #{symbols[:radio_off]} 2) beer\n",
|
163
|
+
" #{symbols[:radio_off]} 3) wine\n",
|
164
|
+
" #{symbols[:radio_off]} 4) whisky\n",
|
165
|
+
" #{symbols[:radio_off]} 5) bourbon",
|
166
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
167
|
+
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
|
168
|
+
].join)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "sets default options through DSL syntax" do
|
172
|
+
prompt = TTY::TestPrompt.new
|
173
|
+
prompt.input << "\r"
|
174
|
+
prompt.input.rewind
|
175
|
+
value = prompt.multi_select("Select drinks?") do |menu|
|
176
|
+
menu.default 2, 5
|
177
|
+
|
178
|
+
menu.choice :vodka, {score: 10}
|
179
|
+
menu.choice :beer, {score: 20}
|
180
|
+
menu.choice :wine, {score: 30}
|
181
|
+
menu.choice :whisky, {score: 40}
|
182
|
+
menu.choice :bourbon, {score: 50}
|
183
|
+
end
|
184
|
+
expect(value).to match_array([{score: 20}, {score: 50}])
|
185
|
+
expect(prompt.output.string).to eq([
|
186
|
+
"\e[?25lSelect drinks? beer, bourbon \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
187
|
+
" #{symbols[:radio_off]} vodka\n",
|
188
|
+
" \e[32m#{symbols[:radio_on]}\e[0m beer\n",
|
189
|
+
" #{symbols[:radio_off]} wine\n",
|
190
|
+
" #{symbols[:radio_off]} whisky\n",
|
191
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m bourbon",
|
192
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
193
|
+
"Select drinks? \e[32mbeer, bourbon\e[0m\n\e[?25h",
|
194
|
+
].join)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "sets default options through hash syntax" do
|
198
|
+
prompt = TTY::TestPrompt.new
|
199
|
+
prompt.input << "\r"
|
200
|
+
prompt.input.rewind
|
201
|
+
value = prompt.multi_select("Select drinks?", default: [2, 5]) do |menu|
|
202
|
+
menu.choice :vodka, {score: 10}
|
203
|
+
menu.choice :beer, {score: 20}
|
204
|
+
menu.choice :wine, {score: 30}
|
205
|
+
menu.choice :whisky, {score: 40}
|
206
|
+
menu.choice :bourbon, {score: 50}
|
207
|
+
end
|
208
|
+
expect(value).to match_array([{score: 20}, {score: 50}])
|
209
|
+
end
|
210
|
+
|
211
|
+
it "raises error for defaults out of range" do
|
212
|
+
prompt = TTY::TestPrompt.new
|
213
|
+
prompt.input << "\r"
|
214
|
+
prompt.input.rewind
|
215
|
+
expect {
|
216
|
+
prompt.multi_select("Select drinks?", default: [2, 6]) do |menu|
|
217
|
+
menu.choice :vodka, {score: 10}
|
218
|
+
menu.choice :beer, {score: 20}
|
219
|
+
menu.choice :wine, {score: 30}
|
220
|
+
menu.choice :whisky, {score: 40}
|
221
|
+
menu.choice :bourbon, {score: 50}
|
222
|
+
end
|
223
|
+
}.to raise_error(TTY::Prompt::ConfigurationError,
|
224
|
+
/default index `6` out of range \(1 - 5\)/)
|
225
|
+
end
|
226
|
+
|
227
|
+
it "sets prompt prefix" do
|
228
|
+
prompt = TTY::TestPrompt.new(prefix: '[?] ')
|
229
|
+
choices = %w(vodka beer wine whisky bourbon)
|
230
|
+
prompt.input << "\r"
|
231
|
+
prompt.input.rewind
|
232
|
+
expect(prompt.multi_select("Select drinks?", choices)). to eq([])
|
233
|
+
expect(prompt.output.string).to eq([
|
234
|
+
"\e[?25l[?] Select drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
235
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
236
|
+
" #{symbols[:radio_off]} beer\n",
|
237
|
+
" #{symbols[:radio_off]} wine\n",
|
238
|
+
" #{symbols[:radio_off]} whisky\n",
|
239
|
+
" #{symbols[:radio_off]} bourbon",
|
240
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
241
|
+
"[?] Select drinks? \n\e[?25h"
|
242
|
+
].join)
|
243
|
+
end
|
244
|
+
|
245
|
+
it "changes selected item color & marker" do
|
246
|
+
prompt = TTY::TestPrompt.new
|
247
|
+
choices = %w(vodka beer wine whisky bourbon)
|
248
|
+
prompt.input << "\r"
|
249
|
+
prompt.input.rewind
|
250
|
+
options = {default: [1], active_color: :blue, marker: '>'}
|
251
|
+
expect(prompt.multi_select("Select drinks?", choices, options)). to eq(['vodka'])
|
252
|
+
expect(prompt.output.string).to eq([
|
253
|
+
"\e[?25lSelect drinks? vodka \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
254
|
+
"> \e[34m#{symbols[:radio_on]}\e[0m vodka\n",
|
255
|
+
" #{symbols[:radio_off]} beer\n",
|
256
|
+
" #{symbols[:radio_off]} wine\n",
|
257
|
+
" #{symbols[:radio_off]} whisky\n",
|
258
|
+
" #{symbols[:radio_off]} bourbon",
|
259
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
260
|
+
"Select drinks? \e[34mvodka\e[0m\n\e[?25h"
|
261
|
+
].join)
|
262
|
+
end
|
263
|
+
|
264
|
+
it "changes help text" do
|
265
|
+
prompt = TTY::TestPrompt.new
|
266
|
+
choices = %w(vodka beer wine whisky bourbon)
|
267
|
+
prompt.input << "\r"
|
268
|
+
prompt.input.rewind
|
269
|
+
expect(prompt.multi_select("Select drinks?", choices, help: '(Bash keyboard)')). to eq([])
|
270
|
+
expect(prompt.output.string).to eq([
|
271
|
+
"\e[?25lSelect drinks? \e[90m(Bash keyboard)\e[0m\n",
|
272
|
+
"#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
|
273
|
+
" #{symbols[:radio_off]} beer\n",
|
274
|
+
" #{symbols[:radio_off]} wine\n",
|
275
|
+
" #{symbols[:radio_off]} whisky\n",
|
276
|
+
" #{symbols[:radio_off]} bourbon",
|
277
|
+
"\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
|
278
|
+
"Select drinks? \n\e[?25h"
|
279
|
+
].join)
|
280
|
+
end
|
281
|
+
|
282
|
+
it "paginates long selections" do
|
283
|
+
prompt = TTY::TestPrompt.new
|
284
|
+
choices = %w(A B C D E F G H)
|
285
|
+
prompt.input << "\r"
|
286
|
+
prompt.input.rewind
|
287
|
+
value = prompt.multi_select("What letter?", choices, per_page: 3, default: 4)
|
288
|
+
expect(value).to eq(['D'])
|
289
|
+
expect(prompt.output.string).to eq([
|
290
|
+
"\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
291
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
|
292
|
+
" #{symbols[:radio_off]} E\n",
|
293
|
+
" #{symbols[:radio_off]} F\n",
|
294
|
+
"\e[90m(Move up or down to reveal more choices)\e[0m",
|
295
|
+
"\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
|
296
|
+
"What letter? \e[32mD\e[0m\n\e[?25h",
|
297
|
+
].join)
|
298
|
+
end
|
299
|
+
|
300
|
+
it "paginates choices as hash object" do
|
301
|
+
prompt = TTY::TestPrompt.new
|
302
|
+
choices = {A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7, H: 8}
|
303
|
+
prompt.input << "\r"
|
304
|
+
prompt.input.rewind
|
305
|
+
value = prompt.multi_select("What letter?", choices, default: 4, per_page: 3)
|
306
|
+
expect(value).to eq([4])
|
307
|
+
expect(prompt.output.string).to eq([
|
308
|
+
"\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
309
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
|
310
|
+
" #{symbols[:radio_off]} E\n",
|
311
|
+
" #{symbols[:radio_off]} F\n",
|
312
|
+
"\e[90m(Move up or down to reveal more choices)\e[0m",
|
313
|
+
"\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
|
314
|
+
"What letter? \e[32mD\e[0m\n\e[?25h",
|
315
|
+
].join)
|
316
|
+
end
|
317
|
+
|
318
|
+
it "paginates long selections through DSL" do
|
319
|
+
prompt = TTY::TestPrompt.new
|
320
|
+
choices = %w(A B C D E F G H)
|
321
|
+
prompt.input << "\r"
|
322
|
+
prompt.input.rewind
|
323
|
+
value = prompt.multi_select("What letter?") do |menu|
|
324
|
+
menu.per_page 3
|
325
|
+
menu.page_help '(Wiggle thy finger up or down to see more)'
|
326
|
+
menu.default 4
|
327
|
+
menu.choices choices
|
328
|
+
end
|
329
|
+
expect(value).to eq(['D'])
|
330
|
+
expect(prompt.output.string).to eq([
|
331
|
+
"\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
332
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
|
333
|
+
" #{symbols[:radio_off]} E\n",
|
334
|
+
" #{symbols[:radio_off]} F\n",
|
335
|
+
"\e[90m(Wiggle thy finger up or down to see more)\e[0m",
|
336
|
+
"\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
|
337
|
+
"What letter? \e[32mD\e[0m\n\e[?25h",
|
338
|
+
].join)
|
339
|
+
end
|
340
|
+
|
341
|
+
it "doesn't paginate short selections" do
|
342
|
+
prompt = TTY::TestPrompt.new
|
343
|
+
choices = %w(A B C D)
|
344
|
+
prompt.input << "\r"
|
345
|
+
prompt.input.rewind
|
346
|
+
value = prompt.multi_select("What letter?", choices, per_page: 4, default: 1)
|
347
|
+
expect(value).to eq(['A'])
|
348
|
+
|
349
|
+
expect(prompt.output.string).to eq([
|
350
|
+
"\e[?25lWhat letter? A \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
351
|
+
"#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m A\n",
|
352
|
+
" #{symbols[:radio_off]} B\n",
|
353
|
+
" #{symbols[:radio_off]} C\n",
|
354
|
+
" #{symbols[:radio_off]} D",
|
355
|
+
"\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
|
356
|
+
"What letter? \e[32mA\e[0m\n\e[?25h",
|
357
|
+
].join)
|
358
|
+
end
|
359
|
+
|
360
|
+
context "with :cycle" do
|
361
|
+
it "doesn't cycle by default" do
|
362
|
+
prompt = TTY::TestPrompt.new
|
363
|
+
choices = %w(A B C)
|
364
|
+
prompt.on(:keypress) { |e| prompt.trigger(:keydown) if e.value == "j" }
|
365
|
+
prompt.input << "j" << "j" << "j" << " " << "\r"
|
366
|
+
prompt.input.rewind
|
367
|
+
|
368
|
+
value = prompt.multi_select("What letter?", choices)
|
369
|
+
expect(value).to eq(["C"])
|
370
|
+
|
371
|
+
expect(prompt.output.string).to eq(
|
372
|
+
output_helper("What letter?", choices, "A", [], init: true,
|
373
|
+
hint: "Use arrow keys, press Space to select and Enter to finish") +
|
374
|
+
output_helper("What letter?", choices, "B", []) +
|
375
|
+
output_helper("What letter?", choices, "C", []) +
|
376
|
+
output_helper("What letter?", choices, "C", []) +
|
377
|
+
output_helper("What letter?", choices, "C", ["C"]) +
|
378
|
+
"What letter? \e[32mC\e[0m\n\e[?25h"
|
379
|
+
)
|
380
|
+
end
|
381
|
+
|
382
|
+
it "cycles when configured to do so" do
|
383
|
+
prompt = TTY::TestPrompt.new
|
384
|
+
choices = %w(A B C)
|
385
|
+
prompt.on(:keypress) { |e| prompt.trigger(:keydown) if e.value == "j" }
|
386
|
+
prompt.input << "j" << "j" << "j" << " " << "\r"
|
387
|
+
prompt.input.rewind
|
388
|
+
value = prompt.multi_select("What letter?", choices, cycle: true)
|
389
|
+
expect(value).to eq(["A"])
|
390
|
+
expect(prompt.output.string).to eq(
|
391
|
+
output_helper("What letter?", choices, "A", [], init: true,
|
392
|
+
hint: "Use arrow keys, press Space to select and Enter to finish") +
|
393
|
+
output_helper("What letter?", choices, "B", []) +
|
394
|
+
output_helper("What letter?", choices, "C", []) +
|
395
|
+
output_helper("What letter?", choices, "A", []) +
|
396
|
+
output_helper("What letter?", choices, "A", ["A"]) +
|
397
|
+
"What letter? \e[32mA\e[0m\n\e[?25h"
|
398
|
+
)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context "with filter" do
|
403
|
+
it "doesn't lose the selection when switching between filters" do
|
404
|
+
prompt = TTY::TestPrompt.new
|
405
|
+
prompt.on(:keypress) { |e| prompt.trigger(:keydelete) if e.value == "\r" }
|
406
|
+
prompt.input << " " # select `Tiny`
|
407
|
+
prompt.input << "a" << " " # match and select `Large`
|
408
|
+
prompt.input << "\u007F" # backspace (shows all)
|
409
|
+
prompt.input << "\r"
|
410
|
+
prompt.input.rewind
|
411
|
+
|
412
|
+
answer = prompt.multi_select("What size?", %w(Tiny Medium Large Huge), filter: true)
|
413
|
+
expect(answer).to eql(%w(Tiny Large))
|
414
|
+
|
415
|
+
expected_prompt_output =
|
416
|
+
output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(), init: true, hint: "Use arrow keys, press Space to select and Enter to finish, and letter keys to filter") +
|
417
|
+
output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(Tiny)) +
|
418
|
+
output_helper("What size?", %w(Large), "Large", %w(Tiny), hint: 'Filter: "a"') +
|
419
|
+
output_helper("What size?", %w(Large), "Large", %w(Tiny Large), hint: 'Filter: "a"') +
|
420
|
+
output_helper("What size?", %w(Tiny Medium Large Huge), "Tiny", %w(Tiny Large)) +
|
421
|
+
exit_message("What size?", %w(Tiny Large))
|
422
|
+
|
423
|
+
expect(prompt.output.string).to eql(expected_prompt_output)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
context "with :disabled" do
|
428
|
+
it "fails when active item is also disabled" do
|
429
|
+
prompt = TTY::TestPrompt.new
|
430
|
+
choices = [{name: 'vodka', disabled: true}, 'beer', 'wine', 'whisky', 'bourbon']
|
431
|
+
expect {
|
432
|
+
prompt.multi_select("Select drinks?", choices)
|
433
|
+
}.to raise_error(TTY::Prompt::ConfigurationError,
|
434
|
+
/active choice 'vodka' matches disabled item/)
|
435
|
+
end
|
436
|
+
|
437
|
+
it "omits disabled choice when nagivating menu" do
|
438
|
+
choices = [
|
439
|
+
{name: 'A'},
|
440
|
+
{name: 'B', disabled: '(out)'},
|
441
|
+
{name: 'C', disabled: '(out)'},
|
442
|
+
{name: 'D'},
|
443
|
+
{name: 'E'}
|
444
|
+
]
|
445
|
+
prompt = TTY::TestPrompt.new
|
446
|
+
prompt.on(:keypress) { |e| prompt.trigger(:keydown) if e.value == "j" }
|
447
|
+
prompt.input << "j" << " " << "j" << " " << "\r"
|
448
|
+
prompt.input.rewind
|
449
|
+
|
450
|
+
answer = prompt.multi_select("What letter?", choices)
|
451
|
+
expect(answer).to eq(%w[D E])
|
452
|
+
|
453
|
+
expected_output =
|
454
|
+
output_helper("What letter?", choices, "A", [], init: true, hint: "Use arrow keys, press Space to select and Enter to finish") +
|
455
|
+
output_helper("What letter?", choices, "D", []) +
|
456
|
+
output_helper("What letter?", choices, "D", %w[D]) +
|
457
|
+
output_helper("What letter?", choices, "E", %w[D]) +
|
458
|
+
output_helper("What letter?", choices, "E", %w[D E]) +
|
459
|
+
exit_message("What letter?", %w[D E])
|
460
|
+
|
461
|
+
expect(prompt.output.string).to eq(expected_output)
|
462
|
+
end
|
463
|
+
|
464
|
+
it "omits disabled choice when number key is pressed" do
|
465
|
+
choices = [
|
466
|
+
{name: 'vodka', value: 1},
|
467
|
+
{name: 'beer', value: 1, disabled: true},
|
468
|
+
{name: 'wine', value: 1},
|
469
|
+
{name: 'whisky', value: 1, disabled: true},
|
470
|
+
{name: 'bourbon', value: 1}
|
471
|
+
]
|
472
|
+
prompt = TTY::TestPrompt.new
|
473
|
+
prompt.input << "2" << " \r"
|
474
|
+
prompt.input.rewind
|
475
|
+
answer = prompt.multi_select("Select drinks?") do |menu|
|
476
|
+
menu.enum ')'
|
477
|
+
|
478
|
+
menu.choice :vodka, 1
|
479
|
+
menu.choice :beer, 2, disabled: true
|
480
|
+
menu.choice :wine, 3
|
481
|
+
menu.choice :whisky, 4, disabled: true
|
482
|
+
menu.choice :bourbon, 5
|
483
|
+
end
|
484
|
+
expect(answer).to eq([1])
|
485
|
+
|
486
|
+
expected_output =
|
487
|
+
output_helper("Select drinks?", choices, "vodka", [], init: true, enum: ') ', hint: "Use arrow or number (1-5) keys, press Space to select and Enter to finish") +
|
488
|
+
output_helper("Select drinks?", choices, "vodka", [], enum: ') ') +
|
489
|
+
output_helper("Select drinks?", choices, "vodka", %w[vodka], enum: ') ') +
|
490
|
+
exit_message("Select drinks?", %w[vodka])
|
491
|
+
|
492
|
+
expect(prompt.output.string).to eq(expected_output)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
end
|