tty-prompt 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.md +30 -0
  4. data/README.md +39 -9
  5. data/examples/echo.rb +5 -1
  6. data/examples/inputs.rb +10 -0
  7. data/examples/mask.rb +6 -2
  8. data/examples/multi_select.rb +1 -1
  9. data/examples/multi_select_paged.rb +9 -0
  10. data/examples/select.rb +5 -5
  11. data/examples/slider.rb +1 -1
  12. data/lib/tty-prompt.rb +2 -36
  13. data/lib/tty/prompt.rb +49 -8
  14. data/lib/tty/prompt/choices.rb +2 -0
  15. data/lib/tty/prompt/confirm_question.rb +6 -1
  16. data/lib/tty/prompt/converter_dsl.rb +9 -6
  17. data/lib/tty/prompt/converter_registry.rb +27 -19
  18. data/lib/tty/prompt/converters.rb +16 -22
  19. data/lib/tty/prompt/enum_list.rb +8 -4
  20. data/lib/tty/prompt/enum_paginator.rb +2 -0
  21. data/lib/tty/prompt/evaluator.rb +1 -1
  22. data/lib/tty/prompt/expander.rb +1 -1
  23. data/lib/tty/prompt/list.rb +21 -11
  24. data/lib/tty/prompt/mask_question.rb +15 -6
  25. data/lib/tty/prompt/multi_list.rb +12 -10
  26. data/lib/tty/prompt/question.rb +38 -36
  27. data/lib/tty/prompt/question/modifier.rb +2 -0
  28. data/lib/tty/prompt/question/validation.rb +5 -4
  29. data/lib/tty/prompt/reader.rb +104 -58
  30. data/lib/tty/prompt/reader/codes.rb +103 -63
  31. data/lib/tty/prompt/reader/console.rb +57 -0
  32. data/lib/tty/prompt/reader/key_event.rb +51 -88
  33. data/lib/tty/prompt/reader/mode.rb +5 -5
  34. data/lib/tty/prompt/reader/win_api.rb +29 -0
  35. data/lib/tty/prompt/reader/win_console.rb +49 -0
  36. data/lib/tty/prompt/slider.rb +10 -6
  37. data/lib/tty/prompt/suggestion.rb +1 -1
  38. data/lib/tty/prompt/symbols.rb +52 -10
  39. data/lib/tty/prompt/version.rb +1 -1
  40. data/lib/tty/{prompt/test.rb → test_prompt.rb} +2 -1
  41. data/spec/unit/ask_spec.rb +8 -16
  42. data/spec/unit/converters/convert_bool_spec.rb +1 -2
  43. data/spec/unit/converters/on_error_spec.rb +9 -0
  44. data/spec/unit/enum_paginator_spec.rb +16 -0
  45. data/spec/unit/enum_select_spec.rb +69 -25
  46. data/spec/unit/expand_spec.rb +14 -14
  47. data/spec/unit/mask_spec.rb +66 -29
  48. data/spec/unit/multi_select_spec.rb +120 -74
  49. data/spec/unit/new_spec.rb +5 -3
  50. data/spec/unit/paginator_spec.rb +16 -0
  51. data/spec/unit/question/default_spec.rb +2 -4
  52. data/spec/unit/question/echo_spec.rb +2 -3
  53. data/spec/unit/question/in_spec.rb +9 -14
  54. data/spec/unit/question/modifier/letter_case_spec.rb +32 -11
  55. data/spec/unit/question/modifier/whitespace_spec.rb +41 -15
  56. data/spec/unit/question/required_spec.rb +9 -13
  57. data/spec/unit/question/validate_spec.rb +7 -10
  58. data/spec/unit/reader/key_event_spec.rb +36 -50
  59. data/spec/unit/reader/publish_keypress_event_spec.rb +5 -3
  60. data/spec/unit/reader/read_keypress_spec.rb +8 -7
  61. data/spec/unit/reader/read_line_spec.rb +9 -9
  62. data/spec/unit/reader/read_multiline_spec.rb +8 -7
  63. data/spec/unit/select_spec.rb +85 -25
  64. data/spec/unit/slider_spec.rb +43 -16
  65. data/spec/unit/yes_no_spec.rb +14 -28
  66. data/tasks/console.rake +1 -0
  67. data/tty-prompt.gemspec +2 -2
  68. metadata +14 -7
