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
@@ -3,9 +3,10 @@
3
3
  RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
4
4
  let(:input) { StringIO.new }
5
5
  let(:out) { StringIO.new }
6
+ let(:env) { { "TTY_TEST" => true } }
6
7
 
7
8
  it "reads single key press" do
8
- reader = described_class.new(input, out)
9
+ reader = described_class.new(input, out, env: env)
9
10
  input << "\e[Aaaaaaa\n"
10
11
  input.rewind
11
12
 
@@ -15,7 +16,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
15
16
  end
16
17
 
17
18
  it 'reads multibyte key press' do
18
- reader = described_class.new(input, out)
19
+ reader = described_class.new(input, out, env: env)
19
20
  input << "ㄱ"
20
21
  input.rewind
21
22
 
@@ -26,7 +27,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
26
27
 
27
28
  context 'when Ctrl+C pressed' do
28
29
  it "defaults to raising InputInterrupt" do
29
- reader = described_class.new(input, out)
30
+ reader = described_class.new(input, out, env: env)
30
31
  input << "\x03"
31
32
  input.rewind
32
33
 
@@ -36,7 +37,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
36
37
  end
37
38
 
38
39
  it "sends interrupt signal when :signal option is chosen" do
39
- reader = described_class.new(input, out, interrupt: :signal)
40
+ reader = described_class.new(input, out, interrupt: :signal, env: env)
40
41
  input << "\x03"
41
42
  input.rewind
42
43
 
@@ -48,7 +49,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
48
49
  end
49
50
 
50
51
  it "exits with 130 code when :exit option is chosen" do
51
- reader = described_class.new(input, out, interrupt: :exit)
52
+ reader = described_class.new(input, out, interrupt: :exit, env: env)
52
53
  input << "\x03"
53
54
  input.rewind
54
55
 
@@ -59,7 +60,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
59
60
 
60
61
  it "evaluates custom handler when proc object is provided" do
61
62
  handler = proc { raise ArgumentError }
62
- reader = described_class.new(input, out, interrupt: handler)
63
+ reader = described_class.new(input, out, interrupt: handler, env: env)
63
64
  input << "\x03"
64
65
  input.rewind
65
66
 
@@ -69,7 +70,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
69
70
  end
70
71
 
71
72
  it "skips handler when handler is nil" do
72
- reader = described_class.new(input, out, interrupt: :noop)
73
+ reader = described_class.new(input, out, interrupt: :noop, env: env)
73
74
  input << "\x03"
74
75
  input.rewind
75
76
 
@@ -3,30 +3,30 @@
3
3
  RSpec.describe TTY::Prompt::Reader, '#read_line' do
4
4
  let(:input) { StringIO.new }
5
5
  let(:output) { StringIO.new }
6
+ let(:env) { { "TTY_TEST" => true } }
6
7
 
7
- subject(:reader) { described_class.new(input, output) }
8
+ subject(:reader) { described_class.new(input, output, env: env) }
8
9
 
9
10
  it 'masks characters' do
10
- mask = '*'
11
- input << "password"
11
+ input << "password\n"
12
12
  input.rewind
13
- answer = reader.read_line(mask)
14
- expect(answer).to eq("password")
13
+ answer = reader.read_line(echo: false)
14
+ expect(answer).to eq("password\n")
15
15
  end
16
16
 
17
17
  it "echoes characters back" do
18
- input << "password"
18
+ input << "password\n"
19
19
  input.rewind
20
20
  answer = reader.read_line
21
- expect(answer).to eq("password")
21
+ expect(answer).to eq("password\n")
22
22
  expect(output.string).to eq("")
23
23
  end
24
24
 
25
25
  it 'deletes characters when backspace pressed' do
26
- input << "aa\ba\bcc"
26
+ input << "aa\ba\bcc\n"
27
27
  input.rewind
28
28
  answer = reader.read_line
29
- expect(answer).to eq('acc')
29
+ expect(answer).to eq("acc\n")
30
30
  end
31
31
 
32
32
  it 'reads multibyte line' do
@@ -3,8 +3,9 @@
3
3
  RSpec.describe TTY::Prompt::Reader, '#read_multiline' do
4
4
  let(:input) { StringIO.new }
5
5
  let(:output) { StringIO.new }
6
+ let(:env) { { "TTY_TEST" => true } }
6
7
 
7
- subject(:reader) { described_class.new(input, output) }
8
+ subject(:reader) { described_class.new(input, output, env: env) }
8
9
 
9
10
  it 'reads no lines' do
