tty-prompt 0.11.0 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +66 -7
  4. data/examples/key_events.rb +11 -0
  5. data/examples/keypress.rb +3 -5
  6. data/examples/multiline.rb +9 -0
  7. data/examples/pause.rb +7 -0
  8. data/lib/tty/prompt.rb +82 -44
  9. data/lib/tty/prompt/confirm_question.rb +20 -36
  10. data/lib/tty/prompt/enum_list.rb +32 -23
  11. data/lib/tty/prompt/expander.rb +35 -31
  12. data/lib/tty/prompt/keypress.rb +91 -0
  13. data/lib/tty/prompt/list.rb +38 -23
  14. data/lib/tty/prompt/mask_question.rb +4 -7
  15. data/lib/tty/prompt/multi_list.rb +3 -1
  16. data/lib/tty/prompt/multiline.rb +71 -0
  17. data/lib/tty/prompt/question.rb +33 -35
  18. data/lib/tty/prompt/reader.rb +154 -38
  19. data/lib/tty/prompt/reader/codes.rb +4 -4
  20. data/lib/tty/prompt/reader/console.rb +1 -1
  21. data/lib/tty/prompt/reader/history.rb +145 -0
  22. data/lib/tty/prompt/reader/key_event.rb +4 -0
  23. data/lib/tty/prompt/reader/line.rb +162 -0
  24. data/lib/tty/prompt/reader/mode.rb +2 -2
  25. data/lib/tty/prompt/reader/win_console.rb +5 -1
  26. data/lib/tty/prompt/slider.rb +18 -12
  27. data/lib/tty/prompt/timeout.rb +48 -0
  28. data/lib/tty/prompt/version.rb +1 -1
  29. data/spec/unit/ask_spec.rb +15 -0
  30. data/spec/unit/converters/convert_bool_spec.rb +1 -0
  31. data/spec/unit/keypress_spec.rb +35 -6
  32. data/spec/unit/multi_select_spec.rb +18 -0
  33. data/spec/unit/multiline_spec.rb +67 -9
  34. data/spec/unit/question/default_spec.rb +1 -0
  35. data/spec/unit/question/echo_spec.rb +8 -0
  36. data/spec/unit/question/in_spec.rb +13 -0
  37. data/spec/unit/question/required_spec.rb +31 -2
  38. data/spec/unit/question/validate_spec.rb +39 -9
  39. data/spec/unit/reader/history_spec.rb +172 -0
  40. data/spec/unit/reader/key_event_spec.rb +12 -8
  41. data/spec/unit/reader/line_spec.rb +110 -0
  42. data/spec/unit/reader/publish_keypress_event_spec.rb +11 -0
  43. data/spec/unit/reader/read_line_spec.rb +32 -2
  44. data/spec/unit/reader/read_multiline_spec.rb +21 -7
  45. data/spec/unit/select_spec.rb +40 -1
  46. data/spec/unit/yes_no_spec.rb +48 -4
  47. metadata +14 -3
  48. data/lib/tty/prompt/history.rb +0 -16
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+
3
+ module TTY
4
+ class Prompt
5
+ class Timeout
6
+ Error = Class.new(RuntimeError)
7
+
8
+ TIMEOUT_HANDLER = proc { |t| t.raise Error, 'timeout expired' }
9
+
10
+ def initialize(options = {})
11
+ @timeout_handler = options.fetch(:timeout_handler) { TIMEOUT_HANDLER }
12
+ @interval_handler = options.fetch(:interval_handler) { proc { } }
13
+ @lock = Mutex.new
14
+ end
15
+
16
+ def self.timeout(secs, interval, &block)
17
+ (@scheduler ||= new).timeout(secs, interval, &block)
18
+ end
19
+
20
+ def timeout(secs, interval, &block)
21
+ return block.() if secs.nil? || secs.to_i.zero?
22
+ @lock.synchronize do
23
+ @runner = Thread.new {
24
+ run_in(secs, interval)
25
+ }
26
+ end
27
+ block.()
28
+ end
29
+
30
+ def run_in(secs, interval)
31
+ Thread.current.abort_on_exception = true
32
+ start = Time.now
33
+
34
+ loop do
35
+ sleep(interval)
36
+ runtime = Time.now - start
37
+ delta = secs - runtime
38
+ @interval_handler.(delta.round)
39
+
40
+ if delta < 0.0
41
+ @timeout_handler.(Thread.current)
42
+ break
43
+ end
44
+ end
45
+ end
46
+ end # Scheduler
47
+ end # Prompt
48
+ end # TTY
@@ -2,6 +2,6 @@
2
2
 
