tty-prompt 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -2
  3. data/CHANGELOG.md +12 -0
  4. data/README.md +223 -59
  5. data/lib/tty/prompt/choice.rb +83 -0
  6. data/lib/tty/prompt/choices.rb +92 -0
  7. data/lib/tty/prompt/codes.rb +32 -0
  8. data/lib/tty/prompt/cursor.rb +131 -0
  9. data/lib/tty/prompt/list.rb +209 -0
  10. data/lib/tty/prompt/mode/echo.rb +10 -9
  11. data/lib/tty/prompt/mode/raw.rb +10 -9
  12. data/lib/tty/prompt/multi_list.rb +105 -0
  13. data/lib/tty/prompt/question/validation.rb +12 -27
  14. data/lib/tty/prompt/question.rb +58 -107
  15. data/lib/tty/prompt/reader.rb +44 -11
  16. data/lib/tty/prompt/response.rb +31 -36
  17. data/lib/tty/prompt/response_delegation.rb +3 -2
  18. data/lib/tty/prompt/statement.rb +10 -10
  19. data/lib/tty/prompt/test.rb +15 -0
  20. data/lib/tty/prompt/version.rb +3 -3
  21. data/lib/tty/prompt.rb +72 -9
  22. data/lib/tty-prompt.rb +11 -0
  23. data/spec/unit/ask_spec.rb +32 -35
  24. data/spec/unit/choice/eql_spec.rb +24 -0
  25. data/spec/unit/choice/from_spec.rb +25 -0
  26. data/spec/unit/choices/add_spec.rb +14 -0
  27. data/spec/unit/choices/each_spec.rb +15 -0
  28. data/spec/unit/choices/new_spec.rb +12 -0
  29. data/spec/unit/choices/pluck_spec.rb +11 -0
  30. data/spec/unit/cursor/new_spec.rb +74 -0
  31. data/spec/unit/error_spec.rb +4 -8
  32. data/spec/unit/multi_select_spec.rb +163 -0
  33. data/spec/unit/question/character_spec.rb +5 -16
  34. data/spec/unit/question/default_spec.rb +4 -10
  35. data/spec/unit/question/in_spec.rb +15 -12
  36. data/spec/unit/question/initialize_spec.rb +1 -6
  37. data/spec/unit/question/modify_spec.rb +25 -24
  38. data/spec/unit/question/required_spec.rb +31 -0
  39. data/spec/unit/question/validate_spec.rb +25 -17
  40. data/spec/unit/question/validation/call_spec.rb +22 -0
  41. data/spec/unit/response/read_bool_spec.rb +38 -27
  42. data/spec/unit/response/read_char_spec.rb +5 -8
  43. data/spec/unit/response/read_date_spec.rb +8 -12
  44. data/spec/unit/response/read_email_spec.rb +25 -22
  45. data/spec/unit/response/read_multiple_spec.rb +11 -13
  46. data/spec/unit/response/read_number_spec.rb +12 -16
  47. data/spec/unit/response/read_range_spec.rb +10 -13
  48. data/spec/unit/response/read_spec.rb +39 -38
  49. data/spec/unit/response/read_string_spec.rb +7 -12
  50. data/spec/unit/say_spec.rb +10 -14
  51. data/spec/unit/select_spec.rb +192 -0
  52. data/spec/unit/statement/initialize_spec.rb +0 -4
  53. data/spec/unit/suggest_spec.rb +6 -9
  54. data/spec/unit/warn_spec.rb +4 -8
  55. metadata +32 -8
  56. data/spec/unit/question/argument_spec.rb +0 -30
  57. data/spec/unit/question/valid_spec.rb +0 -46
  58. data/spec/unit/question/validation/valid_value_spec.rb +0 -22
data/lib/tty/prompt.rb CHANGED
@@ -20,12 +20,12 @@ module TTY
20
20
  # @api private
21
21
  attr_reader :output
22
22
 
23
- # Shell prompt prefix
23
+ # Prompt prefix
24
24
  #
25
25
  # @api private
26
26
  attr_reader :prefix
27
27
 
28
- # Initialize a Shell
28
+ # Initialize a Prompt
29
29
  #
30
30
  # @api public
31
31
  def initialize(input = stdin, output = stdout, options = {})
