tty-prompt 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -3
  3. data/CHANGELOG.md +12 -0
  4. data/README.md +3 -3
  5. data/appveyor.yml +2 -0
  6. data/lib/tty/prompt/keypress.rb +7 -4
  7. data/lib/tty/prompt/reader.rb +1 -1
  8. data/lib/tty/prompt/reader/win_api.rb +14 -0
  9. data/lib/tty/prompt/reader/win_console.rb +9 -2
  10. data/lib/tty/prompt/timeout.rb +44 -23
  11. data/lib/tty/prompt/version.rb +1 -1
  12. data/tty-prompt.gemspec +6 -3
  13. metadata +21 -131
  14. data/spec/spec_helper.rb +0 -45
  15. data/spec/unit/ask_spec.rb +0 -132
  16. data/spec/unit/choice/eql_spec.rb +0 -22
  17. data/spec/unit/choice/from_spec.rb +0 -29
  18. data/spec/unit/choices/add_spec.rb +0 -12
  19. data/spec/unit/choices/each_spec.rb +0 -13
  20. data/spec/unit/choices/find_by_spec.rb +0 -10
  21. data/spec/unit/choices/new_spec.rb +0 -10
  22. data/spec/unit/choices/pluck_spec.rb +0 -9
  23. data/spec/unit/collect_spec.rb +0 -33
  24. data/spec/unit/converters/convert_bool_spec.rb +0 -58
  25. data/spec/unit/converters/convert_char_spec.rb +0 -11
  26. data/spec/unit/converters/convert_custom_spec.rb +0 -14
  27. data/spec/unit/converters/convert_date_spec.rb +0 -34
  28. data/spec/unit/converters/convert_file_spec.rb +0 -17
  29. data/spec/unit/converters/convert_number_spec.rb +0 -39
  30. data/spec/unit/converters/convert_path_spec.rb +0 -18
  31. data/spec/unit/converters/convert_range_spec.rb +0 -22
  32. data/spec/unit/converters/convert_regex_spec.rb +0 -12
  33. data/spec/unit/converters/convert_string_spec.rb +0 -21
  34. data/spec/unit/converters/on_error_spec.rb +0 -9
  35. data/spec/unit/distance/distance_spec.rb +0 -73
  36. data/spec/unit/enum_paginator_spec.rb +0 -65
  37. data/spec/unit/enum_select_spec.rb +0 -310
  38. data/spec/unit/error_spec.rb +0 -20
  39. data/spec/unit/evaluator_spec.rb +0 -67
  40. data/spec/unit/expand_spec.rb +0 -198
  41. data/spec/unit/keypress_spec.rb +0 -58
  42. data/spec/unit/mask_spec.rb +0 -132
  43. data/spec/unit/multi_select_spec.rb +0 -319
  44. data/spec/unit/multiline_spec.rb +0 -77
  45. data/spec/unit/new_spec.rb +0 -20
  46. data/spec/unit/ok_spec.rb +0 -10
  47. data/spec/unit/paginator_spec.rb +0 -63
  48. data/spec/unit/question/checks_spec.rb +0 -97
  49. data/spec/unit/question/default_spec.rb +0 -31
  50. data/spec/unit/question/echo_spec.rb +0 -38
  51. data/spec/unit/question/in_spec.rb +0 -115
  52. data/spec/unit/question/initialize_spec.rb +0 -12
  53. data/spec/unit/question/modifier/apply_to_spec.rb +0 -24
  54. data/spec/unit/question/modifier/letter_case_spec.rb +0 -41
  55. data/spec/unit/question/modifier/whitespace_spec.rb +0 -51
  56. data/spec/unit/question/modify_spec.rb +0 -41
  57. data/spec/unit/question/required_spec.rb +0 -92
  58. data/spec/unit/question/validate_spec.rb +0 -115
  59. data/spec/unit/question/validation/call_spec.rb +0 -31
  60. data/spec/unit/question/validation/coerce_spec.rb +0 -30
  61. data/spec/unit/reader/history_spec.rb +0 -172
  62. data/spec/unit/reader/key_event_spec.rb +0 -86
  63. data/spec/unit/reader/line_spec.rb +0 -110
  64. data/spec/unit/reader/publish_keypress_event_spec.rb +0 -94
  65. data/spec/unit/reader/read_keypress_spec.rb +0 -80
  66. data/spec/unit/reader/read_line_spec.rb +0 -68
  67. data/spec/unit/reader/read_multiline_spec.rb +0 -60
  68. data/spec/unit/result_spec.rb +0 -40
  69. data/spec/unit/say_spec.rb +0 -67
  70. data/spec/unit/select_spec.rb +0 -359
  71. data/spec/unit/slider_spec.rb +0 -96
  72. data/spec/unit/statement/initialize_spec.rb +0 -15
  73. data/spec/unit/suggest_spec.rb +0 -28
  74. data/spec/unit/warn_spec.rb +0 -21
  75. data/spec/unit/yes_no_spec.rb +0 -235