3
3
  module TTY
4
4
  class Prompt
5
- VERSION = "0.11.0"
5
+ VERSION = "0.12.0"
6
6
  end # Prompt
7
7
  end # TTY
@@ -34,6 +34,7 @@ RSpec.describe TTY::Prompt, '#ask' do
34
34
  expect(answer).to eq(nil)
35
35
  expect(prompt.output.string).to eq([
36
36
  "[?] Are you Polish? ",
37
+ "\e[2K\e[1G[?] Are you Polish? \n",
37
38
  "\e[1A\e[2K\e[1G",
38
39
  "[?] Are you Polish? \n"
39
40
  ].join)
@@ -74,6 +75,7 @@ RSpec.describe TTY::Prompt, '#ask' do
74
75
  expect(answer).to eq('')
75
76
  expect(prompt.output.string).to eq([
76
77
  "What is your name? ",
78
+ "\e[2K\e[1GWhat is your name? \n",
77
79
  "\e[1A\e[2K\e[1G",
78
80
  "What is your name? \n"
79
81
  ].join)
@@ -87,6 +89,7 @@ RSpec.describe TTY::Prompt, '#ask' do
87
89
  expect(answer).to eq(nil)
88
90
  expect(prompt.output.string).to eq([
89
91
  "What is your name? ",
92
+ "\e[2K\e[1GWhat is your name? \n",
90
93
  "\e[1A\e[2K\e[1G",
91
94
  "What is your name? \n"
92
95
  ].join)
@@ -107,9 +110,21 @@ RSpec.describe TTY::Prompt, '#ask' do
107
110
 
108
111
  expect(prompt.output.string).to eq([
109
112
  "[?] What is your name? ",
113
+ "\e[2K\e[1G[?] What is your name? P",
114
+ "\e[2K\e[1G[?] What is your name? Pi",
115
+ "\e[2K\e[1G[?] What is your name? Pio",
116
+ "\e[2K\e[1G[?] What is your name? Piot",
117
+ "\e[2K\e[1G[?] What is your name? Piotr",
118
+ "\e[2K\e[1G[?] What is your name? Piotr\n",
110
119
  "\e[1A\e[2K\e[1G",
111
120
  "[?] What is your name? \e[36mPiotr\e[0m\n",
112
121
  ":-) What is your name? ",
122
+ "\e[2K\e[1G:-) What is your name? P",
123
+ "\e[2K\e[1G:-) What is your name? Pi",
124
+ "\e[2K\e[1G:-) What is your name? Pio",
125
+ "\e[2K\e[1G:-) What is your name? Piot",
126
+ "\e[2K\e[1G:-) What is your name? Piotr",
127
+ "\e[2K\e[1G:-) What is your name? Piotr\n",
113
128
  "\e[1A\e[2K\e[1G",
114
129
  ":-) What is your name? \e[34mPiotr\e[0m\n"
115
130
  ].join)
@@ -19,6 +19,7 @@ RSpec.describe TTY::Prompt::Question, 'convert bool' do
19
19
  expect(response).to eql(true)
20
20
  expect(prompt.output.string).to eq([
21
21
  "Do you read books? \e[90m(true)\e[0m ",
22
+ "\e[2K\e[1GDo you read books? \e[90m(true)\e[0m \n",
22
23
  "\e[1A\e[2K\e[1G",
23
24
  "Do you read books? \e[32mtrue\e[0m\n"
24
25
  ].join)
@@ -1,20 +1,49 @@
1
1
  # encoding: utf-8
2
2
 
3
- RSpec.describe TTY::Prompt::Question, 'ask keypress' do
4
- it 'asks for a keypress with :read option' do
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
5
20
  prompt = TTY::TestPrompt.new
6
21
  prompt.input << "abcd"
7
22
  prompt.input.rewind
