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