tty-prompt 0.2.0 → 0.3.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 (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