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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +9 -6
  3. data/CHANGELOG.md +40 -3
  4. data/Gemfile +0 -1
  5. data/README.md +246 -65
  6. data/examples/ask.rb +7 -0
  7. data/examples/echo.rb +7 -0
  8. data/examples/in.rb +7 -0
  9. data/examples/mask.rb +9 -0
  10. data/examples/multi_select.rb +8 -0
  11. data/examples/select.rb +8 -0
  12. data/examples/validation.rb +9 -0
  13. data/examples/yes_no.rb +7 -0
  14. data/lib/tty-prompt.rb +6 -4
  15. data/lib/tty/prompt.rb +100 -25
  16. data/lib/tty/prompt/choice.rb +1 -1
  17. data/lib/tty/prompt/converter_dsl.rb +19 -0
  18. data/lib/tty/prompt/converter_registry.rb +56 -0
  19. data/lib/tty/prompt/converters.rb +77 -0
  20. data/lib/tty/prompt/evaluator.rb +29 -0
  21. data/lib/tty/prompt/list.rb +38 -36
  22. data/lib/tty/prompt/mask_question.rb +85 -0
  23. data/lib/tty/prompt/multi_list.rb +21 -32
  24. data/lib/tty/prompt/question.rb +184 -162
  25. data/lib/tty/prompt/question/checks.rb +85 -0
  26. data/lib/tty/prompt/question/modifier.rb +4 -5
  27. data/lib/tty/prompt/question/validation.rb +29 -35
  28. data/lib/tty/prompt/reader.rb +98 -52
  29. data/lib/tty/prompt/reader/codes.rb +63 -0
  30. data/lib/tty/prompt/reader/key_event.rb +67 -0
  31. data/lib/tty/prompt/reader/mode.rb +66 -0
  32. data/lib/tty/prompt/reader/mode/echo.rb +43 -0
  33. data/lib/tty/prompt/reader/mode/raw.rb +43 -0
  34. data/lib/tty/prompt/result.rb +42 -0
  35. data/lib/tty/prompt/statement.rb +9 -14
  36. data/lib/tty/prompt/suggestion.rb +4 -2
  37. data/lib/tty/prompt/symbols.rb +13 -0
  38. data/lib/tty/prompt/test.rb +3 -2
  39. data/lib/tty/prompt/utils.rb +1 -1
  40. data/lib/tty/prompt/version.rb +1 -1
  41. data/spec/unit/ask_spec.rb +31 -48
  42. data/spec/unit/choice/eql_spec.rb +0 -2
  43. data/spec/unit/choice/from_spec.rb +0 -2
  44. data/spec/unit/choices/add_spec.rb +0 -2
  45. data/spec/unit/choices/each_spec.rb +0 -2
  46. data/spec/unit/choices/new_spec.rb +0 -2
  47. data/spec/unit/choices/pluck_spec.rb +0 -2
  48. data/spec/unit/converters/convert_bool_spec.rb +58 -0
  49. data/spec/unit/{response/read_char_spec.rb → converters/convert_char_spec.rb} +2 -4
  50. data/spec/unit/converters/convert_custom_spec.rb +14 -0
  51. data/spec/unit/converters/convert_date_spec.rb +25 -0
  52. data/spec/unit/converters/convert_file_spec.rb +14 -0
  53. data/spec/unit/{response/read_number_spec.rb → converters/convert_number_spec.rb} +5 -7
  54. data/spec/unit/converters/convert_path_spec.rb +15 -0
  55. data/spec/unit/{response/read_range_spec.rb → converters/convert_range_spec.rb} +3 -5
  56. data/spec/unit/converters/convert_regex_spec.rb +12 -0
  57. data/spec/unit/converters/convert_string_spec.rb +21 -0
  58. data/spec/unit/distance/distance_spec.rb +0 -2
  59. data/spec/unit/error_spec.rb +0 -6
  60. data/spec/unit/evaluator_spec.rb +67 -0
  61. data/spec/unit/keypress_spec.rb +19 -0
  62. data/spec/unit/mask_spec.rb +95 -0
  63. data/spec/unit/multi_select_spec.rb +36 -24
  64. data/spec/unit/multiline_spec.rb +19 -0
  65. data/spec/unit/new_spec.rb +18 -0
  66. data/spec/unit/ok_spec.rb +10 -0
  67. data/spec/unit/question/default_spec.rb +17 -4
  68. data/spec/unit/question/echo_spec.rb +31 -0
  69. data/spec/unit/question/in_spec.rb +48 -16
  70. data/spec/unit/question/initialize_spec.rb +2 -9
  71. data/spec/unit/question/modifier/apply_to_spec.rb +9 -16
  72. data/spec/unit/question/modifier/letter_case_spec.rb +0 -2
  73. data/spec/unit/question/modifier/whitespace_spec.rb +12 -20
  74. data/spec/unit/question/modify_spec.rb +3 -7
  75. data/spec/unit/question/required_spec.rb +20 -14
  76. data/spec/unit/question/validate_spec.rb +20 -19
  77. data/spec/unit/question/validation/call_spec.rb +15 -6
  78. data/spec/unit/question/validation/coerce_spec.rb +17 -11
  79. data/spec/unit/reader/publish_keypress_event_spec.rb +81 -0
  80. data/spec/unit/reader/read_keypress_spec.rb +22 -0
  81. data/spec/unit/reader/read_line_spec.rb +31 -0
  82. data/spec/unit/reader/read_multiline_spec.rb +37 -0
  83. data/spec/unit/result_spec.rb +40 -0
  84. data/spec/unit/say_spec.rb +18 -23
  85. data/spec/unit/select_spec.rb +37 -32
  86. data/spec/unit/statement/initialize_spec.rb +4 -4
  87. data/spec/unit/suggest_spec.rb +0 -2
  88. data/spec/unit/warn_spec.rb +0 -5
  89. data/spec/unit/yes_no_spec.rb +70 -0
  90. data/tty-prompt.gemspec +7 -4
  91. metadata +123 -40
  92. data/lib/tty/prompt/codes.rb +0 -32
  93. data/lib/tty/prompt/cursor.rb +0 -131
  94. data/lib/tty/prompt/error.rb +0 -26
  95. data/lib/tty/prompt/mode.rb +0 -64
  96. data/lib/tty/prompt/mode/echo.rb +0 -41
  97. data/lib/tty/prompt/mode/raw.rb +0 -41
  98. data/lib/tty/prompt/response.rb +0 -247
  99. data/lib/tty/prompt/response_delegation.rb +0 -42
  100. data/spec/unit/cursor/new_spec.rb +0 -74
  101. data/spec/unit/question/character_spec.rb +0 -13
  102. data/spec/unit/reader/getc_spec.rb +0 -42
  103. data/spec/unit/response/read_bool_spec.rb +0 -58
  104. data/spec/unit/response/read_date_spec.rb +0 -16
  105. data/spec/unit/response/read_email_spec.rb +0 -45
  106. data/spec/unit/response/read_multiple_spec.rb +0 -21
  107. data/spec/unit/response/read_spec.rb +0 -69
  108. 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