tty-prompt 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/CHANGELOG.md +15 -0
- data/Gemfile +2 -2
- data/README.md +185 -25
- data/examples/enum.rb +8 -0
- data/examples/enum_select.rb +7 -0
- data/examples/in.rb +3 -1
- data/examples/slider.rb +6 -0
- data/lib/tty-prompt.rb +8 -2
- data/lib/tty/prompt.rb +63 -13
- data/lib/tty/prompt/converters.rb +12 -6
- data/lib/tty/prompt/enum_list.rb +222 -0
- data/lib/tty/prompt/list.rb +48 -15
- data/lib/tty/prompt/multi_list.rb +11 -11
- data/lib/tty/prompt/question.rb +38 -14
- data/lib/tty/prompt/question/checks.rb +5 -3
- data/lib/tty/prompt/reader.rb +12 -18
- data/lib/tty/prompt/reader/codes.rb +15 -9
- data/lib/tty/prompt/reader/key_event.rb +51 -24
- data/lib/tty/prompt/slider.rb +170 -0
- data/lib/tty/prompt/symbols.rb +7 -1
- data/lib/tty/prompt/utils.rb +31 -3
- data/lib/tty/prompt/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/converters/convert_bool_spec.rb +1 -1
- data/spec/unit/converters/convert_date_spec.rb +11 -2
- data/spec/unit/converters/convert_file_spec.rb +1 -1
- data/spec/unit/converters/convert_number_spec.rb +19 -2
- data/spec/unit/converters/convert_path_spec.rb +1 -1
- data/spec/unit/converters/convert_range_spec.rb +4 -3
- data/spec/unit/enum_select_spec.rb +93 -0
- data/spec/unit/multi_select_spec.rb +14 -12
- data/spec/unit/question/checks_spec.rb +97 -0
- data/spec/unit/reader/key_event_spec.rb +67 -0
- data/spec/unit/select_spec.rb +15 -16
- data/spec/unit/slider_spec.rb +54 -0
- data/tty-prompt.gemspec +2 -1
- metadata +31 -5
- data/.ruby-version +0 -1
data/lib/tty/prompt/symbols.rb
CHANGED
@@ -3,11 +3,17 @@
|
|
3
3
|
module TTY
|
4
4
|
class Prompt
|
5
5
|
module Symbols
|
6
|
-
SPACE
|
6
|
+
SPACE = " "
|
7
|
+
SUCCESS = "✓"
|
8
|
+
FAILURE = "✘"
|
9
|
+
|
7
10
|
ITEM_SECURE = "•"
|
8
11
|
ITEM_SELECTED = "‣"
|
9
12
|
RADIO_CHECKED = "⬢"
|
10
13
|
RADIO_UNCHECKED = "⬡"
|
14
|
+
SLIDER_HANDLE = 'O'
|
15
|
+
SLIDER_RANGE = '-'
|
16
|
+
SLIDER_END = '|'
|
11
17
|
end # Symbols
|
12
18
|
end # Prompt
|
13
19
|
end # TTY
|
data/lib/tty/prompt/utils.rb
CHANGED
@@ -4,13 +4,41 @@ module TTY
|
|
4
4
|
module Utils
|
5
5
|
module_function
|
6
6
|
|
7
|
-
|
8
|
-
args.last.respond_to?(:to_hash) ? args.pop : {}
|
9
|
-
end
|
7
|
+
BLANK_REGEX = /\A[[:space:]]*\z/o.freeze
|
10
8
|
|
9
|
+
# Extract options hash from array argument
|
10
|
+
#
|
11
|
+
# @param [Array[Object]] args
|
12
|
+
#
|
13
|
+
# @api public
|
11
14
|
def extract_options(args)
|
12
15
|
options = args.last
|
13
16
|
options.respond_to?(:to_hash) ? options.to_hash.dup : {}
|
14
17
|
end
|
18
|
+
|
19
|
+
def extract_options!(args)
|
20
|
+
args.last.respond_to?(:to_hash) ? args.pop : {}
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check if value is nil or an empty string
|
24
|
+
#
|
25
|
+
# @param [Object] value
|
26
|
+
# the value to check
|
27
|
+
#
|
28
|
+
# @return [Boolean]
|
29
|
+
#
|
30
|
+
# @api public
|
31
|
+
def blank?(value)
|
32
|
+
value.nil? ||
|
33
|
+
value.respond_to?(:empty?) && value.empty? ||
|
34
|
+
BLANK_REGEX === value
|
35
|
+
end
|
36
|
+
|
37
|
+
# Deep copy object
|
38
|
+
#
|
39
|
+
# @api public
|
40
|
+
def deep_copy(object)
|
41
|
+
Marshal.load(Marshal.dump(object))
|
42
|
+
end
|
15
43
|
end # Utils
|
16
44
|
end # TTY
|
data/lib/tty/prompt/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,7 @@ RSpec.describe TTY::Prompt::Question, 'convert bool' do
|
|
9
9
|
prompt.input.rewind
|
10
10
|
expect {
|
11
11
|
prompt.ask("Do you read books?", convert: :bool)
|
12
|
-
}.to raise_error(
|
12
|
+
}.to raise_error(TTY::Prompt::ConversionError)
|
13
13
|
end
|
14
14
|
|
15
15
|
it "handles default values" do
|
@@ -1,8 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
RSpec.describe TTY::Prompt::Question, 'convert date' do
|
4
|
+
|
5
|
+
subject(:prompt) { TTY::TestPrompt.new}
|
6
|
+
|
7
|
+
it 'fails to convert date' do
|
8
|
+
prompt.input << 'invalid'
|
9
|
+
prompt.input.rewind
|
10
|
+
expect {
|
11
|
+
prompt.ask("When were you born?", convert: :date)
|
12
|
+
}.to raise_error(TTY::Prompt::ConversionError)
|
13
|
+
end
|
14
|
+
|
4
15
|
it 'converts date' do
|
5
|
-
prompt = TTY::TestPrompt.new
|
6
16
|
prompt.input << "20th April 1887"
|
7
17
|
prompt.input.rewind
|
8
18
|
response = prompt.ask("When were your born?", convert: :date)
|
@@ -13,7 +23,6 @@ RSpec.describe TTY::Prompt::Question, 'convert date' do
|
|
13
23
|
end
|
14
24
|
|
15
25
|
it "converts datetime" do
|
16
|
-
prompt = TTY::TestPrompt.new
|
17
26
|
prompt.input << "20th April 1887"
|
18
27
|
prompt.input.rewind
|
19
28
|
response = prompt.ask("When were your born?", convert: :datetime)
|
@@ -9,6 +9,6 @@ RSpec.describe TTY::Prompt::Question, 'convert file' do
|
|
9
9
|
prompt.input.rewind
|
10
10
|
answer = prompt.ask("Which file to open?", convert: :file)
|
11
11
|
expect(answer).to eq(file)
|
12
|
-
|
12
|
+
expect(File).to have_received(:open).with(/test\.txt/)
|
13
13
|
end
|
14
14
|
end
|
@@ -1,8 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
RSpec.describe TTY::Prompt::Question, 'convert numbers' do
|
4
|
+
|
5
|
+
subject(:prompt) { TTY::TestPrompt.new }
|
6
|
+
|
7
|
+
it 'fails to convert integer' do
|
8
|
+
prompt.input << 'invalid'
|
9
|
+
prompt.input.rewind
|
10
|
+
expect {
|
11
|
+
prompt.ask("What temparture?", convert: :int)
|
12
|
+
}.to raise_error(TTY::Prompt::ConversionError)
|
13
|
+
end
|
14
|
+
|
4
15
|
it 'converts integer' do
|
5
|
-
prompt = TTY::TestPrompt.new
|
6
16
|
prompt.input << 35
|
7
17
|
prompt.input.rewind
|
8
18
|
answer = prompt.ask("What temperature?", convert: :int)
|
@@ -10,8 +20,15 @@ RSpec.describe TTY::Prompt::Question, 'convert numbers' do
|
|
10
20
|
expect(answer).to eq(35)
|
11
21
|
end
|
12
22
|
|
23
|
+
it 'fails to convert float' do
|
24
|
+
prompt.input << 'invalid'
|
25
|
+
prompt.input.rewind
|
26
|
+
expect {
|
27
|
+
prompt.ask("How tall are you?", convert: :float)
|
28
|
+
}.to raise_error(TTY::Prompt::ConversionError)
|
29
|
+
end
|
30
|
+
|
13
31
|
it 'converts float' do
|
14
|
-
prompt = TTY::TestPrompt.new
|
15
32
|
number = 6.666
|
16
33
|
prompt.input << number
|
17
34
|
prompt.input.rewind
|
@@ -9,7 +9,7 @@ RSpec.describe TTY::Prompt::Question, 'convert path' do
|
|
9
9
|
prompt.input << "/path/to/file"
|
10
10
|
prompt.input.rewind
|
11
11
|
answer = prompt.ask('File location?', convert: :path)
|
12
|
-
# expect(Pathname).to have_received(:new).with(/path\/to\/file/)
|
13
12
|
expect(answer).to eql(path)
|
13
|
+
expect(Pathname).to have_received(:new).with(/path\/to\/file/)
|
14
14
|
end
|
15
15
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
RSpec.describe TTY::Prompt::Question, 'convert range' do
|
4
|
+
|
5
|
+
subject(:prompt) { TTY::TestPrompt.new}
|
6
|
+
|
4
7
|
it 'converts with valid range' do
|
5
|
-
prompt = TTY::TestPrompt.new
|
6
8
|
prompt.input << "20-30"
|
7
9
|
prompt.input.rewind
|
8
10
|
answer = prompt.ask("Which age group?", convert: :range)
|
@@ -11,11 +13,10 @@ RSpec.describe TTY::Prompt::Question, 'convert range' do
|
|
11
13
|
end
|
12
14
|
|
13
15
|
it "fails to convert to range" do
|
14
|
-
prompt = TTY::TestPrompt.new
|
15
16
|
prompt.input << "abcd"
|
16
17
|
prompt.input.rewind
|
17
18
|
expect {
|
18
19
|
prompt.ask('Which age group?', convert: :range)
|
19
|
-
}.to raise_error(
|
20
|
+
}.to raise_error(TTY::Prompt::ConversionError)
|
20
21
|
end
|
21
22
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Prompt do
|
4
|
+
|
5
|
+
subject(:prompt) { TTY::TestPrompt.new }
|
6
|
+
|
7
|
+
it "selects default option when return pressed immediately" do
|
8
|
+
choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
|
9
|
+
prompt.input << "\n"
|
10
|
+
prompt.input.rewind
|
11
|
+
|
12
|
+
expect(prompt.enum_select("Select an editor?", choices)).to eq('/bin/nano')
|
13
|
+
expect(prompt.output.string).to eq([
|
14
|
+
"Select an editor? \n",
|
15
|
+
"\e[32m 1) /bin/nano\e[0m\n",
|
16
|
+
" 2) /usr/bin/vim.basic\n",
|
17
|
+
" 3) /usr/bin/vim.tiny\n",
|
18
|
+
" Choose 1-3 [1]: ",
|
19
|
+
"\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[J",
|
20
|
+
"Select an editor? \e[32m/bin/nano\e[0m\n"
|
21
|
+
].join)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "selects option by index from the list" do
|
25
|
+
choices = %w(/bin/nano /usr/bin/vim.basic /usr/bin/vim.tiny)
|
26
|
+
prompt.input << "3\n"
|
27
|
+
prompt.input.rewind
|
28
|
+
|
29
|
+
expect(prompt.enum_select("Select an editor?", choices, default: 2)).to eq('/usr/bin/vim.tiny')
|
30
|
+
expect(prompt.output.string).to eq([
|
31
|
+
"Select an editor? \n",
|
32
|
+
" 1) /bin/nano\n",
|
33
|
+
"\e[32m 2) /usr/bin/vim.basic\e[0m\n",
|
34
|
+
" 3) /usr/bin/vim.tiny\n",
|
35
|
+
" Choose 1-3 [2]: ",
|
36
|
+
"\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[J",
|
37
|
+
"Select an editor? \n",
|
38
|
+
" 1) /bin/nano\n",
|
39
|
+
" 2) /usr/bin/vim.basic\n",
|
40
|
+
"\e[32m 3) /usr/bin/vim.tiny\e[0m\n",
|
41
|
+
" Choose 1-3 [2]: 3",
|
42
|
+
"\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[J",
|
43
|
+
"Select an editor? \e[32m/usr/bin/vim.tiny\e[0m\n"
|
44
|
+
].join)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "selects option through DSL" do
|
48
|
+
prompt.input << "\n"
|
49
|
+
prompt.input.rewind
|
50
|
+
value = prompt.enum_select("Select an editor?") do |menu|
|
51
|
+
menu.default 2
|
52
|
+
menu.enum '.'
|
53
|
+
|
54
|
+
menu.choice "/bin/nano"
|
55
|
+
menu.choice "/usr/bin/vim.basic"
|
56
|
+
menu.choice "/usr/bin/vim.tiny"
|
57
|
+
end
|
58
|
+
|
59
|
+
expect(value).to eq('/usr/bin/vim.basic')
|
60
|
+
expect(prompt.output.string).to eq([
|
61
|
+
"Select an editor? \n",
|
62
|
+
" 1. /bin/nano\n",
|
63
|
+
"\e[32m 2. /usr/bin/vim.basic\e[0m\n",
|
64
|
+
" 3. /usr/bin/vim.tiny\n",
|
65
|
+
" Choose 1-3 [2]: ",
|
66
|
+
"\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[J",
|
67
|
+
"Select an editor? \e[32m/usr/bin/vim.basic\e[0m\n"
|
68
|
+
].join)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "selects option through DSL with key and value" do
|
72
|
+
prompt.input << "\n"
|
73
|
+
prompt.input.rewind
|
74
|
+
value = prompt.enum_select("Select an editor?") do |menu|
|
75
|
+
menu.default 2
|
76
|
+
|
77
|
+
menu.choice :nano, '/bin/nano'
|
78
|
+
menu.choice :vim, '/usr/bin/vim'
|
79
|
+
menu.choice :emacs, '/usr/bin/emacs'
|
80
|
+
end
|
81
|
+
|
82
|
+
expect(value).to eq('/usr/bin/vim')
|
83
|
+
expect(prompt.output.string).to eq([
|
84
|
+
"Select an editor? \n",
|
85
|
+
" 1) nano\n",
|
86
|
+
"\e[32m 2) vim\e[0m\n",
|
87
|
+
" 3) emacs\n",
|
88
|
+
" Choose 1-3 [2]: ",
|
89
|
+
"\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[1A\e[1000D\e[K\e[J",
|
90
|
+
"Select an editor? \e[32mvim\e[0m\n"
|
91
|
+
].join)
|
92
|
+
end
|
93
|
+
end
|
@@ -74,6 +74,8 @@ RSpec.describe TTY::Prompt do
|
|
74
74
|
prompt.input << " \r"
|
75
75
|
prompt.input.rewind
|
76
76
|
value = prompt.multi_select("Select drinks?") do |menu|
|
77
|
+
menu.enum ')'
|
78
|
+
|
77
79
|
menu.choice :vodka, {score: 1}
|
78
80
|
menu.choice :beer, 2
|
79
81
|
menu.choice :wine, 3
|
@@ -81,19 +83,19 @@ RSpec.describe TTY::Prompt do
|
|
81
83
|
end
|
82
84
|
expect(value).to eq([{score: 1}])
|
83
85
|
expect(prompt.output.string).to eq([
|
84
|
-
"\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
|
85
|
-
"‣ ⬡ vodka\n",
|
86
|
-
" ⬡ beer\n",
|
87
|
-
" ⬡ wine\n",
|
88
|
-
" ⬡ whisky\n",
|
89
|
-
" ⬡ bourbon",
|
86
|
+
"\e[?25lSelect drinks? \e[90m(Use arrow or number (0-9) keys, press Space to select and Enter to finish)\e[0m\n",
|
87
|
+
"‣ ⬡ 1) vodka\n",
|
88
|
+
" ⬡ 2) beer\n",
|
89
|
+
" ⬡ 3) wine\n",
|
90
|
+
" ⬡ 4) whisky\n",
|
91
|
+
" ⬡ 5) bourbon",
|
90
92
|
"\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
|
91
93
|
"Select drinks? vodka\n",
|
92
|
-
"‣ \e[32m⬢\e[0m vodka\n",
|
93
|
-
" ⬡ beer\n",
|
94
|
-
" ⬡ wine\n",
|
95
|
-
" ⬡ whisky\n",
|
96
|
-
" ⬡ bourbon",
|
94
|
+
"‣ \e[32m⬢\e[0m 1) vodka\n",
|
95
|
+
" ⬡ 2) beer\n",
|
96
|
+
" ⬡ 3) wine\n",
|
97
|
+
" ⬡ 4) whisky\n",
|
98
|
+
" ⬡ 5) bourbon",
|
97
99
|
"\e[1000D\e[K\e[1A" * 5, "\e[1000D\e[K",
|
98
100
|
"Select drinks? \e[32mvodka\e[0m\n\e[?25h"
|
99
101
|
].join)
|
@@ -151,7 +153,7 @@ RSpec.describe TTY::Prompt do
|
|
151
153
|
menu.choice :whisky, {score: 40}
|
152
154
|
menu.choice :bourbon, {score: 50}
|
153
155
|
end
|
154
|
-
}.to raise_error(TTY::
|
156
|
+
}.to raise_error(TTY::Prompt::ConfigurationError,
|
155
157
|
/default index `6` out of range \(1 - 5\)/)
|
156
158
|
end
|
157
159
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
RSpec.describe TTY::Prompt::Question do
|
4
|
+
|
5
|
+
subject(:prompt) { TTY::TestPrompt.new }
|
6
|
+
|
7
|
+
it "passes range check" do
|
8
|
+
question = described_class.new(prompt)
|
9
|
+
question.in 1..10
|
10
|
+
|
11
|
+
result = TTY::Prompt::Question::Checks::CheckRange.call(question, 2)
|
12
|
+
|
13
|
+
expect(result).to eq([2])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "fails range check" do
|
17
|
+
question = described_class.new(prompt, messages: TTY::Prompt.messages)
|
18
|
+
question.in 1..10
|
19
|
+
|
20
|
+
result = TTY::Prompt::Question::Checks::CheckRange.call(question, 11)
|
21
|
+
|
22
|
+
expect(result).to eq([11, ["Value 11 must be within the range 1..10"]])
|
23
|
+
end
|
24
|
+
|
25
|
+
it "fails range check" do
|
26
|
+
question = described_class.new(prompt)
|
27
|
+
question.in 1..10, 'Outside of range!'
|
28
|
+
|
29
|
+
result = TTY::Prompt::Question::Checks::CheckRange.call(question, 11)
|
30
|
+
|
31
|
+
expect(result).to eq([11, ['Outside of range!']])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "passes validation check" do
|
35
|
+
question = described_class.new(prompt)
|
36
|
+
question.validate(/\A\d{5}\Z/)
|
37
|
+
|
38
|
+
result = TTY::Prompt::Question::Checks::CheckValidation.call(question, '12345')
|
39
|
+
|
40
|
+
expect(result).to eq(['12345'])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "fails validation check" do
|
44
|
+
question = described_class.new(prompt, messages: TTY::Prompt.messages)
|
45
|
+
question.validate(/\A\d{5}\Z/)
|
46
|
+
|
47
|
+
result = TTY::Prompt::Question::Checks::CheckValidation.call(question, '123')
|
48
|
+
|
49
|
+
expect(result).to eq(['123', ['Your answer is invalid (must match /\\A\\d{5}\\Z/)']])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "fails validation check with inlined custom message" do
|
53
|
+
question = described_class.new(prompt)
|
54
|
+
question.validate(/\A\w+@\w+\.\w+\Z/, 'Invalid email address')
|
55
|
+
|
56
|
+
result = TTY::Prompt::Question::Checks::CheckValidation.call(question, 'piotr@com')
|
57
|
+
|
58
|
+
expect(result).to eq(['piotr@com', ['Invalid email address']])
|
59
|
+
end
|
60
|
+
|
61
|
+
it "fails validation check with custom message" do
|
62
|
+
question = described_class.new(prompt)
|
63
|
+
question.validate(/\A\w+@\w+\.\w+\Z/)
|
64
|
+
question.messages[:valid?] = 'Invalid email address'
|
65
|
+
|
66
|
+
result = TTY::Prompt::Question::Checks::CheckValidation.call(question, 'piotr@com')
|
67
|
+
|
68
|
+
expect(result).to eq(['piotr@com', ['Invalid email address']])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "passes required check" do
|
72
|
+
question = described_class.new(prompt)
|
73
|
+
question.required true
|
74
|
+
|
75
|
+
result = TTY::Prompt::Question::Checks::CheckRequired.call(question, 'Piotr')
|
76
|
+
|
77
|
+
expect(result).to eq(['Piotr'])
|
78
|
+
end
|
79
|
+
|
80
|
+
it "fails required check" do
|
81
|
+
question = described_class.new(prompt, messages: TTY::Prompt.messages)
|
82
|
+
question.required true
|
83
|
+
|
84
|
+
result = TTY::Prompt::Question::Checks::CheckRequired.call(question, nil)
|
85
|
+
|
86
|
+
expect(result).to eq([nil, ['Value must be provided']])
|
87
|
+
end
|
88
|
+
|
89
|
+
it "fails required check with custom message" do
|
90
|
+
question = described_class.new(prompt)
|
91
|
+
question.required true, 'Required input'
|
92
|
+
|
93
|
+
result = TTY::Prompt::Question::Checks::CheckRequired.call(question, nil)
|
94
|
+
|
95
|
+
expect(result).to eq([nil, ['Required input']])
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding
|
2
|
+
|
3
|
+
RSpec.describe TTY::Prompt::Reader::KeyEvent, '::from' do
|
4
|
+
|
5
|
+
it "parses ctrl+h" do
|
6
|
+
event = described_class.from("\b")
|
7
|
+
expect(event.key.name).to eq(:backspace)
|
8
|
+
expect(event.value).to eq("\b")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "parses lowercase char" do
|
12
|
+
event = described_class.from('a')
|
13
|
+
expect(event.key.name).to eq('a')
|
14
|
+
expect(event.value).to eq('a')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "parses uppercase char" do
|
18
|
+
event = described_class.from('A')
|
19
|
+
expect(event.key.name).to eq('a')
|
20
|
+
expect(event.value).to eq('A')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "parses f5 key" do
|
24
|
+
event = described_class.from("\e[15~")
|
25
|
+
expect(event.key.name).to eq(:f5)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "parses up key" do
|
29
|
+
event = described_class.from("\e[A")
|
30
|
+
expect(event.key.name).to eq(:up)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "parses up key on gnome" do
|
34
|
+
event = described_class.from("\eOA")
|
35
|
+
expect(event.key.name).to eq(:up)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "parses down key" do
|
39
|
+
event = described_class.from("\e[B")
|
40
|
+
expect(event.key.name).to eq(:down)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "parses right key" do
|
44
|
+
event = described_class.from("\e[C")
|
45
|
+
expect(event.key.name).to eq(:right)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "parses left key" do
|
49
|
+
event = described_class.from("\e[D")
|
50
|
+
expect(event.key.name).to eq(:left)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "parses clear key" do
|
54
|
+
event = described_class.from("\e[E")
|
55
|
+
expect(event.key.name).to eq(:clear)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "parses end key" do
|
59
|
+
event = described_class.from("\e[F")
|
60
|
+
expect(event.key.name).to eq(:end)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "parses home key" do
|
64
|
+
event = described_class.from("\e[H")
|
65
|
+
expect(event.key.name).to eq(:home)
|
66
|
+
end
|
67
|
+
end
|