@@ -1,20 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt, '.error' do
4
- subject(:prompt) { TTY::TestPrompt.new }
5
-
6
- it 'displays one message' do
7
- prompt.error "Nothing is fine!"
8
- expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m\n"
9
- end
10
-
11
- it 'displays many messages' do
12
- prompt.error "Nothing is fine!", "All is broken!"
13
- expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m\n\e[31mAll is broken!\e[0m\n"
14
- end
15
-
16
- it 'displays message with option' do
17
- prompt.error "Nothing is fine!", newline: false
18
- expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m"
19
- end
20
- end
@@ -1,67 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Evaluator do
4
- it "checks chained validation procs" do
5
- question = double(:question)
6
- evaluator = TTY::Prompt::Evaluator.new(question)
7
-
8
- evaluator.check { |quest, value|
9
- if value < 21
10
- [value, ["#{value} is not bigger than 21"]]
11
- else
12
- value
13
- end
14
- }
15
-
16
- evaluator.check { |quest, value|
17
- if value < 42
18
- [value, ["#{value} is not bigger than 42"]]
19
- else
20
- value
21
- end
22
- }
23
-
24
- answer = evaluator.call(2)
25
- expect(answer.errors.count).to eq(2)
26
- expect(answer.value).to eq(2)
27
- expect(answer.success?).to eq(false)
28
- expect(answer.failure?).to eq(true)
29
- end
30
-
31
- it "checks chained validation objects" do
32
- question = double(:question)
33
- evaluator = TTY::Prompt::Evaluator.new(question)
34
-
35
- LessThan21 = Class.new do
36
- def self.call(quest, value)
37
- if value < 21
38
- [value, ["#{value} is not bigger than 21"]]
39
- else
40
- value
41
- end
42
- end
43
- end
44
-
45
- LessThan42 = Class.new do
46
- def self.call(quest, value)
47
- if value < 42
48
- [value, ["#{value} is not bigger than 42"]]
49
- else
50
- value
51
- end
52
- end
53
- end
54
-
55
- evaluator.check(LessThan21)
56
- evaluator.check(LessThan42)
57
-
58
- answer = evaluator.call(2)
59
- expect(answer.errors).to match_array([
60
- "2 is not bigger than 21",
61
- "2 is not bigger than 42"
62
- ])
63
- expect(answer.value).to eq(2)
64
- expect(answer.success?).to eq(false)
65
- expect(answer.failure?).to eq(true)
66
- end
67
- end
@@ -1,198 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt, '#expand' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- let(:choices) {
8
- [{
9
- key: 'y',
10
- name: 'Overwrite',
11
- value: :yes
12
- }, {
13
- key: 'n',
14
- name: 'Skip',
15
- value: :no
16
- }, {
17
- key: 'a',
18
- name: 'Overwrite all',
19
- value: :all
20
- }, {
21
- key: 'd',
22
- name: 'Show diff',
23
- value: :diff
24
- }, {
25
- key: 'q',
26
- name: 'Quit',
27
- value: :quit
28
- }]
29
- }
30
-
31
- it "expands default option" do
32
- prompt.input << "\n"
33
- prompt.input.rewind
34
-
35
- result = prompt.expand('Overwrite Gemfile?', choices)
36
- expect(result).to eq(:yes)
37
-
38
- expect(prompt.output.string).to eq([
39
- "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
40
- "\e[2K\e[1G",
41
- "Overwrite Gemfile? \e[32mOverwrite\e[0m\n"
42
- ].join)
43
- end
44
-
45
- it "changes default option" do
46
- prompt.input << "\n"
47
- prompt.input.rewind
48
-
49
- result = prompt.expand('Overwrite Gemfile?', choices, default: 3)
50
- expect(result).to eq(:all)
51
-
52
- expect(prompt.output.string).to eq([
53
- "Overwrite Gemfile? (enter \"h\" for help) [y,n,\e[32ma\e[0m,d,q,h] ",
54
- "\e[2K\e[1G",
55
- "Overwrite Gemfile? \e[32mOverwrite all\e[0m\n"
56
- ].join)
57
- end
58
-
59
- it "expands chosen option with extra information" do
60
- prompt.input << "a\n"
61
- prompt.input.rewind
62
-
63
- result = prompt.expand('Overwrite Gemfile?', choices)
64
- expect(result).to eq(:all)
65
-
66
- expect(prompt.output.string).to eq([
67
- "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
68
- "\e[2K\e[1G",
69
- "Overwrite Gemfile? (enter \"h\" for help) [y,n,\e[32ma\e[0m,d,q,h] ",
70
- "a\n",
71
- "\e[32m>> \e[0mOverwrite all",
72
- "\e[A\e[1G\e[55C",
73
- "\e[2K\e[1G",
74
- "\e[1B",
75
- "\e[2K\e[1G",
76
- "\e[A\e[1G",
77
- "Overwrite Gemfile? \e[32mOverwrite all\e[0m\n"
78
- ].join)
79
- end
80
-
81
- it "expands help option and then defaults" do
82
- prompt.input << "h\nd\n"
83
- prompt.input.rewind
84
-
85
- result = prompt.expand('Overwrite Gemfile?', choices)
86
- expect(result).to eq(:diff)
87
-
88
- expect(prompt.output.string).to eq([
89
- "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
90
- "\e[2K\e[1G",
91
- "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,d,q,\e[32mh\e[0m] h\n",
92
- "\e[32m>> \e[0mprint help",
93
- "\e[A\e[1G\e[55C",
94
- "\e[2K\e[1G",
95
- "\e[1B",
96
- "\e[2K\e[1G",
97
- "\e[A\e[1G",
98
- "Overwrite Gemfile? \n",
99
- " y - Overwrite\n",
100
- " n - Skip\n",
101
- " a - Overwrite all\n",
102
- " d - Show diff\n",
103
- " q - Quit\n",
104
- " h - print help\n",
105
- " Choice [y]: ",
106
- "\e[2K\e[1G\e[1A" * 7,
107
- "\e[2K\e[1G",
108
- "Overwrite Gemfile? \n",
109
- " y - Overwrite\n",
110
- " n - Skip\n",
111
- " a - Overwrite all\n",
112
- " \e[32md - Show diff\e[0m\n",
113
- " q - Quit\n",
114
- " h - print help\n",
115
- " Choice [y]: d",
116
- "\e[2K\e[1G\e[1A" * 7,
117
- "\e[2K\e[1G",
118
- "Overwrite Gemfile? \e[32mShow diff\e[0m\n",
119
- ].join)
120
- end
121
-
122
- it "specifies options through DSL" do
123
- prompt.input << "\n"
124
- prompt.input.rewind
125
-
126
- result = prompt.expand('Overwrite Gemfile?') do |q|
127
- q.default 4
128
-
129
- q.choice key: 'y', name: 'Overwrite', value: :yes
130
- q.choice key: 'n', name: 'Skip', value: :no
131
- q.choice key: 'a', name: 'Overwrite all', value: :all
132
- q.choice key: 'd', name: 'Show diff', value: :diff
133
- q.choice key: 'q', name: 'Quit', value: :quit
134
- end
135
-
136
- expect(result).to eq(:diff)
137
-
138
- expect(prompt.output.string).to eq([
139
- "Overwrite Gemfile? (enter \"h\" for help) [y,n,a,\e[32md\e[0m,q,h] ",
140
- "\e[2K\e[1G",
141
- "Overwrite Gemfile? \e[32mShow diff\e[0m\n"
142
- ].join)
143
- end
144
-
145
- it "specifies options through DSL and executes value" do
146
- prompt.input << "\n"
147
- prompt.input.rewind
148
-
149
- result = prompt.expand('Overwrite Gemfile?') do |q|
150
- q.choice key: 'y', name: 'Overwrite' do :ok end
151
- q.choice key: 'n', name: 'Skip', value: :no
152
- q.choice key: 'a', name: 'Overwrite all', value: :all
153
- q.choice key: 'd', name: 'Show diff', value: :diff
154
- q.choice key: 'q', name: 'Quit', value: :quit
155
- end
156
-
157
- expect(result).to eq(:ok)
158
-
159
- expect(prompt.output.string).to eq([
160
- "Overwrite Gemfile? (enter \"h\" for help) [\e[32my\e[0m,n,a,d,q,h] ",
161
- "\e[2K\e[1G",
162
- "Overwrite Gemfile? \e[32mOverwrite\e[0m\n"
163
- ].join)
164
- end
165
-
166
- it "fails to expand due to lack of key attribute" do
167
- choices = [{ name: 'Overwrite', value: :yes }]
168
-
169
- expect {
170
- prompt.expand('Overwrite Gemfile?', choices)
171
- }.to raise_error(TTY::Prompt::ConfigurationError, /Choice Overwrite is missing a :key attribute/)
172
- end
173
-
174
- it "fails to expand due to wrong key length" do
175
- choices = [{ key: 'long', name: 'Overwrite', value: :yes }]
176
-
177
- expect {
178
- prompt.expand('Overwrite Gemfile?', choices)
179
- }.to raise_error(TTY::Prompt::ConfigurationError, /Choice key `long` is more than one character long/)
180
- end
181
-
182
- it "fails to expand due to reserve key" do
183
- choices = [{ key: 'h', name: 'Overwrite', value: :yes }]
184
-
185
- expect {
186
- prompt.expand('Overwrite Gemfile?', choices)
187
- }.to raise_error(TTY::Prompt::ConfigurationError, /Choice key `h` is reserved for help menu/)
188
- end
189
-
190
- it "fails to expand due to duplicate key" do
191
- choices = [{ key: 'y', name: 'Overwrite', value: :yes },
192
- { key: 'y', name: 'Change', value: :yes }]
193
-
194
- expect {
195
- prompt.expand('Overwrite Gemfile?', choices)
196
- }.to raise_error(TTY::Prompt::ConfigurationError, /Choice key `y` is a duplicate/)
197
- end
198
- end
@@ -1,58 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Question, '#keypress' do
4
- it 'receives line feed with echo on' do
5
- prompt = TTY::TestPrompt.new
6
- prompt.input << "\n"
7
- prompt.input.rewind
8
-
9
- answer = prompt.keypress("Press key:", echo: true)
10
-
11
- expect(answer).to eq("\n")
12
- expect(prompt.output.string).to eq([
13
- "Press key: ",
14
- "\e[2K\e[1G",
15
- "Press key: \e[32m\n\e[0m\n",
16
- ].join)
17
- end
18
-
19
- it 'asks for a keypress with echo on' do
20
- prompt = TTY::TestPrompt.new
21
- prompt.input << "abcd"
22
- prompt.input.rewind
23
-
24
- answer = prompt.keypress("Press key:", echo: true)
25
-
26
- expect(answer).to eq("a")
27
- expect(prompt.output.string).to eq([
28
- "Press key: ",
29
- "\e[2K\e[1G",
30
- "Press key: \e[32ma\e[0m\n",
31
- ].join)
32
- end
33
-
34
- it 'asks for a keypress with echo off' do
35
- prompt = TTY::TestPrompt.new
36
- prompt.input << "abcd"
37
- prompt.input.rewind
38
-
39
- answer = prompt.keypress("Press key:")
40
-
41
- expect(answer).to eq("a")
42
- expect(prompt.output.string).to eq([
43
- "Press key: ",
44
- "\e[2K\e[1G",
45
- "Press key: \n",
46
- ].join)
47
- end
48
-
49
- it "interrupts input" do
50
- prompt = TTY::TestPrompt.new(interrupt: :exit)
51
- prompt.input << "\x03"
52
- prompt.input.rewind
53
-
54
- expect {
55
- prompt.keypress("Press key:")
56
- }.to raise_error(SystemExit)
57
- end
58
- end
@@ -1,132 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt, '#mask' do
4
-
5
- subject(:prompt) { TTY::TestPrompt.new }
6
-
7
- let(:symbols) { TTY::Prompt::Symbols.symbols }
8
-
9
- it "masks output by default" do
10
- prompt.input << "pass\r"
11
- prompt.input.rewind
12
- answer = prompt.mask("What is your password?")
13
- expect(answer).to eql("pass")
14
- expect(prompt.output.string).to eq([
15
- "What is your password? ",
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"
28
- ].join)
29
- end
30
-
31
- it 'masks output with custom character' do
32
- prompt.input << "pass\r"
33
- prompt.input.rewind
34
- answer = prompt.mask("What is your password?") { |q| q.mask('*') }
35
- expect(answer).to eql("pass")
36
- expect(prompt.output.string).to eq([
37
- "What is your password? ",
38
- "\e[2K\e[1G",
39
- "What is your password? *",
40
- "\e[2K\e[1G",
41
- "What is your password? **",
42
- "\e[2K\e[1G",
43
- "What is your password? ***",
44
- "\e[2K\e[1G",
45
- "What is your password? ****",
46
- "\e[2K\e[1G",
47
- "What is your password? \e[32m****\e[0m\n",
48
- "\e[1A\e[2K\e[1G",
49
- "What is your password? \e[32m****\e[0m\n",
50
- ].join)
51
- end
52
-
53
- it "masks with unicode character" do
54
- prompt.input << "lov\n"
55
- prompt.input.rewind
56
- answer = prompt.mask("What is your password?", mask: "\u2665")
57
- expect(answer).to eql("lov")
58
- expect(prompt.output.string).to eq([
59
- "What is your password? ",
60
- "\e[2K\e[1G",
61
- "What is your password? ♥",
62
- "\e[2K\e[1G",
63
- "What is your password? ♥♥",
64
- "\e[2K\e[1G",
65
- "What is your password? ♥♥♥",
66
- "\e[2K\e[1G",
67
- "What is your password? \e[32m♥♥♥\e[0m\n",
68
- "\e[1A\e[2K\e[1G",
69
- "What is your password? \e[32m♥♥♥\e[0m\n",
70
- ].join)
71
- end
72
-
73
- it 'ignores mask if echo is off' do
74
- prompt.input << "pass\n"
75
- prompt.input.rewind
76
- answer = prompt.mask('What is your password?') do |q|
77
- q.echo false
78
- q.mask '*'
79
- end
80
- expect(answer).to eql("pass")
81
- expect(prompt.output.string).to eq([
82
- "What is your password? ",
83
- "\e[2K\e[1G",
84
- "What is your password? ",
85
- "\e[2K\e[1G",
86
- "What is your password? ",
87
- "\e[2K\e[1G",
88
- "What is your password? ",
89
- "\e[2K\e[1G",
90
- "What is your password? ",
91
- "\e[2K\e[1G",
92
- "What is your password? \n",
93
- "\e[2K\e[1G",
94
- "What is your password? \n",
95
- ].join)
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
132
- end