tty-prompt 0.18.1 → 0.19.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/README.md +174 -63
  4. data/Rakefile +2 -2
  5. data/examples/ask_blank.rb +9 -0
  6. data/examples/enum_select_disabled.rb +1 -1
  7. data/examples/enum_select_paged.rb +1 -1
  8. data/examples/expand_auto.rb +29 -0
  9. data/examples/mask.rb +1 -1
  10. data/examples/multi_select.rb +1 -1
  11. data/examples/multi_select_disabled_paged.rb +22 -0
  12. data/examples/multi_select_paged.rb +1 -1
  13. data/examples/select_disabled_paged.rb +22 -0
  14. data/examples/select_paginated.rb +1 -1
  15. data/lib/tty/prompt.rb +46 -10
  16. data/lib/tty/prompt/{enum_paginator.rb → block_paginator.rb} +19 -18
  17. data/lib/tty/prompt/choice.rb +1 -3
  18. data/lib/tty/prompt/enum_list.rb +31 -9
  19. data/lib/tty/prompt/expander.rb +19 -1
  20. data/lib/tty/prompt/keypress.rb +30 -35
  21. data/lib/tty/prompt/list.rb +112 -40
  22. data/lib/tty/prompt/mask_question.rb +2 -3
  23. data/lib/tty/prompt/multi_list.rb +36 -12
  24. data/lib/tty/prompt/paginator.rb +37 -25
  25. data/lib/tty/prompt/question.rb +29 -5
  26. data/lib/tty/prompt/slider.rb +16 -8
  27. data/lib/tty/prompt/symbols.rb +30 -6
  28. data/lib/tty/prompt/timer.rb +75 -0
  29. data/lib/tty/prompt/version.rb +1 -1
  30. data/spec/spec_helper.rb +18 -2
  31. data/spec/unit/ask_spec.rb +45 -4
  32. data/spec/unit/{enum_paginator_spec.rb → block_paginator_spec.rb} +14 -5
  33. data/spec/unit/choice/from_spec.rb +16 -0
  34. data/spec/unit/enum_select_spec.rb +104 -32
  35. data/spec/unit/expand_spec.rb +104 -12
  36. data/spec/unit/keypress_spec.rb +2 -8
  37. data/spec/unit/mask_spec.rb +9 -1
  38. data/spec/unit/multi_select_spec.rb +348 -118
  39. data/spec/unit/paginator_spec.rb +29 -10
  40. data/spec/unit/select_spec.rb +390 -108
  41. data/spec/unit/slider_spec.rb +48 -6
  42. data/spec/unit/timer_spec.rb +29 -0
  43. data/tty-prompt.gemspec +4 -6
  44. metadata +17 -46
  45. data/lib/tty/prompt/timeout.rb +0 -78
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Prompt
5
- VERSION = '0.18.1'
5
+ VERSION = '0.19.0'
6
6
  end # Prompt
7
7
  end # TTY
@@ -4,10 +4,10 @@ if ENV['COVERAGE'] || ENV['TRAVIS']
4
4
  require 'simplecov'
5
5
  require 'coveralls'
6
6
 
7
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
8
8
  SimpleCov::Formatter::HTMLFormatter,
9
9
  Coveralls::SimpleCov::Formatter
10
- ]
10
+ ])
11
11
 
12
12
  SimpleCov.start do
13
13
  command_name 'spec'
@@ -17,7 +17,23 @@ end
17
17
 
18
18
  require 'tty-prompt'
19
19
 
20
+ class StringIO
21
+ def wait_readable(*)
22
+ true
23
+ end
24
+ end
25
+
26
+ module Helpers
27
+ def diff_output(actual_output, expected_output)
28
+ puts "ACTUAL: #{actual_output.inspect}"
29
+ puts "--------------------------------\n"
30
+ puts "EXPECT: #{expected_output.inspect}"
31
+ end
32
+ end
33
+
20
34
  RSpec.configure do |config|
35
+ config.include(Helpers)
36
+
21
37
  config.expect_with :rspec do |expectations|
