tty-prompt 0.16.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/lib/tty/prompt/messages.rb +49 -0
  4. data/lib/tty/prompt/version.rb +1 -3
  5. data/spec/spec_helper.rb +45 -0
  6. data/spec/unit/ask_spec.rb +132 -0
  7. data/spec/unit/choice/eql_spec.rb +22 -0
  8. data/spec/unit/choice/from_spec.rb +96 -0
  9. data/spec/unit/choices/add_spec.rb +12 -0
  10. data/spec/unit/choices/each_spec.rb +13 -0
  11. data/spec/unit/choices/find_by_spec.rb +10 -0
  12. data/spec/unit/choices/new_spec.rb +10 -0
  13. data/spec/unit/choices/pluck_spec.rb +9 -0
  14. data/spec/unit/collect_spec.rb +96 -0
  15. data/spec/unit/converters/convert_bool_spec.rb +58 -0
  16. data/spec/unit/converters/convert_char_spec.rb +11 -0
  17. data/spec/unit/converters/convert_custom_spec.rb +14 -0
  18. data/spec/unit/converters/convert_date_spec.rb +34 -0
  19. data/spec/unit/converters/convert_file_spec.rb +18 -0
  20. data/spec/unit/converters/convert_number_spec.rb +39 -0
  21. data/spec/unit/converters/convert_path_spec.rb +15 -0
  22. data/spec/unit/converters/convert_range_spec.rb +22 -0
  23. data/spec/unit/converters/convert_regex_spec.rb +12 -0
  24. data/spec/unit/converters/convert_string_spec.rb +21 -0
  25. data/spec/unit/converters/on_error_spec.rb +9 -0
  26. data/spec/unit/distance/distance_spec.rb +73 -0
  27. data/spec/unit/enum_paginator_spec.rb +75 -0
  28. data/spec/unit/enum_select_spec.rb +446 -0
  29. data/spec/unit/error_spec.rb +20 -0
  30. data/spec/unit/evaluator_spec.rb +67 -0
  31. data/spec/unit/expand_spec.rb +198 -0
  32. data/spec/unit/keypress_spec.rb +72 -0
  33. data/spec/unit/mask_spec.rb +132 -0
  34. data/spec/unit/multi_select_spec.rb +495 -0
  35. data/spec/unit/multiline_spec.rb +77 -0
  36. data/spec/unit/new_spec.rb +20 -0
  37. data/spec/unit/ok_spec.rb +10 -0
  38. data/spec/unit/paginator_spec.rb +73 -0
  39. data/spec/unit/question/checks_spec.rb +97 -0
  40. data/spec/unit/question/default_spec.rb +31 -0
  41. data/spec/unit/question/echo_spec.rb +38 -0
  42. data/spec/unit/question/in_spec.rb +115 -0
  43. data/spec/unit/question/initialize_spec.rb +12 -0
  44. data/spec/unit/question/modifier/apply_to_spec.rb +24 -0
  45. data/spec/unit/question/modifier/letter_case_spec.rb +41 -0
  46. data/spec/unit/question/modifier/whitespace_spec.rb +51 -0
  47. data/spec/unit/question/modify_spec.rb +41 -0
  48. data/spec/unit/question/required_spec.rb +92 -0
  49. data/spec/unit/question/validate_spec.rb +115 -0
  50. data/spec/unit/question/validation/call_spec.rb +31 -0
  51. data/spec/unit/question/validation/coerce_spec.rb +30 -0
  52. data/spec/unit/result_spec.rb +40 -0
  53. data/spec/unit/say_spec.rb +67 -0
  54. data/spec/unit/select_spec.rb +624 -0
  55. data/spec/unit/slider_spec.rb +100 -0
  56. data/spec/unit/statement/initialize_spec.rb +15 -0
  57. data/spec/unit/subscribe_spec.rb +20 -0
  58. data/spec/unit/suggest_spec.rb +28 -0
  59. data/spec/unit/warn_spec.rb +21 -0
  60. data/spec/unit/yes_no_spec.rb +235 -0
  61. data/tty-prompt.gemspec +4 -6
  62. metadata +120 -15
  63. data/.gitignore +0 -16
  64. data/.rspec +0 -3
  65. data/.travis.yml +0 -27
  66. data/CHANGELOG.md +0 -289
  67. data/CODE_OF_CONDUCT.md +0 -49
  68. data/Gemfile +0 -21
  69. data/appveyor.yml +0 -22
  70. data/benchmarks/speed.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aec759d54706c89726d2a7a9b5ec7d7dd14c773c0cb1240e1ecf51c2a0b734c6