10
11
  input << ''
@@ -14,17 +15,17 @@ RSpec.describe TTY::Prompt::Reader, '#read_multiline' do
14
15
  end
15
16
 
16
17
  it "reads a line" do
17
- input << "Single line"
18
+ input << "Single line\n"
18
19
  input.rewind
19
20
  answer = reader.read_multiline
20
- expect(answer).to eq(['Single line'])
21
+ expect(answer).to eq(["Single line\n"])
21
22
  end
22
23
 
23
24
  it 'reads few lines' do
24
- input << "First line\nSecond line\nThird line"
25
+ input << "First line\nSecond line\nThird line\n"
25
26
  input.rewind
26
27
  answer = reader.read_multiline
27
- expect(answer).to eq(['First line', 'Second line', 'Third line'])
28
+ expect(answer).to eq(["First line\n", "Second line\n", "Third line\n"])
28
29
  end
29
30
 
30
31
  it 'reads and yiels every line' do
@@ -32,7 +33,7 @@ RSpec.describe TTY::Prompt::Reader, '#read_multiline' do
32
33
  input.rewind
33
34
  lines = []
34
35
  reader.read_multiline { |line| lines << line }
35
- expect(lines).to eq(['First line', 'Second line', 'Third line'])
36
+ expect(lines).to eq(["First line\n", "Second line\n", "Third line"])
36
37
  end
37
38
 
38
39
  it 'reads multibyte lines' do
@@ -40,6 +41,6 @@ RSpec.describe TTY::Prompt::Reader, '#read_multiline' do
40
41
  input.rewind
41
42
  lines = []
42
43
  reader.read_multiline { |line| lines << line }
43
- expect(lines).to eq(["국경의 긴 터널을 빠져나오자", '설국이었다.'])
44
+ expect(lines).to eq(["국경의 긴 터널을 빠져나오자\n", '설국이었다.'])
44
45
  end
45
46
  end
@@ -4,6 +4,8 @@ RSpec.describe TTY::Prompt, '#select' do
4
4
 
5
5
  subject(:prompt) { TTY::TestPrompt.new }
6
6
 
7
+ let(:symbols) { TTY::Prompt::Symbols.symbols }
8
+
7
9
  it "selects by default first option" do
8
10
  choices = %w(Large Medium Small)
9
11
  prompt.input << "\r"
@@ -11,14 +13,40 @@ RSpec.describe TTY::Prompt, '#select' do
11
13
  expect(prompt.select('What size?', choices)).to eq('Large')
12
14
  expect(prompt.output.string).to eq([
13
15
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
14
- "\e[32m Large\e[0m\n",
16
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
15
17
  " Medium\n",
16
18
  " Small",
17
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
19
+ "\e[2K\e[1G\e[1A" * 3,
20
+ "\e[2K\e[1G",
18
21
  "What size? \e[32mLarge\e[0m\n\e[?25h"
19
22
  ].join)
20
23
  end
21
24
 
25
+ it "allows navigation using events without errors" do
26
+ choices = %w(Large Medium Small)
27
+ prompt.input << "j" << "\r"
28
+ prompt.input.rewind
29
+ prompt.on(:keypress) do |event|
30
+ prompt.trigger(:keydown) if event.value == "j"
31
+ end
32
+ expect { prompt.select('What size?', choices) }.not_to output.to_stderr
33
+ expect(prompt.output.string).to eq([
34
+ "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
35
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
36
+ " Medium\n",
37
+ " Small",
38
+ "\e[2K\e[1G\e[1A" * 3,
39
+ "\e[2K\e[1G",
40
+ "What size? \n",
41
+ " Large\n",
42
+ "\e[32m#{symbols[:pointer]} Medium\e[0m\n",
43
+ " Small",
44
+ "\e[2K\e[1G\e[1A" * 3,
45
+ "\e[2K\e[1G",
46
+ "What size? \e[32mMedium\e[0m\n\e[?25h"
47
+ ].join)
48
+ end
49
+
22
50
  it "sets choice name and value" do
23
51
  choices = {large: 1, medium: 2, small: 3}
24
52
  prompt.input << " "
@@ -26,10 +54,11 @@ RSpec.describe TTY::Prompt, '#select' do
26
54
  expect(prompt.select('What size?', choices)).to eq(1)
27
55
  expect(prompt.output.string).to eq([
28
56
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
29
- "\e[32m large\e[0m\n",
57
+ "\e[32m#{symbols[:pointer]} large\e[0m\n",
30
58
  " medium\n",
31
59
  " small",
32
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
60
+ "\e[2K\e[1G\e[1A" * 3,
61
+ "\e[2K\e[1G",
33
62
  "What size? \e[32mlarge\e[0m\n\e[?25h"
34
63
  ].join)