22
38
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
39
  end
@@ -14,16 +14,57 @@ RSpec.describe TTY::Prompt, '#ask' do
14
14
  end
15
15
 
16
16
  it 'asks an empty question ' do
17
- prompt.ask('')
18
- expect(prompt.output.string).to eql('')
17
+ prompt = TTY::TestPrompt.new
18
+ prompt.input << "\r"
19
+ prompt.input.rewind
20
+
21
+ answer = prompt.ask
22
+ expect(answer).to eq(nil)
23
+
24
+ expect(prompt.output.string).to eql("\e[2K\e[1G\n\e[1A\e[2K\e[1G\n")
19
25
  end
20
26
 
21
- it 'asks an empty question and returns nil if EOF is sent to stdin' do
27
+ it "asks an empty question and returns nil if EOF is sent to stdin" do
28
+ prompt = TTY::TestPrompt.new
22
29
  prompt.input << nil
23
30
  prompt.input.rewind
31
+
24
32
  answer = prompt.ask('')
33
+
25
34
  expect(answer).to eql(nil)
26
- expect(prompt.output.string).to eq('')
35
+ expect(prompt.output.string).to eq("\e[1A\e[2K\e[1G\n")
36
+ end
37
+
38
+ it "asks an empty question with prepopulated value" do
39
+ prompt = TTY::TestPrompt.new
40
+ prompt.input << "\n"
41
+ prompt.input.rewind
42
+
43
+ answer = prompt.ask value: "yes"
44
+
45
+ expect(answer).to eq("yes")
46
+ expect(prompt.output.string).to eq([
47
+ "yes\e[2K\e[1G",
48
+ "yes\n\e[1A\e[2K\e[1G",
49
+ "\e[32myes\e[0m\n"
50
+ ].join)
51
+ end
52
+
53
+ it "asks question with prepopulated value" do
54
+ prompt = TTY::TestPrompt.new prefix: "> "
55
+ prompt.input << "\n"
56
+ prompt.input.rewind
57
+
58
+ answer = prompt.ask("Say?") do |q|
59
+ q.value "yes"
60
+ end
61
+
62
+ expect(answer).to eq("yes")
63
+ expect(prompt.output.string).to eq([
64
+ "> Say? yes\e[2K\e[1G",
65
+ "> Say? yes\n\e[1A\e[2K\e[1G",
66
+ "> Say? \e[32myes\e[0m\n"
67
+ ].join)
27
68
  end
28
69
 
29
70
  it "asks a question with a prefix [?]" do
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- RSpec.describe TTY::Prompt::EnumPaginator, '#paginate' do
3
+ RSpec.describe TTY::Prompt::BlockPaginator, '#paginate' do
4
4
  it "ignores per_page when equal items " do
5
5
  list = %w(a b c d)
6
6
  paginator = described_class.new({per_page: 4})
@@ -44,16 +44,25 @@ RSpec.describe TTY::Prompt::EnumPaginator, '#paginate' do
44
44
  expect(paginator.paginate(list, 8).to_a).to eq([['g',6]])
45
45
  end
46
46
 
47
- it "finds maximum index for current selection" do
47
+ it "finds both start and end index for current selection" do
48
48
  list = %w(a b c d e f g)
49
49
  paginator = described_class.new({per_page: 3, default: 0})
50
50
 
51
+ paginator.paginate(list, 3)
52
+ expect(paginator.start_index).to eq(0)
53
+ expect(paginator.end_index).to eq(2)
54
+
51
55
  paginator.paginate(list, 4)
52
- expect(paginator.max_index).to eq(5)
56
+ expect(paginator.start_index).to eq(3)
57
+ expect(paginator.end_index).to eq(5)
58
+
53
59
  paginator.paginate(list, 5)
54
- expect(paginator.max_index).to eq(5)
60
+ expect(paginator.start_index).to eq(3)
61
+ expect(paginator.end_index).to eq(5)
62
+
55
63
  paginator.paginate(list, 7)