8
- answer = prompt.ask("Which one do you prefer a, b, c or d?", read: :keypress)
23
+
24
+ answer = prompt.keypress("Press key:", echo: true)
25
+
9
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)
10
32
  end
11
33
 
12
- it 'asks for a keypress with method' do
34
+ it 'asks for a keypress with echo off' do
13
35
  prompt = TTY::TestPrompt.new
14
36
  prompt.input << "abcd"
15
37
  prompt.input.rewind
16
- answer = prompt.keypress("Which one do you prefer a, b, c or d?")
38
+
39
+ answer = prompt.keypress("Press key:")
40
+
17
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)
18
47
  end
19
48
 
20
49
  it "interrupts input" do
@@ -23,7 +52,7 @@ RSpec.describe TTY::Prompt::Question, 'ask keypress' do
23
52
  prompt.input.rewind
24
53
 
25
54
  expect {
26
- prompt.keypress("Which one do you prefer a, b, c or d?")
55
+ prompt.keypress("Press key:")
27
56
  }.to raise_error(SystemExit)
28
57
  end
29
58
  end
@@ -257,6 +257,24 @@ RSpec.describe TTY::Prompt do
257
257
  ].join)
258
258
  end
259
259
 
260
+ it "paginates choices as hash object" do
261
+ prompt = TTY::TestPrompt.new
262
+ choices = {A: 1, B: 2, C: 3, D: 4, E: 5, F: 6, G: 7, H: 8}
263
+ prompt.input << "\r"
264
+ prompt.input.rewind
265
+ value = prompt.multi_select("What letter?", choices, default: 4, per_page: 3)
266
+ expect(value).to eq([4])
267
+ expect(prompt.output.string).to eq([
268
+ "\e[?25lWhat letter? D \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
269
+ "#{symbols[:pointer]} \e[32m#{symbols[:radio_on]}\e[0m D\n",
270
+ " #{symbols[:radio_off]} E\n",
271
+ " #{symbols[:radio_off]} F\n",
272
+ "\e[90m(Move up or down to reveal more choices)\e[0m",
273
+ "\e[2K\e[1G\e[1A" * 4, "\e[2K\e[1G",
274
+ "What letter? \e[32mD\e[0m\n\e[?25h",
275
+ ].join)
276
+ end
277
+
260
278
  it "paginates long selections through DSL" do
261
279
  prompt = TTY::TestPrompt.new
262
280
  choices = %w(A B C D E F G H)
@@ -1,19 +1,77 @@
1
1
  # encoding: utf-8
2
2
 
3
- RSpec.describe TTY::Prompt::Question, 'ask multiline' do
4
- it 'reads multiple lines with :read option' do
3
+ RSpec.describe TTY::Prompt::Question, '#multiline' do
4
+ it 'reads no lines' do
5
5
  prompt = TTY::TestPrompt.new
6
- prompt.input << "First line\nSecond line\nThird line"
6
+ prompt.input << "\C-d"
7
7
  prompt.input.rewind
8
- answer = prompt.ask("Provide description?", read: :multiline)
9
- expect(answer).to eq(['First line', 'Second line', 'Third line'])
8
+
9
+ answer = prompt.multiline("Description?")
10
+
11
+ expect(answer).to eq([])
12
+ expect(prompt.output.string).to eq([
13
+ "Description? \e[90m(Press CTRL-D or CTRL-Z to finish)\e[0m\n",
14
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
15
+ "Description? \n"
16
+ ].join)
17
+ end
18
+
19
+ it "uses defualt when no input" do
20
+ prompt = TTY::TestPrompt.new
21
+ prompt.input << "\C-d"
22
+ prompt.input.rewind
23
+
24
+ answer = prompt.multiline("Description?", default: 'A super sweet prompt')
25
+
26
+ expect(answer).to eq([])
27
+ expect(prompt.output.string).to eq([
28
+ "Description? \e[90m(Press CTRL-D or CTRL-Z to finish)\e[0m\n",
29
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
30
+ "Description? \e[32mA super sweet prompt\e[0m\n"
31
+ ].join)
10
32
  end
11
33
 
12
- it 'reads multiple lines with method' do
34
+ it "changes help text" do
13
35
  prompt = TTY::TestPrompt.new