@@ -37,7 +37,7 @@ module TTY
37
37
  # Ask a question.
38
38
  #
39
39
  # @example
40
- # shell = TTY::Shell.new
40
+ # shell = TTY::Prompt.new
41
41
  # shell.ask("What is your name?")
42
42
  #
43
43
  # @param [String] statement
@@ -51,22 +51,85 @@ module TTY
51
51
  # @return [TTY::Question]
52
52
  #
53
53
  # @api public
54
- def ask(statement, *args, &block)
54
+ def ask(message, *args, &block)
55
55
  options = Utils.extract_options!(args)
56
56
 
57
- question = Question.new self, options
58
- question.instance_eval(&block) if block_given?
59
- question.prompt(statement)
57
+ question = Question.new(self, options)
58
+ question.call(message, &block)
59
+ end
60
+
61
+ # Ask a question with a list of options
62
+ #
63
+ # @example
64
+ # prompt = TTY::Prompt.new
65
+ # prompt.select("What size?", %w(large medium small))
66
+ #
67
+ # @example
68
+ # prompt = TTY::Prompt.new
69
+ # prompt.select("What size?") do |menu|
70
+ # menu.choice :large
71
+ # menu.choices %w(:medium :small)
72
+ # end
73
+ #
74
+ # @param [String] question
75
+ # the question to ask
76
+ #
77
+ # @param [Array[Object]] choices
78
+ # the choices to select from
79
+ #
80
+ # @api public
81
+ def select(question, *args, &block)
82
+ options = Utils.extract_options!(args)
83
+ choices = if block
84
+ []
85
+ elsif args.empty?
86
+ options
87
+ else
88
+ args.flatten
89
+ end
90
+
91
+ list = List.new(self, options)
92
+ list.call(question, choices, &block)
93
+ end
94
+
95
+ # Ask a question with multiple attributes activated
96
+ #
97
+ # @example
98
+ # prompt = TTY::Prompt.new
99
+ # choices = %w(Scorpion Jax Kitana Baraka Jade)
100
+ # prompt.multi_select("Choose your destiny?", choices)
101
+ #
102
+ # @param [String] question
103
+ # the question to ask
104
+ #
105
+ # @param [Array[Object]] choices
106
+ # the choices to select from
107
+ #
108
+ # @return [String]
109
+ #
110
+ # @api public
111
+ def multi_select(question, *args, &block)
112
+ options = Utils.extract_options!(args)
113
+ choices = if block
114
+ []
115
+ elsif args.empty?
116
+ options
117
+ else
118
+ args.flatten
119
+ end
120
+
121
+ list = MultiList.new(self, options)
122
+ list.call(question, choices, &block)
60
123
  end
61
124
 
62
125
  # A shortcut method to ask the user positive question and return
63
- # true for 'yes' reply.
126
+ # true for 'yes' reply, false for 'no'.
64
127
  #
65
128
  # @return [Boolean]
66
129
  #
67
130
  # @api public
68
131
  def yes?(statement, *args, &block)
69
- ask(statement, *args, &block).read_bool
132
+ ask(statement, {read: :bool}, &block)
70
133
  end
71
134
 
72
135
  # A shortcut method to ask the user negative question and return
data/lib/tty-prompt.rb CHANGED
@@ -5,11 +5,22 @@ require 'pastel'
5
5
  require 'tty-platform'
6
6
 
7
7
  require 'tty/prompt'
8
+ require 'tty/prompt/choice'
9
+ require 'tty/prompt/choices'
10
+ require 'tty/prompt/codes'
11
+ require 'tty/prompt/cursor'
12
+ require 'tty/prompt/list'
13
+ require 'tty/prompt/multi_list'
8
14
  require 'tty/prompt/mode'
9
15
  require 'tty/prompt/question'
10
16
  require 'tty/prompt/reader'
11
17
  require 'tty/prompt/response'
12
18
  require 'tty/prompt/statement'
13
19
  require 'tty/prompt/suggestion'
20
+ require 'tty/prompt/test'
14
21
  require 'tty/prompt/utils'
15
22
  require 'tty/prompt/version'