56
- expect(paginator.max_index).to eq(8)
64
+ expect(paginator.start_index).to eq(6)
65
+ expect(paginator.end_index).to eq(6)
57
66
  end
58
67
 
59
68
  it "starts with default selection" do
@@ -93,4 +93,20 @@ RSpec.describe TTY::Prompt::Choice, '#from' do
93
93
  expect(choice.value).to eq(:none)
94
94
  expect(choice.disabled?).to eq(true)
95
95
  end
96
+
97
+ it "creates choice from an arbitrary object that responds to to_s call" do
98
+ stub_const("Size", Class.new do
99
+ def to_s
100
+ 'large'
101
+ end
102
+ end)
103
+ size = Size.new
104
+ expected_choice = described_class.new(size, size)
105
+ choice = described_class.from(size)
106
+
107
+ expect(choice).to eq(expected_choice)
108
+ expect(choice.name).to eq(size)
109
+ expect(choice.value).to eq(size)
110
+ expect(choice.disabled?).to eq(false)
111
+ end
96
112
  end
@@ -60,9 +60,10 @@ RSpec.describe TTY::Prompt do
60
60
  answer = prompt.enum_select("Select an editor?", choices)
61
61
  expect(answer).to eq('/bin/nano')
62
62
 
63
- expected_output =
64
- output_helper("Select an editor?", choices, "/bin/nano") +
63
+ expected_output = [
64
+ output_helper("Select an editor?", choices, "/bin/nano"),
65
65
  exit_message("Select an editor?", "/bin/nano")
66
+ ].join
66
67
 
67
68
  expect(prompt.output.string).to eq(expected_output)
68
69
  end
@@ -76,10 +77,11 @@ RSpec.describe TTY::Prompt do
76
77
  answer = prompt.enum_select("Select an editor?", choices, default: 2)
77
78
  expect(answer).to eq('/usr/bin/vim.tiny')
78
79
 
79
- expected_output =
80
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", default: 2) +
81
- output_helper("Select an editor?", choices, "/usr/bin/vim.tiny", default: 2, input: '3') +
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'),
82
83
  exit_message("Select an editor?", "/usr/bin/vim.tiny")
84
+ ].join
83
85
 
84
86
  expect(prompt.output.string).to eq(expected_output)
85
87
  end
@@ -99,10 +101,11 @@ RSpec.describe TTY::Prompt do
99
101
  end
100
102
  expect(answer).to eq('/bin/nano')
101
103
 
102
- expected_output =
103
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", default: 2, enum: '.') +
104
- output_helper("Select an editor?", choices, "/bin/nano", default: 2, enum: '.', input: 1) +
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),
105
107
  exit_message("Select an editor?", "/bin/nano")
108
+ ].join
106
109
 
107
110
  expect(prompt.output.string).to eq(expected_output)
108
111
  end
@@ -123,9 +126,10 @@ RSpec.describe TTY::Prompt do
123
126
 
124
127
  expect(answer).to eq('/usr/bin/vim')
125
128
 
126
- expected_output =
127
- output_helper("Select an editor?", choices, "vim", default: 2) +
129
+ expected_output = [
130
+ output_helper("Select an editor?", choices, "vim", default: 2),
128
131
  exit_message("Select an editor?", "vim")
132
+ ].join
129
133
 
130
134
  expect(prompt.output.string).to eq(expected_output)
131
135
  end
@@ -136,8 +140,12 @@ RSpec.describe TTY::Prompt do
136
140
  prompt.input << "\n"
137
141
  prompt.input.rewind
138
142
  options = {active_color: :red, help_color: :blue, error_color: :green}
139
- expect(prompt.enum_select("Select an editor?", choices, options)).to eq('/bin/nano')
140
- expect(prompt.output.string).to eq([
143
+
144
+ answer = prompt.enum_select("Select an editor?", choices, options)
145
+
146
+ expect(answer).to eq('/bin/nano')
147
+
148
+ expected_output = [
141
149
  "Select an editor? \n",
142
150
  " \e[31m1) /bin/nano\e[0m\n",
143
151
  " 2) /usr/bin/vim.basic\n",
@@ -146,7 +154,56 @@ RSpec.describe TTY::Prompt do
146
154
  "\e[2K\e[1G\e[1A" * 4,
147
155
  "\e[2K\e[1G\e[J",
148
156
  "Select an editor? \e[31m/bin/nano\e[0m\n"
149
- ].join)
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)
150
207
  end
