Skip to content

Commit

Permalink
Change yes? and no? to allow for more flexible options in reference t…
Browse files Browse the repository at this point in the history
…o issue #11
  • Loading branch information
piotrmurach committed Mar 25, 2016
1 parent 6c3a52d commit fc4a8c3
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 8 deletions.
4 changes: 2 additions & 2 deletions lib/tty/prompt.rb
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ def invoke_select(object, question, *args, &block)
#
# @api public
def yes?(message, *args, &block)
defaults = { suffix: 'Y/n', default: true }
defaults = { default: true }
options = Utils.extract_options!(args)
options.merge!(defaults.reject { |k, _| options.key?(k) })

Expand All @@ -250,7 +250,7 @@ def yes?(message, *args, &block)
#
# @api public
def no?(message, *args, &block)
defaults = { suffix: 'y/N', default: false }
defaults = { default: false, type: :no }
options = Utils.extract_options!(args)
options.merge!(defaults.reject { |k, _| options.key?(k) })

Expand Down
87 changes: 83 additions & 4 deletions lib/tty/prompt/confirm_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,23 @@ class ConfirmQuestion < Question
# @api public
def initialize(prompt, options = {})
super
@convert = options.fetch(:convert) { :bool }
@suffix = options.fetch(:suffix) { 'Y/n' }
@positive = options.fetch(:positive) { 'Yes' }
@negative = options.fetch(:negative) { 'No' }

@suffix = options.fetch(:suffix) { UndefinedSetting }
@positive = options.fetch(:positive) { UndefinedSetting }
@negative = options.fetch(:negative) { UndefinedSetting }
@type = options.fetch(:type) { :yes }
end

def positive?
@positive != UndefinedSetting
end

def negative?
@negative != UndefinedSetting
end

def suffix?
@suffix != UndefinedSetting
end

# Set question suffix
Expand All @@ -40,6 +53,14 @@ def negative(value)
@negative = value
end

def call(message, &block)
return if Utils.blank?(message)
@message = message
block.call(self) if block
setup_defaults
render
end

# Render confirmation question
#
# @api private
Expand All @@ -56,6 +77,64 @@ def render_question
@prompt.print(header)
@prompt.print("\n") if @done
end

protected

# @api private
def is?(type)
@type == type
end

# @api private
def setup_defaults
return if suffix? && positive?

if suffix? && !positive?
parts = @suffix.split('/')
@positive = parts[0]
@negative = parts[1]
@convert = conversion
elsif !suffix? && positive?
@suffix = create_suffix
@convert = conversion
else
create_default_labels
@convert = :bool
end
end

def create_default_labels
if is?(:yes)
@suffix = default? ? 'Y/n' : 'y/N'
@positive = default? ? 'Yes' : 'yes'
@negative = default? ? 'no' : 'No'
else
@suffix = default? ? 'y/N' : 'Y/n'
@positive = default? ? 'Yes' : 'yes'
@negative = default? ? 'No' : 'no'
end
end

# @api private
def create_suffix
result = ''
if is?(:yes)
result << "#{default? ? @positive.capitalize : @positive.downcase}"
result << '/'
result << "#{default? ? @negative.downcase : @negative.capitalize}"
else
result << "#{default? ? @positive.downcase : @positive.capitalize}"
result << '/'
result << "#{default? ? @negative.capitalize : @negative.downcase}"
end
end

# Create custom conversion
#
# @api private
def conversion
proc { |input| !input.match(/^#{@positive}|#{@positive[0]}$/i).nil? }
end
end # ConfirmQuestion
end # Prompt
end # TTY
51 changes: 49 additions & 2 deletions spec/unit/yes_no_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"Are you a human? \e[90m(Y/n)\e[0m ",
"\e[1000D\e[K\e[1A",
"\e[1000D\e[K",
"Are you a human? \e[32mNo\e[0m\n"
"Are you a human? \e[32mno\e[0m\n"
].join)
end

Expand All @@ -49,7 +49,38 @@
"Are you a human? \e[90m(Y/n)\e[0m ",
"\e[1000D\e[K\e[1A",
"\e[1000D\e[K",
"Are you a human? \e[32mNo\e[0m\n"
"Are you a human? \e[32mno\e[0m\n"
].join)
end

it "defaults suffix and converter" do
prompt.input << "Nope\n"
prompt.input.rewind
result = prompt.yes?("Are you a human?") do |q|
q.positive 'Yup'
q.negative 'nope'
end
expect(result).to eq(false)
expect(prompt.output.string).to eq([
"Are you a human? \e[90m(Yup/nope)\e[0m ",
"\e[1000D\e[K\e[1A",
"\e[1000D\e[K",
"Are you a human? \e[32mnope\e[0m\n"
].join)
end

it "defaults positive and negative" do
prompt.input << "Nope\n"
prompt.input.rewind
result = prompt.yes?("Are you a human?") do |q|
q.suffix 'Yup/nope'
end
expect(result).to eq(false)
expect(prompt.output.string).to eq([
"Are you a human? \e[90m(Yup/nope)\e[0m ",
"\e[1000D\e[K\e[1A",
"\e[1000D\e[K",
"Are you a human? \e[32mnope\e[0m\n"
].join)
end

Expand Down Expand Up @@ -136,6 +167,22 @@
].join)
end

it "defaults suffix and converter" do
prompt.input << "Yup\n"
prompt.input.rewind
result = prompt.no?("Are you a human?") do |q|
q.positive 'yup'
q.negative 'Nope'
end
expect(result).to eq(false)
expect(prompt.output.string).to eq([
"Are you a human? \e[90m(yup/Nope)\e[0m ",
"\e[1000D\e[K\e[1A",
"\e[1000D\e[K",
"Are you a human? \e[32myup\e[0m\n"
].join)
end

it "customizes question through DSL" do
prompt.input << "agree\r"
prompt.input.rewind
Expand Down

0 comments on commit fc4a8c3

Please sign in to comment.