35
64
  end
@@ -45,10 +74,11 @@ RSpec.describe TTY::Prompt, '#select' do
45
74
  expect(value).to eq('Large')
46
75
  expect(prompt.output.string).to eq([
47
76
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
48
- "\e[32m Large\e[0m\n",
77
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
49
78
  " Medium\n",
50
79
  " Small",
51
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
80
+ "\e[2K\e[1G\e[1A" * 3,
81
+ "\e[2K\e[1G",
52
82
  "What size? \e[32mLarge\e[0m\n\e[?25h"
53
83
  ].join)
54
84
  end
@@ -64,10 +94,11 @@ RSpec.describe TTY::Prompt, '#select' do
64
94
  expect(value).to eq(1)
65
95
  expect(prompt.output.string).to eq([
66
96
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
67
- "\e[32m large\e[0m\n",
97
+ "\e[32m#{symbols[:pointer]} large\e[0m\n",
68
98
  " medium\n",
69
99
  " small",
70
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
100
+ "\e[2K\e[1G\e[1A" * 3,
101
+ "\e[2K\e[1G",
71
102
  "What size? \e[32mlarge\e[0m\n\e[?25h"
72
103
  ].join)
73
104
  end
@@ -82,10 +113,11 @@ RSpec.describe TTY::Prompt, '#select' do
82
113
  expect(value).to eq('Large')
83
114
  expect(prompt.output.string).to eq([
84
115
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
85
- "\e[32m Large\e[0m\n",
116
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
86
117
  " Medium\n",
87
118
  " Small",
88
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
119
+ "\e[2K\e[1G\e[1A" * 3,
120
+ "\e[2K\e[1G",
89
121
  "What size? \e[32mLarge\e[0m\n\e[?25h"
90
122
  ].join)
91
123
  end
@@ -105,9 +137,10 @@ RSpec.describe TTY::Prompt, '#select' do
105
137
  expect(prompt.output.string).to eq([
106
138
  "\e[?25lWhat size? \e[90m(Use arrow or number (1-3) keys, press Enter to select)\e[0m\n",
107
139
  " 1. large\n",
108
- "\e[32m 2. medium\e[0m\n",
140
+ "\e[32m#{symbols[:pointer]} 2. medium\e[0m\n",
109
141
  " 3. small",
110
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
142
+ "\e[2K\e[1G\e[1A" * 3,
143
+ "\e[2K\e[1G",
111
144
  "What size? \e[32mmedium\e[0m\n\e[?25h"
112
145
  ].join)
113
146
  end
@@ -124,9 +157,10 @@ RSpec.describe TTY::Prompt, '#select' do
124
157
  expect(prompt.output.string).to eq([
125
158
  "\e[?25lWhat size? \e[90m(Use arrow or number (1-3) keys, press Enter to select)\e[0m\n",
126
159
  " 1) large\n",
127
- "\e[32m 2) medium\e[0m\n",
160
+ "\e[32m#{symbols[:pointer]} 2) medium\e[0m\n",
128
161
  " 3) small",
129
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
162
+ "\e[2K\e[1G\e[1A" * 3,
163
+ "\e[2K\e[1G",
130
164
  "What size? \e[32mmedium\e[0m\n\e[?25h"
131
165
  ].join)
132
166
  end
@@ -139,9 +173,10 @@ RSpec.describe TTY::Prompt, '#select' do
139
173
  expect(prompt.output.string).to eq([
140
174
  "\e[?25lWhat size? \e[90m(Use arrow or number (1-3) keys, press Enter to select)\e[0m\n",
141
175
  " 1. Large\n",
142
- "\e[32m 2. Medium\e[0m\n",
176
+ "\e[32m#{symbols[:pointer]} 2. Medium\e[0m\n",
143
177
  " 3. Small",
144
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
178
+ "\e[2K\e[1G\e[1A" * 3,
179
+ "\e[2K\e[1G",
145
180
  "What size? \e[32mMedium\e[0m\n\e[?25h"
146
181
  ].join)
147
182
  end
@@ -158,7 +193,8 @@ RSpec.describe TTY::Prompt, '#select' do
158
193
  "\e[34m> Large\e[0m\n",
159
194
  " Medium\n",
160
195
  " Small",