@@ -4,6 +4,8 @@ RSpec.describe TTY::Prompt, '#mask' do
4
4
 
5
5
  subject(:prompt) { TTY::TestPrompt.new }
6
6
 
7
+ let(:symbols) { TTY::Prompt::Symbols.symbols }
8
+
7
9
  it "masks output by default" do
8
10
  prompt.input << "pass\r"
9
11
  prompt.input.rewind
@@ -11,18 +13,18 @@ RSpec.describe TTY::Prompt, '#mask' do
11
13
  expect(answer).to eql("pass")
12
14
  expect(prompt.output.string).to eq([
13
15
  "What is your password? ",
14
- "\e[1000D\e[K",
15
- "What is your password? ",
16
- "\e[1000D\e[K",
17
- "What is your password? ••",
18
- "\e[1000D\e[K",
19
- "What is your password? •••",
20
- "\e[1000D\e[K",
21
- "What is your password? ••••",
22
- "\e[1000D\e[K",
23
- "What is your password? \e[32m••••\e[0m\n",
24
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
25
- "What is your password? \e[32m••••\e[0m\n"
16
+ "\e[2K\e[1G",
17
+ "What is your password? #{symbols[:dot]}",
18
+ "\e[2K\e[1G",
19
+ "What is your password? #{symbols[:dot] * 2}",
20
+ "\e[2K\e[1G",
21
+ "What is your password? #{symbols[:dot] * 3}",
22
+ "\e[2K\e[1G",
23
+ "What is your password? #{symbols[:dot] * 4}",
24
+ "\e[2K\e[1G",
25
+ "What is your password? \e[32m#{symbols[:dot] * 4}\e[0m\n",
26
+ "\e[1A\e[2K\e[1G",
27
+ "What is your password? \e[32m#{symbols[:dot] * 4}\e[0m\n"
26
28
  ].join)
27
29
  end
28
30
 
@@ -33,17 +35,17 @@ RSpec.describe TTY::Prompt, '#mask' do
33
35
  expect(answer).to eql("pass")
34
36
  expect(prompt.output.string).to eq([
35
37
  "What is your password? ",
36
- "\e[1000D\e[K",
38
+ "\e[2K\e[1G",
37
39
  "What is your password? *",
38
- "\e[1000D\e[K",
40
+ "\e[2K\e[1G",
39
41
  "What is your password? **",
40
- "\e[1000D\e[K",
42
+ "\e[2K\e[1G",
41
43
  "What is your password? ***",
42
- "\e[1000D\e[K",
44
+ "\e[2K\e[1G",
43
45
  "What is your password? ****",
44
- "\e[1000D\e[K",
46
+ "\e[2K\e[1G",
45
47
  "What is your password? \e[32m****\e[0m\n",
46
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
48
+ "\e[1A\e[2K\e[1G",
47
49
  "What is your password? \e[32m****\e[0m\n",
48
50
  ].join)
49
51
  end
@@ -55,15 +57,15 @@ RSpec.describe TTY::Prompt, '#mask' do
55
57
  expect(answer).to eql("lov")
56
58
  expect(prompt.output.string).to eq([
57
59
  "What is your password? ",
58
- "\e[1000D\e[K",
60
+ "\e[2K\e[1G",
59
61
  "What is your password? ♥",
60
- "\e[1000D\e[K",
62
+ "\e[2K\e[1G",
61
63
  "What is your password? ♥♥",
62
- "\e[1000D\e[K",
64
+ "\e[2K\e[1G",
63
65
  "What is your password? ♥♥♥",
64
- "\e[1000D\e[K",
66
+ "\e[2K\e[1G",
65
67
  "What is your password? \e[32m♥♥♥\e[0m\n",
66
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
68
+ "\e[1A\e[2K\e[1G",
67
69
  "What is your password? \e[32m♥♥♥\e[0m\n",
68
70
  ].join)
69
71
  end