151
208
 
152
209
  it "displays error with unrecognized input" do
@@ -158,13 +215,14 @@ RSpec.describe TTY::Prompt do
158
215
  answer = prompt.enum_select("Select an editor?", choices)
159
216
  expect(answer).to eq('/usr/bin/vim.basic')
160
217
 
161
- expected_output =
162
- output_helper("Select an editor?", choices, "/bin/nano") +
163
- output_helper("Select an editor?", choices, "/bin/nano", input: '1') +
164
- output_helper("Select an editor?", choices, "/bin/nano", input: '11') +
165
- output_helper("Select an editor?", choices, "/bin/nano", error: 'Please enter a valid number', input: '') +
166
- output_helper("Select an editor?", choices, "/usr/bin/vim.basic", error: 'Please enter a valid number', input: '2') +
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'),
167
224
  exit_message("Select an editor?", "/usr/bin/vim.basic")
225
+ ].join
168
226
 
169
227
  expect(prompt.output.string).to eq(expected_output)
170
228
  end
@@ -354,6 +412,7 @@ RSpec.describe TTY::Prompt do
354
412
  menu.choices choices
355
413
  end
356
414
  expect(value).to eq("A")
415
+
357
416
  expect(prompt.output.string).to eq([
358
417
  "What letter? \n",
359
418
  " \e[32m1) A\e[0m\n",
@@ -391,11 +450,22 @@ RSpec.describe TTY::Prompt do
391
450
  prompt = TTY::TestPrompt.new
392
451
  choices = [{name: 'A', disabled: true}, 'B', 'C', 'D', 'E']
393
452
  expect {
394
- prompt.enum_select("What letter?", choices)
453
+ prompt.enum_select("What letter?", choices, default: 1)
395
454
  }.to raise_error(TTY::Prompt::ConfigurationError,
396
455
  /default index 1 matches disabled choice item/)
397
456
  end
398
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
+
399
469
  it "doesn't allow to choose disabled choice and defaults" do
400
470
  choices = ['A', {name: 'B', disabled: '(out)'}, 'C', 'D', 'E', 'F']
401
471
  prompt = TTY::TestPrompt.new
@@ -405,12 +475,13 @@ RSpec.describe TTY::Prompt do
405
475
  answer = prompt.enum_select("What letter?", choices)
406
476
  expect(answer).to eq("C")
407
477
 
408
- expected_output =
409
- output_helper("What letter?", choices, 'A') +
410
- output_helper("What letter?", choices, 'A', input: '2') +
411
- output_helper("What letter?", choices, 'A', input: '', error: 'Please enter a valid number') +
412
- output_helper("What letter?", choices, 'C', input: '3', error: 'Please enter a valid number') +
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'),
413
483
  exit_message("What letter?", "C")
484
+ ].join
414
485
 
415
486
  expect(prompt.output.string).to eq(expected_output)
416
487
  end
@@ -431,14 +502,15 @@ RSpec.describe TTY::Prompt do
431
502
  answer = prompt.enum_select("What letter?", choices)
432
503
  expect(answer).to eq("D")
433
504
 
434
- expected_output =
435
- output_helper("What letter?", choices, 'A') +
436
- output_helper("What letter?", choices, 'A', input: '2') +
437
- output_helper("What letter?", choices, 'A', input: '') +
438
- output_helper("What letter?", choices, 'A', input: '3') +
439
- output_helper("What letter?", choices, 'A', input: '') +
440
- output_helper("What letter?", choices, 'D', input: '4') +
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'),
441
512
  exit_message("What letter?", "D")
513
+ ].join
442
514
 
443
515
  expect(prompt.output.string).to eq(expected_output)