161
- "\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K",
196
+ "\e[2K\e[1G\e[1A" * 3,
197
+ "\e[2K\e[1G",
162
198
  "What size? \e[34mLarge\e[0m\n\e[?25h"
163
199
  ].join)
164
200
  end
@@ -171,10 +207,11 @@ RSpec.describe TTY::Prompt, '#select' do
171
207
  expect(value).to eq('Large')
172
208
  expect(prompt.output.string).to eq([
173
209
  "\e[?25lWhat size? \e[90m(Bash keyboard)\e[0m\n",
174
- "\e[32m Large\e[0m\n",
210
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
175
211
  " Medium\n",
176
212
  " Small",
177
- "\e[1000D\e[K\e[1A" * 3 + "\e[1000D\e[K",
213
+ "\e[2K\e[1G\e[1A" * 3,
214
+ "\e[2K\e[1G",
178
215
  "What size? \e[32mLarge\e[0m\n\e[?25h"
179
216
  ].join)
180
217
  end
@@ -187,10 +224,11 @@ RSpec.describe TTY::Prompt, '#select' do
187
224
  expect(prompt.select('What size?', choices)).to eq('Large')
188
225
  expect(prompt.output.string).to eq([
189
226
  "\e[?25l[?] What size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
190
- "\e[32m Large\e[0m\n",
227
+ "\e[32m#{symbols[:pointer]} Large\e[0m\n",
191
228
  " Medium\n",
192
229
  " Small",
193
- "\e[1000D\e[K\e[1A" * 3 + "\e[1000D\e[K",
230
+ "\e[2K\e[1G\e[1A" * 3,
231
+ "\e[2K\e[1G",
194
232
  "[?] What size? \e[32mLarge\e[0m\n\e[?25h"
195
233
  ].join)
196
234
  end
@@ -203,11 +241,12 @@ RSpec.describe TTY::Prompt, '#select' do
203
241
  expect(value).to eq('D')
204
242
  expect(prompt.output.string).to eq([
205
243
  "\e[?25lWhat letter? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
206
- "\e[32m D\e[0m\n",
244
+ "\e[32m#{symbols[:pointer]} D\e[0m\n",
207
245
  " E\n",
208
246
  " F\n",
209
247
  "\e[90m(Move up or down to reveal more choices)\e[0m",
210
- "\e[1000D\e[K\e[1A" * 4 + "\e[1000D\e[K",
248
+ "\e[2K\e[1G\e[1A" * 4,
249
+ "\e[2K\e[1G",
211
250
  "What letter? \e[32mD\e[0m\n\e[?25h",
212
251
  ].join)
213
252
  end
@@ -227,11 +266,12 @@ RSpec.describe TTY::Prompt, '#select' do
227
266
  expect(value).to eq('D')
228
267
  expect(prompt.output.string).to eq([
229
268
  "\e[?25lWhat letter? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
230
- "\e[32m D\e[0m\n",
269
+ "\e[32m#{symbols[:pointer]} D\e[0m\n",
231
270
  " E\n",
232
271
  " F\n",
233
272
  "\e[90m(Wiggle thy finger up or down to see more)\e[0m",
234
- "\e[1000D\e[K\e[1A" * 4 + "\e[1000D\e[K",
273
+ "\e[2K\e[1G\e[1A" * 4,
274
+ "\e[2K\e[1G",
235
275
  "What letter? \e[32mD\e[0m\n\e[?25h",
236
276
  ].join)
237
277
  end
@@ -247,6 +287,26 @@ RSpec.describe TTY::Prompt, '#select' do
247
287
  }.to raise_error(TTY::Prompt::ConfigurationError, /in range \(1 - 3\)/)
248
288
  end
249
289
 
290
+ it "doesn't paginate short selections" do
291
+ prompt = TTY::TestPrompt.new
292
+ choices = %w(A B C D)
293
+ prompt.input << "\r"
294
+ prompt.input.rewind
295
+ value = prompt.select("What letter?", choices, per_page: 4, default: 1)
296
+ expect(value).to eq('A')
297
+
298
+ expect(prompt.output.string).to eq([
299
+ "\e[?25lWhat letter? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
300
+ "\e[32m#{symbols[:pointer]} A\e[0m\n",
301
+ " B\n",
302
+ " C\n",
303
+ " D",
304
+ "\e[2K\e[1G\e[1A" * 4,
305
+ "\e[2K\e[1G",
306
+ "What letter? \e[32mA\e[0m\n\e[?25h",
307
+ ].join)
308
+ end
309
+
250
310
  it "verifies default index range" do