@@ -78,18 +80,53 @@ RSpec.describe TTY::Prompt, '#mask' do
78
80
  expect(answer).to eql("pass")
79
81
  expect(prompt.output.string).to eq([
80
82
  "What is your password? ",
81
- "\e[1000D\e[K",
83
+ "\e[2K\e[1G",
82
84
  "What is your password? ",
83
- "\e[1000D\e[K",
85
+ "\e[2K\e[1G",
84
86
  "What is your password? ",
85
- "\e[1000D\e[K",
87
+ "\e[2K\e[1G",
86
88
  "What is your password? ",
87
- "\e[1000D\e[K",
89
+ "\e[2K\e[1G",
88
90
  "What is your password? ",
89
- "\e[1000D\e[K",
91
+ "\e[2K\e[1G",
90
92
  "What is your password? \n",
91
- "\e[1000D\e[K",
93
+ "\e[2K\e[1G",
92
94
  "What is your password? \n",
93
95
  ].join)
94
96
  end
97
+
98
+ it "validates input" do
99
+ prompt.input << "no\nyes\n"
100
+ prompt.input.rewind
101
+ answer = prompt.mask('What is your password?') do |q|
102
+ q.echo true
103
+ q.mask '*'
104
+ q.validate(/[a-z]{3,4}/)
105
+ q.messages[:valid?] = 'Not valid'
106
+ end
107
+ expect(answer).to eq('yes')
108
+ expect(prompt.output.string).to eq([
109
+ "What is your password? ",
110
+ "\e[2K\e[1G",
111
+ "What is your password? *",
112
+ "\e[2K\e[1G",
113
+ "What is your password? **",
114
+ "\e[2K\e[1G",
115
+ "What is your password? \e[32m**\e[0m\n",
116
+ "\e[31m>>\e[0m Not valid",
117
+ "\e[1A\e[2K\e[1G",
118
+ "What is your password? \e[31m**\e[0m",
119
+ "\e[2K\e[1G",
120
+ "What is your password? *",
121
+ "\e[2K\e[1G",
122
+ "What is your password? **",
123
+ "\e[2K\e[1G",
124
+ "What is your password? ***",
125
+ "\e[2K\e[1G",
126
+ "What is your password? \e[32m***\e[0m\n",
127
+ "\e[2K\e[1G",
128
+ "\e[1A\e[2K\e[1G",
129
+ "What is your password? \e[32m***\e[0m\n"
130
+ ].join)
131
+ end
95
132
  end
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  RSpec.describe TTY::Prompt do
4
+ let(:symbols) { TTY::Prompt::Symbols.symbols }
5
+
4
6
  it "selects nothing when return pressed immediately" do
5
7
  prompt = TTY::TestPrompt.new
6
8
  choices = %w(vodka beer wine whisky bourbon)
@@ -9,12 +11,12 @@ RSpec.describe TTY::Prompt do
9
11
  expect(prompt.multi_select("Select drinks?", choices)). to eq([])
10
12
  expect(prompt.output.string).to eq([
11
13
  "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
12
- " vodka\n",
13
- " beer\n",
14
- " wine\n",
15
- " whisky\n",
16
- " bourbon",
17
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
14
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
15
+ " #{symbols[:radio_off]} beer\n",
16
+ " #{symbols[:radio_off]} wine\n",
17
+ " #{symbols[:radio_off]} whisky\n",
18
+ " #{symbols[:radio_off]} bourbon",
19
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
18
20
  "Select drinks? \n\e[?25h"
19
21
  ].join)
20
22
  end
@@ -27,23 +29,48 @@ RSpec.describe TTY::Prompt do
27
29
  expect(prompt.multi_select("Select drinks?", choices)). to eq(['vodka'])