23
+
24
+ module TTY
25
+ PromptConfigurationError = Class.new(StandardError)
26
+ end
@@ -3,74 +3,71 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe TTY::Prompt, '#ask' do
6
- let(:input) { StringIO.new }
7
- let(:output) { StringIO.new }
8
- let(:prefix) { '' }
9
- let(:options) { { prefix: prefix } }
10
6
 
11
- subject(:prompt) { TTY::Prompt.new(input, output, options) }
7
+ subject(:prompt) { TTY::TestPrompt.new }
12
8
 
13
9
  it 'prints message' do
14
- prompt.ask "What is your name?"
15
- expect(output.string).to eql "What is your name?\n"
10
+ prompt.ask("What is your name?")
11
+ expect(prompt.output.string).to eql("What is your name?")
16
12
  end
17
13
 
18
14
  it 'prints an empty message ' do
19
- prompt.ask ""
20
- expect(output.string).to eql ""
15
+ prompt.ask('')
16
+ expect(prompt.output.string).to eql('')
21
17
  end
22
18
 
23
19
  it 'prints an empty message and returns nil if EOF is sent to stdin' do
24
- input << nil
25
- input.rewind
26
- q = prompt.ask ""
27
- expect(q.read).to eql nil
20
+ prompt.input << nil
21
+ prompt.input.rewind
22
+ response = prompt.ask("")
23
+ expect(response).to eql(nil)
24
+ expect(prompt.output.string).to eq('')
28
25
  end
29
26
 
30
- context 'with a prompt prefix' do
31
- let(:prefix) { ' > ' }
32
-
33
- it "asks a question with '>'" do
34
- input << ''
35
- input.rewind
36
- prompt.ask "Are you Polish?"
37
- expect(output.string).to eql " > Are you Polish?\n"
38
- end
27
+ it "asks a question with a prefix '>'" do
28
+ prompt = TTY::TestPrompt.new(prefix: ' > ')
29
+ prompt.input << ''
30
+ prompt.input.rewind
31
+ response = prompt.ask "Are you Polish?"
32
+ expect(response).to eq(nil)
33
+ expect(prompt.output.string).to eql " > Are you Polish?"
39
34
  end
40
35
 
41
36
  it 'asks a question with block' do
42
- input << ''
43
- input.rewind
44
- q = prompt.ask "What is your name?" do
45
- default 'Piotr'
37
+ prompt.input << ''
38
+ prompt.input.rewind
39
+ value = prompt.ask "What is your name?" do |q|
40
+ q.default 'Piotr'
46
41
  end
47
- expect(q.read).to eql "Piotr"
42
+ expect(value).to eql "Piotr"
43
+ expect(prompt.output.string).to eq('What is your name?')
48
44
  end
49
45
 
50
46
  context 'yes?' do
51
47
  it 'agrees' do
52
- input << 'yes'
53
- input.rewind
48
+ prompt.input << 'yes'
49
+ prompt.input.rewind
54
50
  expect(prompt.yes?("Are you a human?")).to eq(true)
51
+ expect(prompt.output.string).to eq('Are you a human?')
55
52
  end
56
53
 
57
54
  it 'disagrees' do
58
- input << 'no'
59
- input.rewind
55
+ prompt.input << 'no'
56
+ prompt.input.rewind
60
57
  expect(prompt.yes?("Are you a human?")).to eq(false)
61
58
  end
62
59
  end
63
60
 
64
61
  context 'no?' do
65
62
  it 'agrees' do
66
- input << 'no'
67
- input.rewind
63
+ prompt.input << 'no'
64
+ prompt.input.rewind
68
65
  expect(prompt.no?("Are you a human?")).to eq(true)
69
66
  end
70
67
 
71
68
  it 'disagrees' do
72
- input << 'yes'
73
- input.rewind
69
+ prompt.input << 'yes'
70
+ prompt.input.rewind
74
71
  expect(prompt.no?("Are you a human?")).to eq(false)
75
72
  end