444
516
  end
@@ -35,11 +35,13 @@ RSpec.describe TTY::Prompt, '#expand' do
35
35
  result = prompt.expand('Overwrite Gemfile?', choices)
36
36
  expect(result).to eq(:yes)
37
37
 
38
- expect(prompt.output.string).to eq([
38
+ expected_output = [
39
39
  "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
40
40
  "\e[2K\e[1G",
41
41
  "Overwrite Gemfile? \e[32mOverwrite\e[0m\n"
42
- ].join)
42
+ ].join
43
+
44
+ expect(prompt.output.string).to eq(expected_output)
43
45
  end
44
46
 
45
47
  it "changes default option" do
@@ -49,11 +51,13 @@ RSpec.describe TTY::Prompt, '#expand' do
49
51
  result = prompt.expand('Overwrite Gemfile?', choices, default: 3)
50
52
  expect(result).to eq(:all)
51
53
 
52
- expect(prompt.output.string).to eq([
54
+ expected_output = [
53
55
  "Overwrite Gemfile? (enter \"h\" for help) [y,n,\e[32ma\e[0m,d,q,h] ",
54
56
  "\e[2K\e[1G",
55
57
  "Overwrite Gemfile? \e[32mOverwrite all\e[0m\n"
56
- ].join)
58
+ ].join
59
+
60
+ expect(prompt.output.string).to eq(expected_output)
57
61
  end
58
62
 
59
63
  it "expands chosen option with extra information" do
@@ -63,7 +67,7 @@ RSpec.describe TTY::Prompt, '#expand' do
63
67
  result = prompt.expand('Overwrite Gemfile?', choices)
64
68
  expect(result).to eq(:all)
65
69
 
66
- expect(prompt.output.string).to eq([
70
+ expected_output = [
67
71
  "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
68
72
  "\e[2K\e[1G",
69
73
  "Overwrite Gemfile? (enter \"h\" for help) [y,n,\e[32ma\e[0m,d,q,h] ",
@@ -75,7 +79,9 @@ RSpec.describe TTY::Prompt, '#expand' do
75
79
  "\e[2K\e[1G",
76
80
  "\e[A\e[1G",
77
81
  "Overwrite Gemfile? \e[32mOverwrite all\e[0m\n"
78
- ].join)
82
+ ].join
83
+
84
+ expect(prompt.output.string).to eq(expected_output)
79
85
  end
80
86
 
81
87
  it "expands help option and then defaults" do
@@ -85,7 +91,7 @@ RSpec.describe TTY::Prompt, '#expand' do
85
91
  result = prompt.expand('Overwrite Gemfile?', choices)
86
92
  expect(result).to eq(:diff)
87
93
 