28
30
  expect(prompt.output.string).to eq([
29
31
  "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
30
- " vodka\n",
31
- " beer\n",
32
- " wine\n",
33
- " whisky\n",
34
- " bourbon",
35
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
32
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
33
+ " #{symbols[:radio_off]} beer\n",
34
+ " #{symbols[:radio_off]} wine\n",
35
+ " #{symbols[:radio_off]} whisky\n",
36
+ " #{symbols[:radio_off]} bourbon",
37
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
36
38
  "Select drinks? vodka\n",
37
- " \e[32m⬢\e[0m vodka\n",
38
- " beer\n",
39
- " wine\n",
40
- " whisky\n",
41
- " bourbon",
42
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
39
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
40
+ " #{symbols[:radio_off]} beer\n",
41
+ " #{symbols[:radio_off]} wine\n",
42
+ " #{symbols[:radio_off]} whisky\n",
43
+ " #{symbols[:radio_off]} bourbon",
44
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
43
45
  "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
44
46
  ].join)
45
47
  end
46
48
 
49
+ it "selects item when space pressed but doesn't echo item if echo: false" do
50
+ prompt = TTY::TestPrompt.new
51
+ choices = %w(vodka beer wine whisky bourbon)
52
+ prompt.input << " \r"
53
+ prompt.input.rewind
54
+ expect(prompt.multi_select("Select drinks?", choices, echo: false)). to eq(['vodka'])
55
+ expect(prompt.output.string).to eq([
56
+ "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
57
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
58
+ " #{symbols[:radio_off]} beer\n",
59
+ " #{symbols[:radio_off]} wine\n",
60
+ " #{symbols[:radio_off]} whisky\n",
61
+ " #{symbols[:radio_off]} bourbon",
62
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
63
+ "Select drinks? \n",
64
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
65
+ " #{symbols[:radio_off]} beer\n",
66
+ " #{symbols[:radio_off]} wine\n",
67
+ " #{symbols[:radio_off]} whisky\n",
68
+ " #{symbols[:radio_off]} bourbon",
69
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
70
+ "Select drinks? \n\e[?25h"
71
+ ].join)
72
+ end
73
+
47
74
  it "sets choice custom values" do
48
75
  prompt = TTY::TestPrompt.new
49
76
  choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
@@ -52,19 +79,19 @@ RSpec.describe TTY::Prompt do
52
79
  expect(prompt.multi_select("Select drinks?", choices)).to eq([1])
53
80
  expect(prompt.output.string).to eq([
54
81
  "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
55
- " vodka\n",
56
- " beer\n",
57
- " wine\n",
58
- " whisky\n",
59
- " bourbon",
60
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
82
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
83
+ " #{symbols[:radio_off]} beer\n",
84
+ " #{symbols[:radio_off]} wine\n",
85
+ " #{symbols[:radio_off]} whisky\n",
86
+ " #{symbols[:radio_off]} bourbon",
87
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
61
88
  "Select drinks? vodka\n",
62
- " \e[32m⬢\e[0m vodka\n",
63
- " beer\n",
64
- " wine\n",
65
- " whisky\n",
66
- " bourbon",
67
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
89
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m vodka\n",
90
+ " #{symbols[:radio_off]} beer\n",
91
+ " #{symbols[:radio_off]} wine\n",
92
+ " #{symbols[:radio_off]} whisky\n",
93
+ " #{symbols[:radio_off]} bourbon",
94
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
68
95
  "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
69
96
  ].join)
70
97
  end
@@ -84,19 +111,19 @@ RSpec.describe TTY::Prompt do
84
111
  expect(value).to eq([{score: 1}])
85
112
  expect(prompt.output.string).to eq([
86
113
  "\e[?25lSelect drinks? \e[90m(Use arrow or number (1-5) keys, press Space to select and Enter to finish)\e[0m\n",
87
- " 1) vodka\n",
88
- " 2) beer\n",
89
- " 3) wine\n",
90
- " 4) whisky\n",
91
- " 5) bourbon",
92
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
114
+ "#{symbols[:pointer]} #{symbols[:radio_off]} 1) vodka\n",
115
+ " #{symbols[:radio_off]} 2) beer\n",
116
+ " #{symbols[:radio_off]} 3) wine\n",
117
+ " #{symbols[:radio_off]} 4) whisky\n",
118
+ " #{symbols[:radio_off]} 5) bourbon",
119
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
93
120
  "Select drinks? vodka\n",
94
- " \e[32m⬢\e[0m 1) vodka\n",
95
- " 2) beer\n",
96
- " 3) wine\n",
97
- " 4) whisky\n",
98
- " 5) bourbon",
99
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
121
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m 1) vodka\n",
122
+ " #{symbols[:radio_off]} 2) beer\n",
123
+ " #{symbols[:radio_off]} 3) wine\n",
124
+ " #{symbols[:radio_off]} 4) whisky\n",
125
+ " #{symbols[:radio_off]} 5) bourbon",
126
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
100
127
  "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
101
128
  ].join)
