tty-prompt 0.10.1 → 0.11.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 (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})