14
- prompt.input << "First\nSecond\nThird"
36
+ prompt.input << "\C-d"
15
37
  prompt.input.rewind
16
- answer = prompt.multiline("Provide description?")
17
- expect(answer).to eq(['First', 'Second', 'Third'])
38
+
39
+ answer = prompt.multiline("Description?") do |q|
40
+ q.default 'A super sweet prompt'
41
+ q.help '(Press thy ctrl-d to end)'
42
+ end
43
+
44
+ expect(answer).to eq([])
45
+ expect(prompt.output.string).to eq([
46
+ "Description? \e[90m(Press thy ctrl-d to end)\e[0m\n",
47
+ "\e[2K\e[1G\e[1A\e[2K\e[1G",
48
+ "Description? \e[32mA super sweet prompt\e[0m\n"
49
+ ].join)
50
+ end
51
+
52
+ it 'reads multiple lines with empty lines' do
53
+ prompt = TTY::TestPrompt.new
54
+ prompt.input << "aa\n\nbb\n\n\ncc\C-d"
55
+ prompt.input.rewind
56
+
57
+ answer = prompt.multiline("Description?")
58
+ expect(answer).to eq(["aa\n", "bb\n", "cc"])
59
+ expect(prompt.output.string).to eq([
60
+ "Description? \e[90m(Press CTRL-D or CTRL-Z to finish)\e[0m\n",
61
+ "\e[2K\e[1Ga",
62
+ "\e[2K\e[1Gaa",
63
+ "\e[2K\e[1Gaa\n",
64
+ "\e[2K\e[1G\n",
65
+ "\e[2K\e[1Gb",
66
+ "\e[2K\e[1Gbb",
67
+ "\e[2K\e[1Gbb\n",
68
+ "\e[2K\e[1G\n",
69
+ "\e[2K\e[1G\n",
70
+ "\e[2K\e[1Gc",
71
+ "\e[2K\e[1Gcc",
72
+ "\e[2K\e[1G\e[1A" * 6,
73
+ "\e[2K\e[1G",
74
+ "Description? \e[32maa ...\e[0m\n"
75
+ ].join)
18
76
  end
19
77
  end
@@ -12,6 +12,7 @@ RSpec.describe TTY::Prompt::Question, '#default' do
12
12
  expect(answer).to eq(name)
13
13
  expect(prompt.output.string).to eq([
14
14
  "What is your name? \e[90m(Anonymous)\e[0m ",
15
+ "\e[2K\e[1GWhat is your name? \e[90m(Anonymous)\e[0m \n",
15
16
  "\e[1A\e[2K\e[1G",
16
17
  "What is your name? \e[32mAnonymous\e[0m\n"
17
18
  ].join)
@@ -11,6 +11,14 @@ RSpec.describe TTY::Prompt::Question, '#echo' do
11
11
  expect(answer).to eql("password")
12
12
  expect(prompt.output.string).to eq([
13
13
  "What is your password? ",
14
+ "\e[2K\e[1GWhat is your password? p",
15
+ "\e[2K\e[1GWhat is your password? pa",
16
+ "\e[2K\e[1GWhat is your password? pas",
17
+ "\e[2K\e[1GWhat is your password? pass",
18
+ "\e[2K\e[1GWhat is your password? passw",
19
+ "\e[2K\e[1GWhat is your password? passwo",
20
+ "\e[2K\e[1GWhat is your password? passwor",
21
+ "\e[2K\e[1GWhat is your password? password",
14
22
  "\e[1A\e[2K\e[1G",
15
23
  "What is your password? \e[32mpassword\e[0m\n"
16
24
  ].join)
@@ -24,6 +24,7 @@ RSpec.describe TTY::Prompt::Question, '#in' do
24
24
  expect(answer).to eq('8')
25
25
  expect(prompt.output.string).to eq([
26
26
  "How do you like it on scale 1-10? ",
27
+ "\e[2K\e[1GHow do you like it on scale 1-10? 8",
27
28
  "\e[1A\e[2K\e[1G",
28
29
  "How do you like it on scale 1-10? \e[32m8\e[0m\n",
29
30
  ].join)