76
73
  end
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choice, '#==' do
6
+ it "is true with the same name and value attributes" do
7
+ expect(described_class.new(:large, 1)).
8
+ to eq(described_class.new(:large, 1))
9
+ end
10
+
11
+ it "is false with different name attribute" do
12
+ expect(described_class.new(:large, 1)).
13
+ not_to eq(described_class.new(:medium, 1))
14
+ end
15
+
16
+ it "is false with different value attribute" do
17
+ expect(described_class.new(:large, 1)).
18
+ not_to eq(described_class.new(:large, 2))
19
+ end
20
+
21
+ it "is false with non-choice object" do
22
+ expect(described_class.new(:large, 1)).not_to eq(:other)
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choice, '#from' do
6
+ it "creates choice from choice" do
7
+ choice = described_class.new(:large, 1)
8
+ expect(described_class.from(choice)).to eq(choice)
9
+ end
10
+
11
+ it "creates choice from string" do
12
+ choice = described_class.new('large', 'large')
13
+ expect(described_class.from('large')).to eq(choice)
14
+ end
15
+
16
+ it "creates choice from array" do
17
+ choice = described_class.new('large', 1)
18
+ expect(described_class.from([:large, 1])).to eq(choice)
19
+ end
20
+
21
+ it "creates choice from hash value" do
22
+ choice = described_class.new('large', 1)
23
+ expect(described_class.from({large: 1})).to eq(choice)
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choices, '#<<' do
6
+ it "adds choice to collection" do
7
+ choices = described_class.new
8
+ expect(choices).to be_empty
9
+ choice = TTY::Prompt::Choice.from([:label, 1])
10
+ choices << [:label, 1]
11
+ expect(choices.size).to eq(1)
12
+ expect(choices.to_ary).to eq([choice])
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choices, '.each' do
6
+ it "iterates over collection" do
7
+ choices = described_class[:large, :medium, :small]
8
+ actual = []
9
+ choices.each do |choice|
10
+ actual << choice.name
11
+ end
12
+ expect(actual).to eq([:large, :medium, :small])
13
+ expect(choices.each).to be_kind_of(Enumerator)
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choices, '.new' do
6
+ it "creates choices collection" do
7
+ choice_1 = TTY::Prompt::Choice.from(:label1)
8
+ choice_2 = TTY::Prompt::Choice.from(:label2)
9
+ collection = described_class[:label1, :label2]
10
+ expect(collection.choices).to eq([choice_1, choice_2])
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt::Choices, '.pluck' do
6
+ it "plucks choice from collection by name" do
7
+ collection = %w(large medium small)
8
+ choices = described_class[*collection]
9
+ expect(choices.pluck('medium').name).to eq('medium')
10
+ end
11
+ end
@@ -0,0 +1,74 @@
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
@@ -3,28 +3,24 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe TTY::Prompt, '.error' do
6
- let(:input) { StringIO.new }
7
- let(:output) { StringIO.new }
8
6
  let(:color) { Pastel.new(enabled: true) }
9
7
 
10
- subject(:prompt) { described_class.new(input, output) }
8
+ subject(:prompt) { TTY::TestPrompt.new }
11
9
 
12
10
  before { allow(Pastel).to receive(:new).and_return(color) }
13
11
 
14
- after { output.rewind }
15
-
16
12
  it 'displays one message' do
17
13
  prompt.error "Nothing is fine!"
18
- expect(output.string).to eql "\e[31mNothing is fine!\e[0m\n"
14
+ expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m\n"
19
15
  end
20
16
 
21
17
  it 'displays many messages' do
22
18
  prompt.error "Nothing is fine!", "All is broken!"
