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
@@ -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