tty-prompt 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +9 -6
- data/CHANGELOG.md +40 -3
- data/Gemfile +0 -1
- data/README.md +246 -65
- data/examples/ask.rb +7 -0
- data/examples/echo.rb +7 -0
- data/examples/in.rb +7 -0
- data/examples/mask.rb +9 -0
- data/examples/multi_select.rb +8 -0
- data/examples/select.rb +8 -0
- data/examples/validation.rb +9 -0
- data/examples/yes_no.rb +7 -0
- data/lib/tty-prompt.rb +6 -4
- data/lib/tty/prompt.rb +100 -25
- data/lib/tty/prompt/choice.rb +1 -1
- data/lib/tty/prompt/converter_dsl.rb +19 -0
- data/lib/tty/prompt/converter_registry.rb +56 -0
- data/lib/tty/prompt/converters.rb +77 -0
- data/lib/tty/prompt/evaluator.rb +29 -0
- data/lib/tty/prompt/list.rb +38 -36
- data/lib/tty/prompt/mask_question.rb +85 -0
- data/lib/tty/prompt/multi_list.rb +21 -32
- data/lib/tty/prompt/question.rb +184 -162
- data/lib/tty/prompt/question/checks.rb +85 -0
- data/lib/tty/prompt/question/modifier.rb +4 -5
- data/lib/tty/prompt/question/validation.rb +29 -35
- data/lib/tty/prompt/reader.rb +98 -52
- data/lib/tty/prompt/reader/codes.rb +63 -0
- data/lib/tty/prompt/reader/key_event.rb +67 -0
- data/lib/tty/prompt/reader/mode.rb +66 -0
- data/lib/tty/prompt/reader/mode/echo.rb +43 -0
- data/lib/tty/prompt/reader/mode/raw.rb +43 -0
- data/lib/tty/prompt/result.rb +42 -0
- data/lib/tty/prompt/statement.rb +9 -14
- data/lib/tty/prompt/suggestion.rb +4 -2
- data/lib/tty/prompt/symbols.rb +13 -0
- data/lib/tty/prompt/test.rb +3 -2
- data/lib/tty/prompt/utils.rb +1 -1
- data/lib/tty/prompt/version.rb +1 -1
- data/spec/unit/ask_spec.rb +31 -48
- data/spec/unit/choice/eql_spec.rb +0 -2
- data/spec/unit/choice/from_spec.rb +0 -2
- data/spec/unit/choices/add_spec.rb +0 -2
- data/spec/unit/choices/each_spec.rb +0 -2
- data/spec/unit/choices/new_spec.rb +0 -2
- data/spec/unit/choices/pluck_spec.rb +0 -2
- data/spec/unit/converters/convert_bool_spec.rb +58 -0
- data/spec/unit/{response/read_char_spec.rb → converters/convert_char_spec.rb} +2 -4
- data/spec/unit/converters/convert_custom_spec.rb +14 -0
- data/spec/unit/converters/convert_date_spec.rb +25 -0
- data/spec/unit/converters/convert_file_spec.rb +14 -0
- data/spec/unit/{response/read_number_spec.rb → converters/convert_number_spec.rb} +5 -7
- data/spec/unit/converters/convert_path_spec.rb +15 -0
- data/spec/unit/{response/read_range_spec.rb → converters/convert_range_spec.rb} +3 -5
- data/spec/unit/converters/convert_regex_spec.rb +12 -0
- data/spec/unit/converters/convert_string_spec.rb +21 -0
- data/spec/unit/distance/distance_spec.rb +0 -2
- data/spec/unit/error_spec.rb +0 -6
- data/spec/unit/evaluator_spec.rb +67 -0
- data/spec/unit/keypress_spec.rb +19 -0
- data/spec/unit/mask_spec.rb +95 -0
- data/spec/unit/multi_select_spec.rb +36 -24
- data/spec/unit/multiline_spec.rb +19 -0
- data/spec/unit/new_spec.rb +18 -0
- data/spec/unit/ok_spec.rb +10 -0
- data/spec/unit/question/default_spec.rb +17 -4
- data/spec/unit/question/echo_spec.rb +31 -0
- data/spec/unit/question/in_spec.rb +48 -16
- data/spec/unit/question/initialize_spec.rb +2 -9
- data/spec/unit/question/modifier/apply_to_spec.rb +9 -16
- data/spec/unit/question/modifier/letter_case_spec.rb +0 -2
- data/spec/unit/question/modifier/whitespace_spec.rb +12 -20
- data/spec/unit/question/modify_spec.rb +3 -7
- data/spec/unit/question/required_spec.rb +20 -14
- data/spec/unit/question/validate_spec.rb +20 -19
- data/spec/unit/question/validation/call_spec.rb +15 -6
- data/spec/unit/question/validation/coerce_spec.rb +17 -11
- data/spec/unit/reader/publish_keypress_event_spec.rb +81 -0
- data/spec/unit/reader/read_keypress_spec.rb +22 -0
- data/spec/unit/reader/read_line_spec.rb +31 -0
- data/spec/unit/reader/read_multiline_spec.rb +37 -0
- data/spec/unit/result_spec.rb +40 -0
- data/spec/unit/say_spec.rb +18 -23
- data/spec/unit/select_spec.rb +37 -32
- data/spec/unit/statement/initialize_spec.rb +4 -4
- data/spec/unit/suggest_spec.rb +0 -2
- data/spec/unit/warn_spec.rb +0 -5
- data/spec/unit/yes_no_spec.rb +70 -0
- data/tty-prompt.gemspec +7 -4
- metadata +123 -40
- data/lib/tty/prompt/codes.rb +0 -32
- data/lib/tty/prompt/cursor.rb +0 -131
- data/lib/tty/prompt/error.rb +0 -26
- data/lib/tty/prompt/mode.rb +0 -64
- data/lib/tty/prompt/mode/echo.rb +0 -41
- data/lib/tty/prompt/mode/raw.rb +0 -41
- data/lib/tty/prompt/response.rb +0 -247
- data/lib/tty/prompt/response_delegation.rb +0 -42
- data/spec/unit/cursor/new_spec.rb +0 -74
- data/spec/unit/question/character_spec.rb +0 -13
- data/spec/unit/reader/getc_spec.rb +0 -42
- data/spec/unit/response/read_bool_spec.rb +0 -58
- data/spec/unit/response/read_date_spec.rb +0 -16
- data/spec/unit/response/read_email_spec.rb +0 -45
- data/spec/unit/response/read_multiple_spec.rb +0 -21
- data/spec/unit/response/read_spec.rb +0 -69
- data/spec/unit/response/read_string_spec.rb +0 -14
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
module TTY
|
6
|
-
class Prompt
|
7
|
-
module ResponseDelegation
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
def_delegators :dispatch, :read,
|
11
|
-
:read_bool,
|
12
|
-
:read_char,
|
13
|
-
:read_choice,
|
14
|
-
:read_date,
|
15
|
-
:read_datetime,
|
16
|
-
:read_email,
|
17
|
-
:read_file,
|
18
|
-
:read_float,
|
19
|
-
:read_input,
|
20
|
-
:read_int,
|
21
|
-
:read_keypress,
|
22
|
-
:read_multiple,
|
23
|
-
:read_password,
|
24
|
-
:read_range,
|
25
|
-
:read_regex,
|
26
|
-
:read_string,
|
27
|
-
:read_symbol,
|
28
|
-
:read_text,
|
29
|
-
:read_type
|
30
|
-
|
31
|
-
# Create response instance when question readed is invoked
|
32
|
-
#
|
33
|
-
# @param [Response] response
|
34
|
-
#
|
35
|
-
# @api private
|
36
|
-
def dispatch(response = Response.new(self, prompt))
|
37
|
-
@response ||= response
|
38
|
-
end
|
39
|
-
|
40
|
-
end # ResponseDelegation
|
41
|
-
end # Prompt
|
42
|
-
end # TTY
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Cursor do
|
6
|
-
it "allows to print without mutating state" do
|
7
|
-
cursor = described_class.new
|
8
|
-
expect(cursor.shell).to eq(false)
|
9
|
-
expect(cursor.print.shell).to eq(true)
|
10
|
-
expect(cursor.shell).to eq(false)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "shows cursor" do
|
14
|
-
cursor = described_class.new
|
15
|
-
expect(cursor.show).to eq("\e[?25h")
|
16
|
-
end
|
17
|
-
|
18
|
-
it "hides cursor" do
|
19
|
-
cursor = described_class.new
|
20
|
-
expect(cursor.hide).to eq("\e[?25l")
|
21
|
-
end
|
22
|
-
|
23
|
-
it "saves cursor position" do
|
24
|
-
cursor = described_class.new
|
25
|
-
expect(cursor.save).to eq("\e[s")
|
26
|
-
end
|
27
|
-
|
28
|
-
it "restores cursor position" do
|
29
|
-
cursor = described_class.new
|
30
|
-
expect(cursor.restore).to eq("\e[u")
|
31
|
-
end
|
32
|
-
|
33
|
-
it "moves up default by 1 line" do
|
34
|
-
cursor = described_class.new
|
35
|
-
expect(cursor.move_up).to eq("\e[1A")
|
36
|
-
end
|
37
|
-
|
38
|
-
it "moves up by 5 lines" do
|
39
|
-
cursor = described_class.new
|
40
|
-
expect(cursor.move_up(5)).to eq("\e[5A")
|
41
|
-
end
|
42
|
-
|
43
|
-
it "moves down default by 1 line" do
|
44
|
-
cursor = described_class.new
|
45
|
-
expect(cursor.move_down).to eq("\e[1B")
|
46
|
-
end
|
47
|
-
|
48
|
-
it "clears line" do
|
49
|
-
cursor = described_class.new
|
50
|
-
expect(cursor.clear_line).to eq("\e[1000D\e[K")
|
51
|
-
end
|
52
|
-
|
53
|
-
it "clears 5 lines up" do
|
54
|
-
cursor = described_class.new
|
55
|
-
expect(cursor.clear_lines(5)).to eq([
|
56
|
-
"\e[1A\e[1000D\e[K",
|
57
|
-
"\e[1A\e[1000D\e[K",
|
58
|
-
"\e[1A\e[1000D\e[K",
|
59
|
-
"\e[1A\e[1000D\e[K",
|
60
|
-
"\e[1A\e[1000D\e[K"
|
61
|
-
].join)
|
62
|
-
end
|
63
|
-
|
64
|
-
it "clears 5 lines down" do
|
65
|
-
cursor = described_class.new
|
66
|
-
expect(cursor.clear_lines(5, :down)).to eq([
|
67
|
-
"\e[1B\e[1000D\e[K",
|
68
|
-
"\e[1B\e[1000D\e[K",
|
69
|
-
"\e[1B\e[1000D\e[K",
|
70
|
-
"\e[1B\e[1000D\e[K",
|
71
|
-
"\e[1B\e[1000D\e[K"
|
72
|
-
].join)
|
73
|
-
end
|
74
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#character' do
|
6
|
-
it 'switches to character input' do
|
7
|
-
prompt = TTY::TestPrompt.new
|
8
|
-
prompt.input << "abcd"
|
9
|
-
prompt.input.rewind
|
10
|
-
answer = prompt.ask("Which one do you prefer a, b, c or d?") { |q| q.char(true) }
|
11
|
-
expect(answer).to eq("abcd")
|
12
|
-
end
|
13
|
-
end
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Reader, '#getc' do
|
6
|
-
let(:instance) { described_class.new(prompt) }
|
7
|
-
|
8
|
-
let(:input) { StringIO.new }
|
9
|
-
let(:output) { StringIO.new }
|
10
|
-
let(:prompt) { TTY::Prompt.new(input, output) }
|
11
|
-
|
12
|
-
subject(:reader) { instance.getc mask }
|
13
|
-
|
14
|
-
context 'with mask' do
|
15
|
-
let(:mask) { '*'}
|
16
|
-
|
17
|
-
it 'masks characters' do
|
18
|
-
input << "password\n"
|
19
|
-
input.rewind
|
20
|
-
expect(reader).to eql "password"
|
21
|
-
expect(output.string).to eql("********")
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context "without mask" do
|
26
|
-
let(:mask) { }
|
27
|
-
|
28
|
-
it 'masks characters' do
|
29
|
-
input << "password\n"
|
30
|
-
input.rewind
|
31
|
-
expect(reader).to eql "password"
|
32
|
-
expect(output.string).to eql("password")
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'deletes characters when backspace pressed' do
|
36
|
-
input << "\b\b"
|
37
|
-
input.rewind
|
38
|
-
expect(reader).to eql ''
|
39
|
-
expect(output.string).to eql('')
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read_bool' do
|
6
|
-
it 'fails to read boolean' do
|
7
|
-
prompt = TTY::TestPrompt.new
|
8
|
-
prompt.input << 'invalid'
|
9
|
-
prompt.input.rewind
|
10
|
-
expect {
|
11
|
-
prompt.ask("Do you read books?", read: :bool)
|
12
|
-
}.to raise_error(Necromancer::ConversionTypeError)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "handles default values" do
|
16
|
-
prompt = TTY::TestPrompt.new
|
17
|
-
prompt.input << "\n"
|
18
|
-
prompt.input.rewind
|
19
|
-
response = prompt.ask('Do you read books?', read: :bool, default: true)
|
20
|
-
expect(response).to eql(true)
|
21
|
-
expect(prompt.output.string).to eq('Do you read books?')
|
22
|
-
end
|
23
|
-
|
24
|
-
it "handles default values" do
|
25
|
-
prompt = TTY::TestPrompt.new
|
26
|
-
prompt.input << "\n"
|
27
|
-
prompt.input.rewind
|
28
|
-
response = prompt.ask("Do you read books?") { |q|
|
29
|
-
q.default true
|
30
|
-
q.read :bool
|
31
|
-
}
|
32
|
-
expect(response).to eq(true)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'reads negative boolean' do
|
36
|
-
prompt = TTY::TestPrompt.new
|
37
|
-
prompt.input << 'No'
|
38
|
-
prompt.input.rewind
|
39
|
-
response = prompt.ask('Do you read books?', read: :bool)
|
40
|
-
expect(response).to eq(false)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'reads positive boolean' do
|
44
|
-
prompt = TTY::TestPrompt.new
|
45
|
-
prompt.input << 'Yes'
|
46
|
-
prompt.input.rewind
|
47
|
-
response = prompt.ask("Do you read books?", read: :bool)
|
48
|
-
expect(response).to eq(true)
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'reads single positive boolean' do
|
52
|
-
prompt = TTY::TestPrompt.new
|
53
|
-
prompt.input << 'y'
|
54
|
-
prompt.input.rewind
|
55
|
-
response = prompt.ask('Do you read books?', read: :bool)
|
56
|
-
expect(response).to eq(true)
|
57
|
-
end
|
58
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read_date' do
|
6
|
-
it 'reads date' do
|
7
|
-
prompt = TTY::TestPrompt.new
|
8
|
-
prompt.input << "20th April 1887"
|
9
|
-
prompt.input.rewind
|
10
|
-
response = prompt.ask("When were your born?", read: :date)
|
11
|
-
expect(response).to be_kind_of(Date)
|
12
|
-
expect(response.day).to eq(20)
|
13
|
-
expect(response.month).to eq(4)
|
14
|
-
expect(response.year).to eq(1887)
|
15
|
-
end
|
16
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read_email' do
|
6
|
-
context 'with valid email' do
|
7
|
-
it 'reads empty' do
|
8
|
-
prompt = TTY::TestPrompt.new
|
9
|
-
prompt.input << ""
|
10
|
-
prompt.input.rewind
|
11
|
-
response = prompt.ask("What is your email?", read: :email)
|
12
|
-
expect(response).to eql(nil)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'reads valid email' do
|
16
|
-
prompt = TTY::TestPrompt.new
|
17
|
-
prompt.input << "piotr@example.com"
|
18
|
-
prompt.input.rewind
|
19
|
-
response = prompt.ask('What is your email?', read: :email)
|
20
|
-
expect(response).to eq('piotr@example.com')
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'with invalid email' do
|
25
|
-
it 'fails to read invalid email' do
|
26
|
-
prompt = TTY::TestPrompt.new
|
27
|
-
prompt.input << "this will@neverwork"
|
28
|
-
prompt.input.rewind
|
29
|
-
expect {
|
30
|
-
prompt.ask("What is your email?", read: :email)
|
31
|
-
}.to raise_error(TTY::Prompt::InvalidArgument)
|
32
|
-
end
|
33
|
-
|
34
|
-
xit 'reads invalid and asks again' do
|
35
|
-
prompt = TTY::TestPrompt.new
|
36
|
-
prompt.input << "this will@neverwork\nthis.will@example.com"
|
37
|
-
prompt.input.rewind
|
38
|
-
response = prompt.ask("What is your email?", read: :email) do |q|
|
39
|
-
q.on_error :retry
|
40
|
-
end
|
41
|
-
expect(response).to eq('this.will@example.com')
|
42
|
-
expect(prompt.output.string).to eq("What is your email?\nWhat is your email?")
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,21 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read_multiline' do
|
6
|
-
it 'reads multiple lines' do
|
7
|
-
prompt = TTY::TestPrompt.new
|
8
|
-
prompt.input << "First line\nSecond line\nThird line"
|
9
|
-
prompt.input.rewind
|
10
|
-
answer = prompt.ask("Provide description?", read: :multiline)
|
11
|
-
expect(answer).to eq("First line\nSecond line\nThird line")
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'terminates on empty lines' do
|
15
|
-
prompt = TTY::TestPrompt.new
|
16
|
-
prompt.input << "First line\n\nSecond line"
|
17
|
-
prompt.input.rewind
|
18
|
-
answer = prompt.ask("Provide description?")
|
19
|
-
expect(answer).to eq("First line\n")
|
20
|
-
end
|
21
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read' do
|
6
|
-
context 'with no mask' do
|
7
|
-
it 'asks with echo on' do
|
8
|
-
prompt = TTY::TestPrompt.new
|
9
|
-
prompt.input << "password"
|
10
|
-
prompt.input.rewind
|
11
|
-
answer = prompt.ask("What is your password: ") { |q| q.echo(true) }
|
12
|
-
expect(answer).to eql("password")
|
13
|
-
expect(prompt.output.string).to eql('What is your password: ')
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'asks with echo off' do
|
17
|
-
prompt = TTY::TestPrompt.new
|
18
|
-
prompt.input << "password"
|
19
|
-
prompt.input.rewind
|
20
|
-
answer = prompt.ask("What is your password: ") { |q| q.echo(false) }
|
21
|
-
expect(answer).to eql("password")
|
22
|
-
expect(prompt.output.string).to eql('What is your password: ')
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'with mask' do
|
27
|
-
it 'masks output with character' do
|
28
|
-
prompt = TTY::TestPrompt.new
|
29
|
-
prompt.input << "password\n"
|
30
|
-
prompt.input.rewind
|
31
|
-
answer = prompt.ask("What is your password: ") { |q| q.mask('*') }
|
32
|
-
expect(answer).to eql("password")
|
33
|
-
expect(prompt.output.string).to eql('What is your password: ********')
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'ignores mask if echo is off' do
|
37
|
-
prompt = TTY::TestPrompt.new
|
38
|
-
prompt.input << "password"
|
39
|
-
prompt.input.rewind
|
40
|
-
answer = prompt.ask('What is your password: ') do |q|
|
41
|
-
q.echo false
|
42
|
-
q.mask '*'
|
43
|
-
end
|
44
|
-
expect(answer).to eql("password")
|
45
|
-
expect(prompt.output.string).to eql('What is your password: ')
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'with mask and echo as options' do
|
50
|
-
it 'asks with options' do
|
51
|
-
prompt = TTY::TestPrompt.new
|
52
|
-
prompt.input << "password"
|
53
|
-
prompt.input.rewind
|
54
|
-
answer = prompt.ask("What is your password: ", echo: false, mask: '*')
|
55
|
-
expect(answer).to eq("password")
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'asks with block' do
|
59
|
-
prompt = TTY::TestPrompt.new
|
60
|
-
prompt.input << "password"
|
61
|
-
prompt.input.rewind
|
62
|
-
answer = prompt.ask "What is your password: " do |q|
|
63
|
-
q.echo false
|
64
|
-
q.mask '*'
|
65
|
-
end
|
66
|
-
expect(answer).to eq("password")
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
RSpec.describe TTY::Prompt::Question, '#read_string' do
|
6
|
-
it 'reads string' do
|
7
|
-
prompt = TTY::TestPrompt.new
|
8
|
-
prompt.input << 'Piotr'
|
9
|
-
prompt.input.rewind
|
10
|
-
answer = prompt.ask("What is your name?", read: :string)
|
11
|
-
expect(answer).to be_a(String)
|
12
|
-
expect(answer).to eq('Piotr')
|
13
|
-
end
|
14
|
-
end
|