4
- data.tar.gz: af25b5b8fe122644232e5e02fd2aea203bad75901d7dfa1d2c0605c4181035ab
3
+ metadata.gz: c1c688ca710d4099ceda4afec8d6e7dcbd2b20db56a94162348366dbfa15a33e
4
+ data.tar.gz: 58d8588967168ce881cd0b4da632d1bff7d67e735ad5debf906bf415d6c00ec6
5
5
  SHA512:
6
- metadata.gz: a44c4754daf0cabddbcce1a3863988603150df18364075ad0b9d2bef8193d16b3e0d67804f7553ace2f68c907cbcf9ad708f28442b5bd66c088400732bfa8101
7
- data.tar.gz: 4253e5b3e30113775138f233c28a020291d3d20a70ed8f7e37c68407c62ebda1f09788909274c66c8e8e88cb4c855dd0085a13a89a9e42b7fc5174dabc05051c
6
+ metadata.gz: e7037f42befaf3ebec087e72a17f1aeaf208e459952c6682a4f05cfc7ac753a081fc15e1524b8c286a2819872f8d75f3d669907a0244c49ccd520982b7c4e5fb
7
+ data.tar.gz: 39a6c809245322fd7a7d083343d2c6109ca9a28f8cdfc82ed0844eceb110704add7eccc0f1d5b4fd93f990f1c6a4a3b045ba0101f6bd71a8f967afe7c3d96f2a
data/README.md CHANGED
@@ -758,7 +758,7 @@ After the user presses "k":
758
758
  # Kitana
759
759
  ```
760
760
 
761
- After the user presse "ka":
761
+ After the user presses "ka":
762
762
 
763
763
  ```ruby
764
764
  # =>
@@ -1186,7 +1186,7 @@ The slider provides easy visual way of picking a value marked by `O` marker. You
1186
1186
  prompt.slider('Volume', max: 100, step: 5)
1187
1187
  # =>
1188
1188
  # Volume ──────────O────────── 50
