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,110 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Reader::Line do
4
- it "inserts characters in line" do
5
- line = described_class.new('aaaaa')
6
- line[0] = 'test'
7
- expect(line.text).to eq('testaaaaa')
8
- line[4..6] = ''
9
- expect(line.text).to eq('testaa')
10
- end
11
-
12
- it "moves cursor left and right" do
13
- line = described_class.new('aaaaa')
14
- 5.times { line.left }
15
- expect(line.cursor).to eq(0)
16
- expect(line.start?).to eq(true)
17
- line.left(5)
18
- expect(line.cursor).to eq(0)
19
- line.right(20)
20
- expect(line.cursor).to eq(5)
21
- expect(line.end?).to eq(true)
22
- end
23
-
24
- it "inserts char at start of the line" do
25
- line = described_class.new('aaaaa')
26
- expect(line.cursor).to eq(5)
27
- line[0] = 'b'
28
- expect(line.cursor).to eq(1)
29
- expect(line.text).to eq('baaaaa')
30
- line.insert('b')
31
- expect(line.text).to eq('bbaaaaa')
32
- end
33
-
34
- it "inserts char at end of the line" do
35
- line = described_class.new('aaaaa')
36
- expect(line.cursor).to eq(5)
37
- line[4] = 'b'
38
- expect(line.cursor).to eq(5)
39
- expect(line.text).to eq('aaaaab')
40
- end
41
-
42
- it "inserts char inside the line" do
43
- line = described_class.new('aaaaa')
44
- expect(line.cursor).to eq(5)
45
- line[2] = 'b'
46
- expect(line.cursor).to eq(3)
47
- expect(line.text).to eq('aabaaa')
48
- end
49
-
50
- it "inserts char outside of the line size" do
51
- line = described_class.new('aaaaa')
52
- expect(line.cursor).to eq(5)
53
- line[10] = 'b'
54
- expect(line.cursor).to eq(11)
55
- expect(line.text).to eq('aaaaa b')
56
- end
57
-
58
- it "inserts chars on empty string" do
59
- line = described_class.new('')
60
- expect(line.cursor).to eq(0)
61
- line.insert('a')
62
- expect(line.cursor).to eq(1)
63
- line.insert('b')
64
- expect(line.cursor).to eq(2)
65
- expect(line.to_s).to eq('ab')
66
- line.insert('cc')
67
- expect(line.cursor).to eq(4)
68
- expect(line.to_s).to eq('abcc')
69
- end
70
-
71
- it "inserts characters with #insert call" do
72
- line = described_class.new('aaaaa')
73
- line.left(2)
74
- expect(line.cursor).to eq(3)
75
- line.insert(' test ')
76
- expect(line.text).to eq('aaa test aa')
77
- expect(line.cursor).to eq(9)
78
- line.right
79
- expect(line.cursor).to eq(10)
80
- end
81
-
82
- it "removes char before current cursor position" do
83
- line = described_class.new('abcdef')
84
- expect(line.cursor).to eq(6)
85
- line.remove
86
- line.remove
87
- expect(line.text).to eq('abcd')
88
- expect(line.cursor).to eq(4)
89
- line.left
90
- line.left
91
- line.remove
92
- expect(line.text).to eq('acd')
93
- expect(line.cursor).to eq(1)
94
- line.insert('x')
95
- expect(line.text).to eq('axcd')
96
- end
97
-
98
- it "deletes char under current cursor position" do
99
- line = described_class.new('abcdef')
100
- line.left(3)
101
- line.delete
102
- expect(line.text).to eq('abcef')
103
- line.right
104
- line.delete
105
- expect(line.text).to eq('abce')
106
- line.left(4)
107
- line.delete
108
- expect(line.text).to eq('bce')
109
- end
110
- end
@@ -1,94 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Reader, '#publish_keypress_event' do
4
- let(:input) { StringIO.new }
5
- let(:out) { StringIO.new }
6
- let(:env) { { "TTY_TEST" => true } }
7
-
8
- let(:reader) { described_class.new(input, out, env: env) }
9
-
10
- it "publishes :keypress events" do
11
- input << "abc\n"
12
- input.rewind
13
- chars = []
14
- reader.on(:keypress) { |event| chars << event.value }
15
- answer = reader.read_line
16
- expect(chars).to eq(%W(a b c \n))
17
- expect(answer).to eq("abc\n")
18
- end
19
-
20
- it "publishes :keyup for read_keypress" do
21
- input << "\e[Aaa"
22
- input.rewind
23
- keys = []
24
- reader.on(:keypress) { |event| keys << "keypress_#{event.value}" }
25
- reader.on(:keyup) { |event| keys << "keyup_#{event.value}" }
26
- reader.on(:keydown) { |event| keys << "keydown_#{event.value}" }
27
-
28
- answer = reader.read_keypress
29
- expect(keys).to eq(["keyup_\e[A", "keypress_\e[A"])
30
- expect(answer).to eq("\e[A")
31
- end
32
-
33
- it "publishes :keydown event for read_keypress" do
34
- input << "\e[Baa"
35
- input.rewind
36
- keys = []
37
- reader.on(:keypress) { |event| keys << "keypress_#{event.value}" }
38
- reader.on(:keyup) { |event| keys << "keyup_#{event.value}" }
39
- reader.on(:keydown) { |event| keys << "keydown_#{event.value}" }
40
-
41
- answer = reader.read_keypress
42
- expect(keys).to eq(["keydown_\e[B", "keypress_\e[B"])
43
- expect(answer).to eq("\e[B")
44
- end
45
-
46
- it "publishes :keynum event" do
47
- input << "5aa"
48
- input.rewind
49
- keys = []
50
- reader.on(:keypress) { |event| keys << "keypress_#{event.value}" }
51
- reader.on(:keyup) { |event| keys << "keyup_#{event.value}" }
52
- reader.on(:keynum) { |event| keys << "keynum_#{event.value}" }
53
-
54
- answer = reader.read_keypress
55
- expect(keys).to eq(["keynum_5", "keypress_5"])
56
- expect(answer).to eq("5")
57
- end
58
-
59
- it "publishes :keyreturn event" do
60
- input << "\r"
61
- input.rewind
62
- keys = []
63
- reader.on(:keypress) { |event| keys << "keypress" }
64
- reader.on(:keyup) { |event| keys << "keyup" }
65
- reader.on(:keyreturn) { |event| keys << "keyreturn" }
66
-
67
- answer = reader.read_keypress
68
- expect(keys).to eq(["keyreturn", "keypress"])
69
- expect(answer).to eq("\r")
70
- end
71
-
72
- it "subscribes to multiple events" do
73
- input << "\n"
74
- input.rewind
75
- keys = []
76
- reader.on(:keyenter) { |event| keys << "keyenter" }
77
- .on(:keypress) { |event| keys << "keypress" }
78
-
79
- answer = reader.read_keypress
80
- expect(keys).to eq(["keyenter", "keypress"])
81
- expect(answer).to eq("\n")
82
- end
83
-
84
- it "subscribes to ctrl+X type of event event" do
85
- input << ?\C-z
86
- input.rewind
87
- keys = []
88
- reader.on(:keyctrl_z) { |event| keys << "ctrl_z" }
89
-
90
- answer = reader.read_keypress
91
- expect(keys).to eq(['ctrl_z'])
92
- expect(answer).to eq(?\C-z)
93
- end
94
- end
@@ -1,80 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Reader, '#read_keypress' do
4
- let(:input) { StringIO.new }
5
- let(:out) { StringIO.new }
6
- let(:env) { { "TTY_TEST" => true } }
7
-
8
- it "reads single key press" do
9
- reader = described_class.new(input, out, env: env)
10
- input << "\e[Aaaaaaa\n"
11
- input.rewind
12
-
13
- answer = reader.read_keypress
14
-
15
- expect(answer).to eq("\e[A")
16
- end
17
-
18
- it 'reads multibyte key press' do
19
- reader = described_class.new(input, out, env: env)
20
- input << "ㄱ"
21
- input.rewind
22
-
23
- answer = reader.read_keypress
24
-
25
- expect(answer).to eq("ㄱ")
26
- end
27
-
28
- context 'when Ctrl+C pressed' do
29
- it "defaults to raising InputInterrupt" do
30
- reader = described_class.new(input, out, env: env)
31
- input << "\x03"
32
- input.rewind
33
-
34
- expect {
35
- reader.read_keypress
36
- }.to raise_error(TTY::Prompt::Reader::InputInterrupt)
37
- end
38
-
39
- it "sends interrupt signal when :signal option is chosen" do
40
- reader = described_class.new(input, out, interrupt: :signal, env: env)
41
- input << "\x03"
42
- input.rewind
43
-
44
- allow(Process).to receive(:pid).and_return(666)
45
- allow(Process).to receive(:kill)
46
- expect(Process).to receive(:kill).with('SIGINT', 666)
47
-
48
- reader.read_keypress
49
- end
50
-
51
- it "exits with 130 code when :exit option is chosen" do
52
- reader = described_class.new(input, out, interrupt: :exit, env: env)
53
- input << "\x03"
54
- input.rewind
55
-
56
- expect {
57
- reader.read_keypress
58
- }.to raise_error(SystemExit)
59
- end
60
-
61
- it "evaluates custom handler when proc object is provided" do
62
- handler = proc { raise ArgumentError }
63
- reader = described_class.new(input, out, interrupt: handler, env: env)
64
- input << "\x03"
65
- input.rewind
66
-
67
- expect {
68
- reader.read_keypress
69
- }.to raise_error(ArgumentError)
70
- end
71
-
72
- it "skips handler when handler is nil" do
73
- reader = described_class.new(input, out, interrupt: :noop, env: env)
74
- input << "\x03"
75
- input.rewind
76
-
77
- expect(reader.read_keypress).to eq("\x03")
78
- end
79
- end
80
- end
@@ -1,68 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Reader, '#read_line' do
4
- let(:input) { StringIO.new }
5
- let(:output) { StringIO.new }
6
- let(:env) { { "TTY_TEST" => true } }
7
-
8
- subject(:reader) { described_class.new(input, output, env: env) }
9
-
10
- it 'masks characters' do
11
- input << "password\n"
12
- input.rewind
13
- answer = reader.read_line(echo: false)
14
- expect(answer).to eq("password\n")
15
- end
16
-
17
- it "echoes characters back" do
18
- input << "password\n"
19
- input.rewind
20
- answer = reader.read_line
21
- expect(answer).to eq("password\n")
22
- expect(output.string).to eq([
23
- "\e[2K\e[1Gp",
24
- "\e[2K\e[1Gpa",
25
- "\e[2K\e[1Gpas",
26
- "\e[2K\e[1Gpass",
27
- "\e[2K\e[1Gpassw",
28
- "\e[2K\e[1Gpasswo",
29
- "\e[2K\e[1Gpasswor",
30
- "\e[2K\e[1Gpassword",
31
- "\e[2K\e[1Gpassword\n"
32
- ].join)
33
- end
34
-
35
- it "doesn't echo characters back" do
36
- input << "password\n"
37
- input.rewind
38
- answer = reader.read_line(echo: false)
39
- expect(answer).to eq("password\n")
40
- expect(output.string).to eq('')
41
- end
42
-
43
- it "displays a prompt before input" do
44
- input << "aa\n"
45
- input.rewind
46
- answer = reader.read_line('>> ')
47
- expect(answer).to eq("aa\n")
48
- expect(output.string).to eq([
49
- "\e[2K\e[1G>> a",
50
- "\e[2K\e[1G>> aa",
51
- "\e[2K\e[1G>> aa\n"
52
- ].join)
53
- end
54
-
55
- xit 'deletes characters when backspace pressed' do
56
- input << "aa\ba\bcc\n"
57
- input.rewind
58
- answer = reader.read_line
59
- expect(answer).to eq("acc\n")
60
- end
61
-
62
- it 'reads multibyte line' do
63
- input << "한글"
64
- input.rewind
65
- answer = reader.read_line
66
- expect(answer).to eq("한글")
67
- end
68
- end
@@ -1,60 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Reader, '#read_multiline' do
4
- let(:input) { StringIO.new }
5
- let(:output) { StringIO.new }
6
- let(:env) { { "TTY_TEST" => true } }
7
-
8
- subject(:reader) { described_class.new(input, output, env: env) }
9
-
10
- it 'reads no lines' do
11
- input << "\C-d"
12
- input.rewind
13
- answer = reader.read_multiline
14
- expect(answer).to eq([])
15
- end
16
-
17
- it "reads a line and terminates on Ctrl+d" do
18
- input << "Single line\C-d"
19
- input.rewind
20
- answer = reader.read_multiline
21
- expect(answer).to eq(["Single line"])
22
- end
23
-
24
- it "reads a line and terminates on Ctrl+z" do
25
- input << "Single line\C-z"
26
- input.rewind
27
- answer = reader.read_multiline
28
- expect(answer).to eq(["Single line"])
29
- end
30
-
31
- it 'reads few lines' do
32
- input << "First line\nSecond line\nThird line\n\C-d"
33
- input.rewind
34
- answer = reader.read_multiline
35
- expect(answer).to eq(["First line\n", "Second line\n", "Third line\n"])
36
- end
37
-
38
- it "skips empty lines" do
39
- input << "\n\nFirst line\n\n\n\n\nSecond line\C-d"
40
- input.rewind
41
- answer = reader.read_multiline
42
- expect(answer).to eq(["First line\n", "Second line"])
43
- end
44
-
45
- it 'reads and yiels every line' do
46
- input << "First line\nSecond line\nThird line\C-z"
47
- input.rewind
48
- lines = []
49
- reader.read_multiline { |line| lines << line }
50
- expect(lines).to eq(["First line\n", "Second line\n", "Third line"])
51
- end
52
-
53
- it 'reads multibyte lines' do
54
- input << "국경의 긴 터널을 빠져나오자\n설국이었다.\C-d"
55
- input.rewind
56
- lines = []
57
- reader.read_multiline { |line| lines << line }
58
- expect(lines).to eq(["국경의 긴 터널을 빠져나오자\n", '설국이었다.'])
59
- end
60
- end
@@ -1,40 +0,0 @@
1
- # encoding: utf-8
2
-
3
- RSpec.describe TTY::Prompt::Result do
4
- it "checks value to be invalid" do
5
- question = double(:question)
6
- result = TTY::Prompt::Result.new(question, nil)
7
-
8
- answer = result.with { |quest, value|
9
- if value.nil?
10
- [value, ["`#{value}` provided cannot be empty"]]
11
- else
12
- value
13
- end
14
- }
15
- expect(answer).to be_a(TTY::Prompt::Result::Failure)
16
- expect(answer.success?).to eq(false)
17
- expect(answer.errors).to eq(["`` provided cannot be empty"])
18
- end
19
-
20
- it "checks value to be valid" do
21
- question = double(:question)
22
- result = TTY::Prompt::Result.new(question, 'Piotr')
23
-
24
- CheckRequired = Class.new do
25
- def self.call(quest, value)
26
- if value.nil?
27
- [value, ["`#{value}` provided cannot be empty"]]
28
- else
29
- value
30
- end
31
- end
32
- end
33
-
34
- answer = result.with(CheckRequired)
35
- expect(answer).to be_a(TTY::Prompt::Result::Success)
36
- expect(answer.success?).to eq(true)
37
- expect(answer.value).to eq('Piotr')
38
- expect(answer.errors).to eq([])
39
- end
40
- end