88
- expect(prompt.output.string).to eq([
94
+ expected_output = [
89
95
  "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
90
96
  "\e[2K\e[1G",
91
97
  "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,d,q,\e[32mh\e[0m] h\n",
@@ -116,7 +122,89 @@ RSpec.describe TTY::Prompt, '#expand' do
116
122
  "\e[2K\e[1G\e[1A" * 7,
117
123
  "\e[2K\e[1G",
118
124
  "Overwrite Gemfile? \e[32mShow diff\e[0m\n",
119
- ].join)
125
+ ].join
126
+
127
+ expect(prompt.output.string).to eq(expected_output)
128
+ end
129
+
130
+ it "automatically expands hint" do
131
+ prompt.input << "d\n"
132
+ prompt.input.rewind
133
+
134
+ result = prompt.expand('Overwrite Gemfile?', choices, auto_hint: true)
135
+ expect(result).to eq(:diff)
136
+
137
+ expected_output = [
138
+ "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
139
+ "\n\e[32m>> \e[0mOverwrite",
140
+ "\e[A\e[1G\e[54C",
141
+ "\e[2K\e[1G",
142
+ "\e[1B",
143
+ "\e[2K\e[1G",
144
+ "\e[A\e[1G",
145
+ "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,\e[32md\e[0m,q,h] ",
146
+ "d\n",
147
+ "\e[32m>> \e[0mShow diff",
148
+ "\e[A\e[1G\e[55C",
149
+ "\e[2K\e[1G",
150
+ "\e[1B",
151
+ "\e[2K\e[1G",
152
+ "\e[A\e[1G",
153
+ "Overwrite Gemfile? \e[32mShow diff\e[0m\n",
154
+ "\e[32m>> \e[0mShow diff",
155
+ "\e[A\e[1G\e[28C\n"
156
+ ].join
157
+
158
+ expect(prompt.output.string).to eq(expected_output)
159
+ end
160
+
161
+ it "informs about invalid input when automatically expanding hint" do
162
+ prompt = TTY::TestPrompt.new
163
+ prompt.on(:keypress) { |e| prompt.trigger(:keybackspace) if e.value == "w" }
164
+ prompt.input << "y" << "y" << "\u007F" << "\r"
165
+ prompt.input.rewind
166
+
167
+ result = prompt.expand('Overwrite Gemfile?', choices, defualt: 1, auto_hint: true)
168
+ expect(result).to eq(:yes)
169
+
170
+ expected_output = [
171
+ "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
172
+ "\n\e[32m>> \e[0mOverwrite",
173
+ "\e[A\e[1G\e[54C",
174
+ "\e[2K\e[1G",
175
+ "\e[1B",
176
+ "\e[2K\e[1G",
177
+ "\e[A\e[1G",
178
+ "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
179
+ "y\n",
180
+ "\e[32m>> \e[0mOverwrite",
181
+ "\e[A\e[1G\e[55C",
182
+ "\e[2K\e[1G",
183
+ "\e[1B",
184
+ "\e[2K\e[1G",
185
+ "\e[A\e[1G",
186
+ "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,d,q,h] ",
187
+ "yy\n",
188
+ "\e[32m>> \e[0minvalid option",
189
+ "\e[A\e[1G\e[56C",
190
+ "\e[2K\e[1G",
191
+ "\e[1B",
192
+ "\e[2K\e[1G",
193
+ "\e[A\e[1G",
194
+ "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
195
+ "y\n",
196
+ "\e[32m>> \e[0mOverwrite",
197
+ "\e[A\e[1G\e[55C",
198
+ "\e[2K\e[1G",
199
+ "\e[1B",
200
+ "\e[2K\e[1G",
201
+ "\e[A\e[1G",
202
+ "Overwrite Gemfile? \e[32mOverwrite\e[0m\n",
203
+ "\e[32m>> \e[0mOverwrite",
204
+ "\e[A\e[1G\e[28C\n"
205
+ ].join
206
+
207
+ expect(prompt.output.string).to eq(expected_output)
120
208
  end
121
209
 
122
210
  it "specifies options through DSL" do
@@ -135,11 +223,13 @@ RSpec.describe TTY::Prompt, '#expand' do
135
223
 
136
224
  expect(result).to eq(:diff)
137
225
 
138
- expect(prompt.output.string).to eq([
226
+ expected_output = [
139
227
  "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,\e[32md\e[0m,q,h] ",
140
228
  "\e[2K\e[1G",
141
229
  "Overwrite Gemfile? \e[32mShow diff\e[0m\n"
142
- ].join)
230
+ ].join
231
+
232
+ expect(prompt.output.string).to eq(expected_output)
143
233
  end
144
234
 
145
235
  it "specifies options through DSL and executes value" do
@@ -156,11 +246,13 @@ RSpec.describe TTY::Prompt, '#expand' do
156
246
 
157
247
  expect(result).to eq(:ok)
158
248
 
159
- expect(prompt.output.string).to eq([
249
+ expected_output = [
160
250
  "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
161
251
  "\e[2K\e[1G",
162
252
  "Overwrite Gemfile? \e[32mOverwrite\e[0m\n"
163
- ].join)
253
+ ].join
254
+
255
+ expect(prompt.output.string).to eq(expected_output)
164
256
  end
165
257
 
166
258
  it "fails to expand due to lack of key attribute" do