@@ -40,6 +41,9 @@ RSpec.describe TTY::Prompt::Question, '#in' do
40
41
  expect(answer).to eq('8.1')
41
42
  expect(prompt.output.string).to eq([
42
43
  "How do you like it on scale 1-10? ",
44
+ "\e[2K\e[1GHow do you like it on scale 1-10? 8",
45
+ "\e[2K\e[1GHow do you like it on scale 1-10? 8.",
46
+ "\e[2K\e[1GHow do you like it on scale 1-10? 8.1",
43
47
  "\e[1A\e[2K\e[1G",
44
48
  "How do you like it on scale 1-10? \e[32m8.1\e[0m\n",
45
49
  ].join)
@@ -56,6 +60,7 @@ RSpec.describe TTY::Prompt::Question, '#in' do
56
60
  expect(answer).to eq('E')
57
61
  expect(prompt.output.string).to eq([
58
62
  "Your favourite vitamin? (A-K) ",
63
+ "\e[2K\e[1GYour favourite vitamin? (A-K) E",
59
64
  "\e[1A\e[2K\e[1G",
60
65
  "Your favourite vitamin? (A-K) \e[32mE\e[0m\n"
61
66
  ].join)
@@ -70,9 +75,13 @@ RSpec.describe TTY::Prompt::Question, '#in' do
70
75
  expect(answer).to eq('2')