102
129
  end
@@ -117,12 +144,12 @@ RSpec.describe TTY::Prompt do
117
144
  expect(value).to match_array([{score: 20}, {score: 50}])
118
145
  expect(prompt.output.string).to eq([
119
146
  "\e[?25lSelect drinks? beer, bourbon \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
120
- " vodka\n",
121
- " \e[32m⬢\e[0m beer\n",
122
- " wine\n",
123
- " whisky\n",
124
- " \e[32m⬢\e[0m bourbon",
125
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
147
+ " #{symbols[:radio_off]} vodka\n",
148
+ " \e[32m#{symbols[:radio_on]}\e[0m beer\n",
149
+ " #{symbols[:radio_off]} wine\n",
150
+ " #{symbols[:radio_off]} whisky\n",
151
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m bourbon",
152
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
126
153
  "Select drinks? \e[32mbeer, bourbon\e[0m\n\e[?25h",
127
154
  ].join)
128
155
  end
@@ -165,12 +192,12 @@ RSpec.describe TTY::Prompt do
165
192
  expect(prompt.multi_select("Select drinks?", choices)). to eq([])
166
193
  expect(prompt.output.string).to eq([
167
194
  "\e[?25l[?] Select drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
168
- " vodka\n",
169
- " beer\n",
170
- " wine\n",
171
- " whisky\n",
172
- " bourbon",
173
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
195
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
196
+ " #{symbols[:radio_off]} beer\n",
197
+ " #{symbols[:radio_off]} wine\n",
198
+ " #{symbols[:radio_off]} whisky\n",
199
+ " #{symbols[:radio_off]} bourbon",
200
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
174
201
  "[?] Select drinks? \n\e[?25h"
175
202
  ].join)
176
203
  end
@@ -184,12 +211,12 @@ RSpec.describe TTY::Prompt do
184
211
  expect(prompt.multi_select("Select drinks?", choices, options)). to eq(['vodka'])
185
212
  expect(prompt.output.string).to eq([
186
213
  "\e[?25lSelect drinks? vodka \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
187
- "> \e[34m⬢\e[0m vodka\n",
188
- " beer\n",
189
- " wine\n",
190
- " whisky\n",
191
- " bourbon",
192
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
214
+ "> \e[34m#{symbols[:radio_on]}\e[0m vodka\n",
215
+ " #{symbols[:radio_off]} beer\n",
216
+ " #{symbols[:radio_off]} wine\n",
217
+ " #{symbols[:radio_off]} whisky\n",
218
+ " #{symbols[:radio_off]} bourbon",
219
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
193
220
  "Select drinks? \e[34mvodka\e[0m\n\e[?25h"
194
221
  ].join)
195
222
  end
@@ -202,12 +229,12 @@ RSpec.describe TTY::Prompt do
202
229
  expect(prompt.multi_select("Select drinks?", choices, help: '(Bash keyboard)')). to eq([])
203
230
  expect(prompt.output.string).to eq([
204
231
  "\e[?25lSelect drinks? \e[90m(Bash keyboard)\e[0m\n",
205
- " vodka\n",
206
- " beer\n",
207
- " wine\n",
208
- " whisky\n",
209
- " bourbon",
210
- "\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
232
+ "#{symbols[:pointer]} #{symbols[:radio_off]} vodka\n",
233
+ " #{symbols[:radio_off]} beer\n",
234
+ " #{symbols[:radio_off]} wine\n",
235
+ " #{symbols[:radio_off]} whisky\n",
236
+ " #{symbols[:radio_off]} bourbon",
237
+ "\e[2K\e[1G\e[1A" * 5, "\e[2K\e[1G",
211
238
  "Select drinks? \n\e[?25h"
212
239
  ].join)
213
240
  end