1189
- # (User arrow keys, press Enter to select)
1189
+ # (Use arrow keys, press Enter to select)
1190
1190
  ```
1191
1191
 
1192
1192
  By default the slider is configured to pick middle of the range as a start value, you can change this by using the `:default` option:
@@ -0,0 +1,49 @@
1
+ module TTY
2
+ class Prompt
3
+ class Messages
4
+
5
+ def setup_messages
6
+ @messages = {
7
+ range?: 'Value %{value} must be within the range %{in}',
8
+ valid?: 'Your answer is invalid (must match %{valid})',
9
+ required?: 'Value must be provided'
10
+ }
11
+ end
12
+
13
+ def initialize
14
+ setup_messages
15
+ end
16
+
17
+ # Stores all the error messages displayed to user
18
+ # The currently supported messages are:
19
+ # * :range?
20
+ # * :required?
21
+ # * :valid?
22
+ attr_reader :messages
23
+
24
+ def get(key)
25
+
26
+ end
27
+
28
+ # Retrieve message based on the key
29
+ #
30
+ # @param [Symbol] name
31
+ # the name of message key
32
+ #
33
+ # @param [Hash] tokens
34
+ # the tokens to evaluate
35
+ #
36
+ # @return [Array[String]]
37
+ #
38
+ # @api private
39
+ def message_for(name, tokens = nil)
40
+ template = @messages[name]
41
+ if !template.match(/\%\{/).nil?
42
+ [template % tokens]
43
+ else
44
+ [template]
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,7 +1,5 @@
1
- # encoding: utf-8
2
-
3
1
  module TTY
4
2
  class Prompt
5
- VERSION = '0.16.1'.freeze
3
+ VERSION = '0.17.0'.freeze
6
4
  end # Prompt
7
5
  end # TTY
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ if RUBY_VERSION > '1.9' and (ENV['COVERAGE'] || ENV['TRAVIS'])
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
8
+ SimpleCov::Formatter::HTMLFormatter,
9
+ Coveralls::SimpleCov::Formatter
10
+ ]
11
+
12
+ SimpleCov.start do
13
+ command_name 'spec'
14
+ add_filter 'spec'
15
+ end
16
+ end
17
+
18
+ require 'tty-prompt'
19
+
20
+ RSpec.configure do |config|
21
+ config.expect_with :rspec do |expectations|
22
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
+ end
24
+
25
+ config.mock_with :rspec do |mocks|
26
+ mocks.verify_partial_doubles = true
27
+ end
28
+
29
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
30
+ config.disable_monkey_patching!
31
+
32
+ # This setting enables warnings. It's recommended, but in some cases may
33
+ # be too noisy due to issues in dependencies.
34
+ config.warnings = true
35
+
36
+ if config.files_to_run.one?
37
+ config.default_formatter = 'doc'
38
+ end
39
+
40
+ config.profile_examples = 2
41
+
42
+ config.order = :random
43
+
44
+ Kernel.srand config.seed
45
+ end
@@ -0,0 +1,132 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt, '#ask' do
4
+
5
+ subject(:prompt) { TTY::TestPrompt.new }
6
+
7
+ it 'asks question' do
8
+ prompt.ask('What is your name?')
9
+ expect(prompt.output.string).to eq([
10
+ "What is your name? ",
11
+ "\e[1A\e[2K\e[1G",
12
+ "What is your name? \n"
13
+ ].join)
14
+ end
15
+
16
+ it 'asks an empty question ' do
17
+ prompt.ask('')
18
+ expect(prompt.output.string).to eql('')
19
+ end
20
+
21
+ it 'asks an empty question and returns nil if EOF is sent to stdin' do
22
+ prompt.input << nil
23
+ prompt.input.rewind
24
+ answer = prompt.ask('')
25
+ expect(answer).to eql(nil)
26
+ expect(prompt.output.string).to eq('')
27
+ end
28
+
29
+ it "asks a question with a prefix [?]" do
30
+ prompt = TTY::TestPrompt.new(prefix: "[?] ")
31
+ prompt.input << "\r"
32
+ prompt.input.rewind
33
+ answer = prompt.ask 'Are you Polish?'
34
+ expect(answer).to eq(nil)
35
+ expect(prompt.output.string).to eq([
36
+ "[?] Are you Polish? ",
37
+ "\e[2K\e[1G[?] Are you Polish? \n",
38
+ "\e[1A\e[2K\e[1G",
39
+ "[?] Are you Polish? \n"
40
+ ].join)
41
+ end
42
+
43
+ it 'asks a question with block' do
44
+ prompt.input << ''
45
+ prompt.input.rewind
46
+ answer = prompt.ask "What is your name?" do |q|
47
+ q.default 'Piotr'
48
+ end
49
+ expect(answer).to eq('Piotr')
50
+ expect(prompt.output.string).to eq([
51
+ "What is your name? \e[90m(Piotr)\e[0m ",
52
+ "\e[1A\e[2K\e[1G",
53
+ "What is your name? \e[32mPiotr\e[0m\n"
54
+ ].join)
55
+ end
56
+
57
+ it "changes question color" do
58
+ prompt.input << ''
59
+ prompt.input.rewind
60
+ options = {default: 'Piotr', help_color: :red, active_color: :cyan}
61
+ answer = prompt.ask("What is your name?", options)
62
+ expect(answer).to eq('Piotr')
63
+ expect(prompt.output.string).to eq([
64
+ "What is your name? \e[31m(Piotr)\e[0m ",
65
+ "\e[1A\e[2K\e[1G",
66
+ "What is your name? \e[36mPiotr\e[0m\n"
67
+ ].join)
68
+ end
69
+
70
+ it "permits empty default parameter" do
71
+ prompt.input << "\r"
72
+ prompt.input.rewind
73
+
74
+ answer = prompt.ask("What is your name?", default: '')
75
+ expect(answer).to eq('')
76
+ expect(prompt.output.string).to eq([
77
+ "What is your name? ",
78
+ "\e[2K\e[1GWhat is your name? \n",
79
+ "\e[1A\e[2K\e[1G",
80
+ "What is your name? \n"
81
+ ].join)
82
+ end
83
+
84
+ it "permits nil default parameter" do
85
+ prompt.input << "\r"
86
+ prompt.input.rewind
87
+
88
+ answer = prompt.ask("What is your name?", default: nil)
89
+ expect(answer).to eq(nil)
90
+ expect(prompt.output.string).to eq([
91
+ "What is your name? ",
92
+ "\e[2K\e[1GWhat is your name? \n",
93
+ "\e[1A\e[2K\e[1G",
94
+ "What is your name? \n"
95
+ ].join)
96
+ end
97
+
98
+ it "overwrites global settings" do
99
+ global_settings = {prefix: "[?] ", active_color: :cyan, help_color: :red}
100
+ prompt = TTY::TestPrompt.new(global_settings)
101
+
102
+ prompt.input << "Piotr\r"
103
+ prompt.input.rewind
104
+ prompt.ask('What is your name?')
105
+
106
+ prompt.input << "Piotr\r"
107
+ prompt.input.rewind
108
+ local_settings = {prefix: ':-) ', active_color: :blue, help_color: :magenta}
109
+ prompt.ask('What is your name?', local_settings)
110
+
111
+ expect(prompt.output.string).to eq([
112
+ "[?] What is your name? ",
113
+ "\e[2K\e[1G[?] What is your name? P",
114
+ "\e[2K\e[1G[?] What is your name? Pi",
115
+ "\e[2K\e[1G[?] What is your name? Pio",
116
+ "\e[2K\e[1G[?] What is your name? Piot",
117
+ "\e[2K\e[1G[?] What is your name? Piotr",
118
+ "\e[2K\e[1G[?] What is your name? Piotr\n",
119
+ "\e[1A\e[2K\e[1G",
120
+ "[?] What is your name? \e[36mPiotr\e[0m\n",
121
+ ":-) What is your name? ",
122
+ "\e[2K\e[1G:-) What is your name? P",
123
+ "\e[2K\e[1G:-) What is your name? Pi",
124
+ "\e[2K\e[1G:-) What is your name? Pio",
125
+ "\e[2K\e[1G:-) What is your name? Piot",
126
+ "\e[2K\e[1G:-) What is your name? Piotr",
127
+ "\e[2K\e[1G:-) What is your name? Piotr\n",
128
+ "\e[1A\e[2K\e[1G",
129
+ ":-) What is your name? \e[34mPiotr\e[0m\n"
130
+ ].join)
131
+ end
132
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choice, '#==' do
4
+ it "is true with the same name and value attributes" do
5
+ expect(described_class.new(:large, 1)).
6
+ to eq(described_class.new(:large, 1))
7
+ end
8
+
9
+ it "is false with different name attribute" do
10
+ expect(described_class.new(:large, 1)).
11
+ not_to eq(described_class.new(:medium, 1))
12
+ end
13
+
14
+ it "is false with different value attribute" do
15
+ expect(described_class.new(:large, 1)).
16
+ not_to eq(described_class.new(:large, 2))
17
+ end
18
+
19
+ it "is false with non-choice object" do
20
+ expect(described_class.new(:large, 1)).not_to eq(:other)
21
+ end
22
+ end
@@ -0,0 +1,96 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choice, '#from' do
4
+ it "skips Choice instance" do
5
+ choice = described_class.new(:large, 1)
6
+
7
+ expect(described_class.from(choice)).to eq(choice)
8
+ end
9
+
10
+ it "creates choice from string" do
11
+ expected_choice = described_class.new('large', 'large')
12
+ choice = described_class.from('large')
13
+
14
+ expect(choice).to eq(expected_choice)
15
+ expect(choice.name).to eq('large')
16
+ expect(choice.value).to eq('large')
17
+ end
18
+
19
+ it "creates choice from array with one element" do
20
+ expected_choice = described_class.new('large', 'large')
21
+ choice = described_class.from([:large])
22
+
23
+ expect(choice).to eq(expected_choice)
24
+ expect(choice.name).to eq('large')
25
+ expect(choice.value).to eq('large')
26
+ end
27
+
28
+ it "creates choice from array with more than one element" do
29
+ expected_choice = described_class.new('large', 1)
30
+ choice = described_class.from([:large, 1])
31
+
32
+ expect(choice).to eq(expected_choice)
33
+ expect(choice.name).to eq('large')
34
+ expect(choice.value).to eq(1)
35
+ end
36
+
37
+ it "creates choice from hash value" do
38
+ expected_choice = described_class.new('large', 1)
39
+ choice = described_class.from({large: 1})
40
+
41
+ expect(choice).to eq(expected_choice)
42
+ expect(choice.name).to eq('large')
43
+ expect(choice.value).to eq(1)
44
+ end
45
+
46
+ it "creats choice from array with key value pair" do
47
+ expected_choice = described_class.new('large', 1)
48
+ choice = described_class.from([{'large' => 1}])
49
+
50
+ expect(choice).to eq(expected_choice)
51
+ expect(choice.name).to eq('large')
52
+ expect(choice.value).to eq(1)
53
+ end
54
+
55
+ it "creats choice from array with hash elements" do
56
+ expected_choice = described_class.new('large', 1)
57
+ choice = described_class.from([{name: 'large', value: 1}])
58
+
59
+ expect(choice).to eq(expected_choice)
60
+ expect(choice.name).to eq('large')
61
+ expect(choice.value).to eq(1)
62
+ end
63
+
64
+ it "creats choice from array with hash elements without value" do
65
+ expected_choice = described_class.new('large', 'large')
66
+ choice = described_class.from([{name: 'large'}])
67
+
68
+ expect(choice).to eq(expected_choice)
69
+ expect(choice.name).to eq('large')
70
+ expect(choice.value).to eq('large')
71
+ end
72
+
73
+ it "creates choice from hash with key property" do
74
+ default = {key: 'h', name: 'Help', value: :help}
75
+ expected_choice = described_class.new('Help', :help, key: 'h')
76
+ choice = described_class.from(default)
77
+
78
+ expect(choice).to eq(expected_choice)
79
+ expect(choice.name).to eq('Help')
80
+ expect(choice.value).to eq(:help)
81
+ expect(choice.disabled?).to eq(false)
82
+ end
83
+
84
+ it "creates disabled choice" do
85
+ expected_choice = described_class.new('Disabled', :none, disabled: true)
86
+ choice = described_class.from({
87
+ name: 'Disabled',
88
+ value: :none,
89
+ disabled: 'unavailable'})
90
+
91
+ expect(choice).to eq(expected_choice)
92
+ expect(choice.name).to eq('Disabled')
93
+ expect(choice.value).to eq(:none)
94
+ expect(choice.disabled?).to eq(true)
95
+ end
96
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choices, '#<<' do
4
+ it "adds choice to collection" do
5
+ choices = described_class.new
6
+ expect(choices).to be_empty
7
+ choice = TTY::Prompt::Choice.from([:label, 1])
8
+ choices << [:label, 1]
9
+ expect(choices.size).to eq(1)
10
+ expect(choices.to_ary).to eq([choice])
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choices, '.each' do
4
+ it "iterates over collection" do
5
+ choices = described_class[:large, :medium, :small]
6
+ actual = []
7
+ choices.each do |choice|
8
+ actual << choice.name
9
+ end
10
+ expect(actual).to eq([:large, :medium, :small])
11
+ expect(choices.each).to be_kind_of(Enumerator)
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choices, '#find_by' do
4
+ it "finds a matching choice by key name" do
5
+ collection = [{name: 'large'},{name: 'medium'},{name: 'small'}]
6
+ choice = TTY::Prompt::Choice.from(name: 'small')
7
+ choices = described_class[*collection]
8
+ expect(choices.find_by(:name, 'small')).to eq(choice)
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choices, '.new' do
4
+ it "creates choices collection" do
5
+ choice_1 = TTY::Prompt::Choice.from(:label1)
6
+ choice_2 = TTY::Prompt::Choice.from(:label2)
7
+ collection = described_class[:label1, :label2]
8
+ expect(collection.choices).to eq([choice_1, choice_2])
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ RSpec.describe TTY::Prompt::Choices, '#pluck' do
4
+ it "plucks choice by key name" do
5
+ collection = [{name: 'large'},{name: 'medium'},{name: 'small'}]
6
+ choices = described_class[*collection]
7
+ expect(choices.pluck(:name)).to eq(['large', 'medium', 'small'])
8
+ end
9
+ end