71
76
  expect(prompt.output.string).to eq([
72
77
  "How spicy on scale? (1-5) ",
78
+ "\e[2K\e[1GHow spicy on scale? (1-5) A",
79
+ "\e[2K\e[1GHow spicy on scale? (1-5) A\n",
73
80
  "\e[31m>>\e[0m Value A must be within the range 1..5\e[1A",
74
81
  "\e[2K\e[1G",
75
82
  "How spicy on scale? (1-5) ",
83
+ "\e[2K\e[1GHow spicy on scale? (1-5) 2",
84
+ "\e[2K\e[1GHow spicy on scale? (1-5) 2\n",
76
85
  "\e[2K\e[1G",
77
86
  "\e[1A\e[2K\e[1G",
78
87
  "How spicy on scale? (1-5) \e[32m2\e[0m\n"
@@ -91,9 +100,13 @@ RSpec.describe TTY::Prompt::Question, '#in' do
91
100
  expect(answer).to eq('2')
92
101
  expect(prompt.output.string).to eq([
93
102
  "How spicy on scale? (1-5) ",
103
+ "\e[2K\e[1GHow spicy on scale? (1-5) A",
104
+ "\e[2K\e[1GHow spicy on scale? (1-5) A\n",
94
105
  "\e[31m>>\e[0m Ohh dear what is this A doing in 1..5?\e[1A",
95
106
  "\e[2K\e[1G",
96
107
  "How spicy on scale? (1-5) ",
108
+ "\e[2K\e[1GHow spicy on scale? (1-5) 2",
109
+ "\e[2K\e[1GHow spicy on scale? (1-5) 2\n",
97
110
  "\e[2K\e[1G",
98
111
  "\e[1A\e[2K\e[1G",
99
112
  "How spicy on scale? (1-5) \e[32m2\e[0m\n"
@@ -10,6 +10,11 @@ RSpec.describe TTY::Prompt::Question, '#required' do
10
10
  prompt.ask('What is your name?') { |q| q.required(true) }
11
11
  expect(prompt.output.string).to eq([
12
12
  "What is your name? ",
13
+ "\e[2K\e[1GWhat is your name? P",
14
+ "\e[2K\e[1GWhat is your name? Pi",
15
+ "\e[2K\e[1GWhat is your name? Pio",
16
+ "\e[2K\e[1GWhat is your name? Piot",
17
+ "\e[2K\e[1GWhat is your name? Piotr",
13
18
  "\e[1A\e[2K\e[1G",
14
19
  "What is your name? \e[32mPiotr\e[0m\n"
15
20
  ].join)
@@ -21,9 +26,17 @@ RSpec.describe TTY::Prompt::Question, '#required' do
21
26
  prompt.ask('What is your name?', required: true)
22
27
  expect(prompt.output.string).to eq([
23
28
  "What is your name? ",
29
+ "\e[2K\e[1GWhat is your name? ",
30
+ "\e[2K\e[1GWhat is your name? ",
31
+ "\e[2K\e[1GWhat is your name? \n",
24
32
  "\e[31m>>\e[0m Value must be provided\e[1A",
25
33
  "\e[2K\e[1G",
26
34
  "What is your name? ",
35
+ "\e[2K\e[1GWhat is your name? P",
36
+ "\e[2K\e[1GWhat is your name? Pi",
37
+ "\e[2K\e[1GWhat is your name? Pio",
38
+ "\e[2K\e[1GWhat is your name? Piot",
39
+ "\e[2K\e[1GWhat is your name? Piotr",
27
40
  "\e[2K\e[1G",
28
41
  "\e[1A\e[2K\e[1G",
29
42
  "What is your name? \e[32mPiotr\e[0m\n"
@@ -38,22 +51,38 @@ RSpec.describe TTY::Prompt::Question, '#required' do
38
51
  end
39
52
 
40
53
  it "uses required in validation check" do
41
- prompt.input << " \n#{__FILE__}\ntest\n"
54
+ prompt.input << " \nexists\ntest\n"
42
55
  prompt.input.rewind
43
56
  answer = prompt.ask('File name?') do |q|
44
57
  q.required(true)
45
- q.validate { |v| !::File.exist?(v) }
58
+ q.validate { |v| !(v =~ /exists/) }
46
59
  q.messages[:required?] = 'File name must not be empty!'
47
60
  q.messages[:valid?] = 'File already exists!'
48
61
  end
62
+ expect(answer).to eq('test')
49
63
  expect(prompt.output.string).to eq([
50
64
  "File name? ",
65
+ "\e[2K\e[1GFile name? ",
66
+ "\e[2K\e[1GFile name? ",
67
+ "\e[2K\e[1GFile name? \n",
51
68
  "\e[31m>>\e[0m File name must not be empty!",
52
69
  "\e[1A\e[2K\e[1G",
53
70
  "File name? ",
71
+ "\e[2K\e[1GFile name? e",
72
+ "\e[2K\e[1GFile name? ex",
73
+ "\e[2K\e[1GFile name? exi",
74
+ "\e[2K\e[1GFile name? exis",
75
+ "\e[2K\e[1GFile name? exist",
76
+ "\e[2K\e[1GFile name? exists",
77
+ "\e[2K\e[1GFile name? exists\n",
54
78
  "\e[31m>>\e[0m File already exists!",
55
79
  "\e[1A\e[2K\e[1G",
56
80
  "File name? ",
81
+ "\e[2K\e[1GFile name? t",
82
+ "\e[2K\e[1GFile name? te",
83
+ "\e[2K\e[1GFile name? tes",
84
+ "\e[2K\e[1GFile name? test",
85
+ "\e[2K\e[1GFile name? test\n",
57
86
  "\e[2K\e[1G",
58
87
  "\e[1A\e[2K\e[1G",
59
88
  "File name? \e[32mtest\e[0m\n",
@@ -5,18 +5,21 @@ RSpec.describe TTY::Prompt::Question, '#validate' do
5
5
  subject(:prompt) { TTY::TestPrompt.new }
6
6
 
7
7
  it 'validates input with regex' do
8
- prompt.input << 'piotr.murach'
8
+ prompt.input << 'p.m'
9
9
  prompt.input.rewind
10
10
 
11
11
  answer = prompt.ask('What is your username?') do |q|
12
12
  q.validate(/^[^\.]+\.[^\.]+/)
13
13
  end
14
14
 
15
- expect(answer).to eq('piotr.murach')
15
+ expect(answer).to eq('p.m')
16
16
  expect(prompt.output.string).to eq([
17
17
  "What is your username? ",
18
+ "\e[2K\e[1GWhat is your username? p",
19
+ "\e[2K\e[1GWhat is your username? p.",
20
+ "\e[2K\e[1GWhat is your username? p.m",
18
21
  "\e[1A\e[2K\e[1G",
19
- "What is your username? \e[32mpiotr.murach\e[0m\n"
22
+ "What is your username? \e[32mp.m\e[0m\n"
20
23
  ].join)
21
24
  end
22
25
 
@@ -43,27 +46,41 @@ RSpec.describe TTY::Prompt::Question, '#validate' do
43
46
  end
44
47
 
45
48
  it "provides default error message for wrong input" do
46
- prompt.input << "invalid\npiotr@example.com"
49
+ prompt.input << "wrong\np@m.com\n"
47
50
  prompt.input.rewind
48
51
 
49
52
  answer = prompt.ask('What is your email?') do |q|
50
53
  q.validate :email
51
54
  end
52
55
 
53
- expect(answer).to eq('piotr@example.com')
56
+ expect(answer).to eq('p@m.com')
54
57
  expect(prompt.output.string).to eq([
55
58
  "What is your email? ",
59
+ "\e[2K\e[1GWhat is your email? w",
60
+ "\e[2K\e[1GWhat is your email? wr",
61
+ "\e[2K\e[1GWhat is your email? wro",
62
+ "\e[2K\e[1GWhat is your email? wron",
63
+ "\e[2K\e[1GWhat is your email? wrong",
64
+ "\e[2K\e[1GWhat is your email? wrong\n",
56
65
  "\e[31m>>\e[0m Your answer is invalid (must match :email)\e[1A",
57
66
  "\e[2K\e[1G",
58
67
  "What is your email? ",
68
+ "\e[2K\e[1GWhat is your email? p",
69
+ "\e[2K\e[1GWhat is your email? p@",
70
+ "\e[2K\e[1GWhat is your email? p@m",
71
+ "\e[2K\e[1GWhat is your email? p@m.",
72
+ "\e[2K\e[1GWhat is your email? p@m.c",
73
+ "\e[2K\e[1GWhat is your email? p@m.co",
74
+ "\e[2K\e[1GWhat is your email? p@m.com",
75
+ "\e[2K\e[1GWhat is your email? p@m.com\n",
59
76
  "\e[2K\e[1G",
60
77
  "\e[1A\e[2K\e[1G",
61
- "What is your email? \e[32mpiotr@example.com\e[0m\n"
78
+ "What is your email? \e[32mp@m.com\e[0m\n"
62
79
  ].join)
63
80
  end
64
81
 
65
82
  it "provides custom error message for wrong input" do
66
- prompt.input << "invalid\npiotr@example.com"
83
+ prompt.input << "wrong\np@m.com"
67
84
  prompt.input.rewind
68
85
 
69
86
  answer = prompt.ask('What is your email?') do |q|
@@ -71,15 +88,28 @@ RSpec.describe TTY::Prompt::Question, '#validate' do
71
88
  q.messages[:valid?] = 'Not an email!'
72
89
  end
73
90
 
74
- expect(answer).to eq('piotr@example.com')
91
+ expect(answer).to eq('p@m.com')
75
92
  expect(prompt.output.string).to eq([
76
93
  "What is your email? ",
94
+ "\e[2K\e[1GWhat is your email? w",
95
+ "\e[2K\e[1GWhat is your email? wr",
96
+ "\e[2K\e[1GWhat is your email? wro",
97
+ "\e[2K\e[1GWhat is your email? wron",
98
+ "\e[2K\e[1GWhat is your email? wrong",
99
+ "\e[2K\e[1GWhat is your email? wrong\n",
77
100
  "\e[31m>>\e[0m Not an email!\e[1A",
78
101
  "\e[2K\e[1G",
79
102
  "What is your email? ",
103
+ "\e[2K\e[1GWhat is your email? p",
104
+ "\e[2K\e[1GWhat is your email? p@",
105
+ "\e[2K\e[1GWhat is your email? p@m",
106
+ "\e[2K\e[1GWhat is your email? p@m.",
107
+ "\e[2K\e[1GWhat is your email? p@m.c",
108
+ "\e[2K\e[1GWhat is your email? p@m.co",
109
+ "\e[2K\e[1GWhat is your email? p@m.com",
80
110
  "\e[2K\e[1G",
81
111
  "\e[1A\e[2K\e[1G",
82
- "What is your email? \e[32mpiotr@example.com\e[0m\n"
112
+ "What is your email? \e[32mp@m.com\e[0m\n"
83
113
  ].join)
84
114
  end
85
115
  end