23
- expect(output.string).to eql "\e[31mNothing is fine!\e[0m\n\e[31mAll is broken!\e[0m\n"
19
+ expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m\n\e[31mAll is broken!\e[0m\n"
24
20
  end
25
21
 
26
22
  it 'displays message with option' do
27
23
  prompt.error "Nothing is fine!", newline: false
28
- expect(output.string).to eql "\e[31mNothing is fine!\e[0m"
24
+ expect(prompt.output.string).to eql "\e[31mNothing is fine!\e[0m"
29
25
  end
30
26
  end
@@ -0,0 +1,163 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe TTY::Prompt do
6
+ let(:color) { Pastel.new(enabled: true) }
7
+
8
+ before { allow(Pastel).to receive(:new).and_return(color) }
9
+
10
+ it "selects nothing when return pressed immediately" do
11
+ prompt = TTY::TestPrompt.new
12
+ choices = %w(vodka beer wine whisky bourbon)
13
+ prompt.input << "\r"
14
+ prompt.input.rewind
15
+ expect(prompt.multi_select("Select drinks?", choices)). to eq([])
16
+ expect(prompt.output.string).to eq([
17
+ "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
18
+ "‣ ⬡ vodka\n",
19
+ " ⬡ beer\n",
20
+ " ⬡ wine\n",
21
+ " ⬡ whisky\n",
22
+ " ⬡ bourbon\n",
23
+ "\e[1A\e[1000D\e[K" * 6,
24
+ "Select drinks? \n\e[?25h"
25
+ ].join)
26
+ end
27
+
28
+ it "selects item when space pressed" do
29
+ prompt = TTY::TestPrompt.new
30
+ choices = %w(vodka beer wine whisky bourbon)
31
+ prompt.input << " \r"
32
+ prompt.input.rewind
33
+ expect(prompt.multi_select("Select drinks?", choices)). to eq(['vodka'])
34
+ expect(prompt.output.string).to eq([
35
+ "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
36
+ "‣ ⬡ vodka\n",
37
+ " ⬡ beer\n",
38
+ " ⬡ wine\n",
39
+ " ⬡ whisky\n",
40
+ " ⬡ bourbon\n",
41
+ "\e[1A\e[1000D\e[K" * 6,
42
+ "Select drinks? vodka\n",
43
+ "‣ \e[32m⬢\e[0m vodka\n",
44
+ " ⬡ beer\n",
45
+ " ⬡ wine\n",
46
+ " ⬡ whisky\n",
47
+ " ⬡ bourbon\n",
48
+ "\e[1A\e[1000D\e[K" * 6,
49
+ "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
50
+ ].join)
51
+ end
52
+
53
+ it "sets choice custom values" do
54
+ prompt = TTY::TestPrompt.new
55
+ choices = {vodka: 1, beer: 2, wine: 3, whisky: 4, bourbon: 5}
56
+ prompt.input << " \r"
57
+ prompt.input.rewind
58
+ expect(prompt.multi_select("Select drinks?", choices)).to eq([1])
59
+ expect(prompt.output.string).to eq([
60
+ "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
61
+ "‣ ⬡ vodka\n",
62
+ " ⬡ beer\n",
63
+ " ⬡ wine\n",
64
+ " ⬡ whisky\n",
65
+ " ⬡ bourbon\n",
66
+ "\e[1A\e[1000D\e[K" * 6,
67
+ "Select drinks? vodka\n",
68
+ "‣ \e[32m⬢\e[0m vodka\n",
69
+ " ⬡ beer\n",
70
+ " ⬡ wine\n",
71
+ " ⬡ whisky\n",
72
+ " ⬡ bourbon\n",
73
+ "\e[1A\e[1000D\e[K" * 6,
74
+ "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
75
+ ].join)
76
+ end
77
+
78
+ it "sets choice name and value through DSL" do
79
+ prompt = TTY::TestPrompt.new
80
+ prompt.input << " \r"
81
+ prompt.input.rewind
82
+ value = prompt.multi_select("Select drinks?") do |menu|
83
+ menu.choice :vodka, {score: 1}
84
+ menu.choice :beer, 2
85
+ menu.choice :wine, 3
86
+ menu.choices whisky: 4, bourbon: 5
87
+ end
88
+ expect(value).to eq([{score: 1}])
89
+ expect(prompt.output.string).to eq([
90
+ "\e[?25lSelect drinks? \e[90m(Use arrow keys, press Space to select and Enter to finish)\e[0m\n",
91
+ "‣ ⬡ vodka\n",
92
+ " ⬡ beer\n",
93
+ " ⬡ wine\n",
94
+ " ⬡ whisky\n",
95
+ " ⬡ bourbon\n",
96
+ "\e[1A\e[1000D\e[K" * 6,
97
+ "Select drinks? vodka\n",
98
+ "‣ \e[32m⬢\e[0m vodka\n",
99
+ " ⬡ beer\n",
100
+ " ⬡ wine\n",
101
+ " ⬡ whisky\n",
102
+ " ⬡ bourbon\n",
103
+ "\e[1A\e[1000D\e[K" * 6,
104
+ "Select drinks? \e[32mvodka\e[0m\n\e[?25h"
105
+ ].join)
106
+ end
107
+
108
+ it "sets default options through DSL syntax" do
109
+ prompt = TTY::TestPrompt.new
110
+ prompt.input << "\r"
111
+ prompt.input.rewind
112
+ value = prompt.multi_select("Select drinks?") do |menu|
113
+ menu.default 2, 5
114
+
115
+ menu.choice :vodka, {score: 10}
116
+ menu.choice :beer, {score: 20}
117
+ menu.choice :wine, {score: 30}
118
+ menu.choice :whisky, {score: 40}
119
+ menu.choice :bourbon, {score: 50}
120
+ end
121
+ expect(value).to match_array([{score: 20}, {score: 50}])
122
+ expect(prompt.output.string).to eq([
123
+ "\e[?25lSelect drinks? beer, bourbon\n",
124
+ " ⬡ vodka\n",
125
+ " \e[32m⬢\e[0m beer\n",
126
+ " ⬡ wine\n",
127
+ " ⬡ whisky\n",
128
+ "‣ \e[32m⬢\e[0m bourbon\n",
129
+ "\e[1A\e[1000D\e[K" * 6,
130
+ "Select drinks? \e[32mbeer, bourbon\e[0m\n\e[?25h",
131
+ ].join)
132
+ end
133
+
134
+ it "sets default options through hash syntax" do
135
+ prompt = TTY::TestPrompt.new
136
+ prompt.input << "\r"
137
+ prompt.input.rewind
138
+ value = prompt.multi_select("Select drinks?",default: [2, 5]) do |menu|
139
+ menu.choice :vodka, {score: 10}
140
+ menu.choice :beer, {score: 20}
141
+ menu.choice :wine, {score: 30}
142
+ menu.choice :whisky, {score: 40}
143
+ menu.choice :bourbon, {score: 50}
144
+ end
145
+ expect(value).to match_array([{score: 20}, {score: 50}])
146
+ end
147
+
148
+ it "raises error for defaults out of range" do
149
+ prompt = TTY::TestPrompt.new
150
+ prompt.input << "\r"
151
+ prompt.input.rewind
152
+ expect {
153
+ prompt.multi_select("Select drinks?",default: [2, 6]) do |menu|
154
+ menu.choice :vodka, {score: 10}
155
+ menu.choice :beer, {score: 20}
156
+ menu.choice :wine, {score: 30}
157
+ menu.choice :whisky, {score: 40}
158
+ menu.choice :bourbon, {score: 50}
159
+ end
160
+ }.to raise_error(TTY::PromptConfigurationError,
161
+ /default index `6` out of range \(1 - 5\)/)
162
+ end
163
+ end
@@ -3,22 +3,11 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe TTY::Prompt::Question, '#character' do
6
- let(:input) { StringIO.new }
7
- let(:output) { StringIO.new }
8
- let(:prompt) { TTY::Prompt.new(input, output) }
9
-
10
6
  it 'switches to character input' do
11
- input << "abcd"
12
- input.rewind
13
- q = prompt.ask("Which one do you prefer a, b, c or d?").char(true)
14
- expect(q.character)
15
- expect(q.read_string).to eq("abcd")
16
- end
17
-
18
- it 'acts as reader without arguments' do
19
- input << "abcd"
20
- input.rewind
21
- q = prompt.ask("Which one do you prefer a, b, c or d?")
22
- expect(q.char).to eq(false)
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")
23
12
  end
24
13
  end
@@ -3,23 +3,17 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe TTY::Prompt::Question, '#default' do
6
- let(:input) { StringIO.new }
7
- let(:output) { StringIO.new }
8
- let(:prompt) { TTY::Prompt.new(input, output) }
9
-
10
6
  it 'uses default value' do
7
+ prompt = TTY::TestPrompt.new
11
8
  name = 'Anonymous'
12
- q = prompt.ask("What is your name?").default(name)
13
- answer = q.read
9
+ answer = prompt.ask('What is your name?', default: name)
14
10
  expect(answer).to eq(name)
15
11
  end
16
12
 
17
13
  it 'uses default value in block' do
14
+ prompt = TTY::TestPrompt.new
18
15
  name = 'Anonymous'
19
- q = prompt.ask "What is your name?" do
20
- default name
21
- end
22
- answer = q.read
16
+ answer = prompt.ask('What is your name?') { |q| q.default(name) }
23
17
  expect(answer).to eq(name)
24
18
  end
25
19
  end