251
311
  prompt = TTY::TestPrompt.new
252
312
  choices = %w(Large Medium Small)
@@ -4,16 +4,18 @@ RSpec.describe TTY::Prompt, '#slider' do
4
4
 
5
5
  subject(:prompt) { TTY::TestPrompt.new }
6
6
 
7
+ let(:symbols) { TTY::Prompt::Symbols.symbols }
8
+
7
9
  it "specifies ranges & step" do
8
10
  prompt.input << "\r"
9
11
  prompt.input.rewind
10
12
  expect(prompt.slider('What size?', min: 32, max: 54, step: 2)).to eq(44)
11
13
  expect(prompt.output.string).to eq([
12
14
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
13
- "|------",
14
- "\e[32mO\e[0m",
15
- "-----| 44",
16
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
15
+ symbols[:pipe] + symbols[:line] * 6,
16
+ "\e[32m#{symbols[:handle]}\e[0m",
17
+ "#{symbols[:line] * 5 + symbols[:pipe]} 44",
18
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
17
19
  "What size? \e[32m44\e[0m\n\e[?25h"
18
20
  ].join)
19
21
  end
@@ -24,10 +26,10 @@ RSpec.describe TTY::Prompt, '#slider' do
24
26
  expect(prompt.slider('What size?', min: 32, max: 54, step: 2, default: 38)).to eq(38)
25
27
  expect(prompt.output.string).to eq([
26
28
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
27
- "|---",
28
- "\e[32mO\e[0m",
29
- "--------| 38",
30
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
29
+ symbols[:pipe] + symbols[:line] * 3,
30
+ "\e[32m#{symbols[:handle]}\e[0m",
31
+ "#{symbols[:line] * 8 + symbols[:pipe]} 38",
32
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
31
33
  "What size? \e[32m38\e[0m\n\e[?25h"
32
34
  ].join)
33
35
  end
@@ -44,10 +46,10 @@ RSpec.describe TTY::Prompt, '#slider' do
44
46
  expect(value).to eq(6)
45
47
  expect(prompt.output.string).to eq([
46
48
  "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
47
- "|---",
48
- "\e[32mO\e[0m",
49
- "-------| 6",
50
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
49
+ symbols[:pipe] + symbols[:line] * 3,
50
+ "\e[32m#{symbols[:handle]}\e[0m",
51
+ "#{symbols[:line] * 7 + symbols[:pipe]} 6",
52
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
51
53
  "What size? \e[32m6\e[0m\n\e[?25h"
52
54
  ].join)
53
55
  end
@@ -59,11 +61,36 @@ RSpec.describe TTY::Prompt, '#slider' do
59
61
  expect(prompt.slider('What size?', options)).to eq(5)
60
62
  expect(prompt.output.string).to eq([
61
63
  "\e[?25lWhat size? \e[36m(Use arrow keys, press Enter to select)\e[0m\n",
62
- "|-----",
63
- "\e[31mO\e[0m",
64
- "-----| 5",
65
- "\e[1000D\e[K\e[1A\e[1000D\e[K",
64
+ symbols[:pipe] + symbols[:line] * 5,
65
+ "\e[31m#{symbols[:handle]}\e[0m",
66
+ "#{symbols[:line] * 5 + symbols[:pipe]} 5",
67
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
66
68
  "What size? \e[31m5\e[0m\n\e[?25h"
67
69
  ].join)
68
70
  end
71
+
72
+ it "doesn't allow values outside of range" do
73
+ prompt.input << "l\r"
74
+ prompt.input.rewind
75
+ prompt.on(:keypress) do |event|
76
+ if event.value = 'l'
77
+ prompt.trigger(:keyright)
78
+ end
79
+ end
80
+ res = prompt.slider('What size?', min: 0, max: 10, step: 1, default: 10)
81
+ expect(res).to eq(10)
82
+ expect(prompt.output.string).to eq([
83
+ "\e[?25lWhat size? \e[90m(Use arrow keys, press Enter to select)\e[0m\n",
84
+ symbols[:pipe] + symbols[:line] * 10,
85
+ "\e[32m#{symbols[:handle]}\e[0m",
86
+ "#{symbols[:pipe]} 10",
87
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
88
+ "What size? \n",
89
+ symbols[:pipe] + symbols[:line] * 10,
90
+ "\e[32m#{symbols[:handle]}\e[0m",
91
+ "#{symbols[:pipe]} 10",
92
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
93
+ "What size? \e[32m10\e[0m\n\e[?25h"
94
+ ].join)
95
+ end
69
96
  end