@@ -221,11 +248,11 @@ RSpec.describe TTY::Prompt do
221
248
  expect(value).to eq(['D'])
222
249
  expect(prompt.output.string).to eq([
223
250
  "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
224
- " \e[32m⬢\e[0m D\n",
225
- " E\n",
226
- " F\n",
251
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
252
+ " #{symbols[:radio_off]} E\n",
253
+ " #{symbols[:radio_off]} F\n",
227
254
  "\e[90m(Move up or down to reveal more choices)\e[0m",
228
- "\e[1000D\e[K\e[1A" * 4 + "\e[1000D\e[K",
255
+ "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
229
256
  "What letter? \e[32mD\e[0m\n\e[?25h",
230
257
  ].join)
231
258
  end
@@ -244,12 +271,31 @@ RSpec.describe TTY::Prompt do
244
271
  expect(value).to eq(['D'])
245
272
  expect(prompt.output.string).to eq([
246
273
  "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
247
- " \e[32m⬢\e[0m D\n",
248
- " E\n",
249
- " F\n",
274
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
275
+ " #{symbols[:radio_off]} E\n",
276
+ " #{symbols[:radio_off]} F\n",
250
277
  "\e[90m(Wiggle thy finger up or down to see more)\e[0m",
251
- "\e[1000D\e[K\e[1A" * 4 + "\e[1000D\e[K",
278
+ "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
252
279
  "What letter? \e[32mD\e[0m\n\e[?25h",
253
280
  ].join)
254
281
  end
282
+
283
+ it "doesn't paginate short selections" do
284
+ prompt = TTY::TestPrompt.new
285
+ choices = %w(A B C D)
286
+ prompt.input << "\r"
287
+ prompt.input.rewind
288
+ value = prompt.multi_select("What letter?", choices, per_page: 4, default: 1)
289
+ expect(value).to eq(['A'])
290
+
291
+ expect(prompt.output.string).to eq([
292
+ "\e[?25lWhat letter? A \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
293
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m A\n",
294
+ " #{symbols[:radio_off]} B\n",
295
+ " #{symbols[:radio_off]} C\n",
296
+ " #{symbols[:radio_off]} D",
297
+ "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
298
+ "What letter? \e[32mA\e[0m\n\e[?25h",
299
+ ].join)
300
+ end
255
301
  end
@@ -1,18 +1,20 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  RSpec.describe TTY::Prompt, '#new' do
4
+ let(:env) { { "TTY_TEST" => true } }
5
+
4
6
  it "sets prefix" do
5
- prompt = described_class.new(prefix: "[?]")
7
+ prompt = described_class.new(prefix: "[?]", env: env)
6
8
  expect(prompt.prefix).to eq("[?]")
7
9
  end
8
10
 
9
11
  it "sets input stream" do
10
- prompt = described_class.new(input: :stream1)
12
+ prompt = described_class.new(input: :stream1, env: env)
11
13
  expect(prompt.input).to eq(:stream1)
12
14
  end
13
15
 
14
16
  it "sets output stream" do
15
- prompt = described_class.new(output: :stream2)
17
+ prompt = described_class.new(output: :stream2, env: env)
16
18
  expect(prompt.output).to eq(:stream2)
17
19
  end
18
20
  end
@@ -1,6 +1,22 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  RSpec.describe TTY::Prompt::Paginator, '#paginate' do
4
+ it "ignores per_page when equal items " do
5
+ list = %w(a b c d)
6
+ paginator = described_class.new({per_page: 4})
7
+
8
+ expect(paginator.paginate(list, 1).to_a).to eq([
9
+ ['a',0],['b',1],['c',2],['d',3]])
10
+ end
11
+
12
+ it "ignores per_page when less items " do
13
+ list = %w(a b c d)
14
+ paginator = described_class.new({per_page: 5})
15
+
16
+ expect(paginator.paginate(list, 1).to_a).to eq([
17
+ ['a',0],['b',1],['c',2],['d',3]])
18
+ end
19
+
4
20
  it "paginates items matching per_page count" do
5
21
  list = %w(a b c d e f)
6
22
  paginator = described_class.new({per_page: 3})