tty-prompt 0.12.0 → 0.13.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 (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