summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatrinox <geofflee21@me.com>2016-01-24 21:06:56 -0800
committerAbinoam Praxedes Marques Jr <abinoam@gmail.com>2016-02-19 03:57:18 -0300
commit08f7451a9554df8ca2a165c153011844ad46f9e0 (patch)
treecc794da112e75bf38fb61d6faa9db273926c5468
parentdb74d876215d9ba1ac82ea21d38475fb27e1677c (diff)
downloadhighline-08f7451a9554df8ca2a165c153011844ad46f9e0.tar.gz
Fix bug with responses hash not updating with each additional menu choice
Originally, build_responses gave precedence to new hash (which makes sense) but then old hash was given precedence because it allowed the user to set things and let that stick Instead, the solution should be to split the concerns: one hash for user one hash for internal. The hashes are then merged when outputting, giving the user responses precedence This does have the side effect of taking away responses reflection on the side of the client but that is easily added in build_responses
-rwxr-xr-xlib/highline.rb2
-rwxr-xr-xlib/highline/question.rb36
-rw-r--r--lib/highline/question_asker.rb2
-rw-r--r--test/test_menu.rb20
4 files changed, 45 insertions, 15 deletions
diff --git a/lib/highline.rb b/lib/highline.rb
index ba409b6..0ef2b57 100755
--- a/lib/highline.rb
+++ b/lib/highline.rb
@@ -485,7 +485,7 @@ class HighLine
# of the question.
#
def explain_error(error, question)
- say(question.responses[error]) if error
+ say(question.final_responses[error]) if error
say(question.ask_on_error_msg)
end
diff --git a/lib/highline/question.rb b/lib/highline/question.rb
index 769da39..3724c67 100755
--- a/lib/highline/question.rb
+++ b/lib/highline/question.rb
@@ -61,7 +61,8 @@ class HighLine
@first_answer = nil
@directory = Pathname.new(File.expand_path(File.dirname($0)))
@glob = "*"
- @responses = Hash.new
+ @user_responses = Hash.new
+ @internal_responses = default_responses_hash
@overwrite = false
# allow block to override settings
@@ -214,7 +215,9 @@ class HighLine
# <tt>:not_valid</tt>:: The error message shown when
# validation checks fail.
#
- attr_reader :responses
+ def responses
+ @user_responses
+ end
#
# When set to +true+ the question is asked, but output does not progress to
# the next line. The Cursor is moved back to the beginning of the question
@@ -242,16 +245,21 @@ class HighLine
# @return [Hash] responses Hash winner (new and old merge).
# @param message_source [Class] Array or String for example.
# Same as {#answer_type}.
- # @param new_hash_wins [Boolean] merge precedence (new vs. old).
- def build_responses(message_source = answer_type, new_hash_wins = false)
+ def build_responses(message_source = answer_type)
append_default if [::String, Symbol].include? default.class
- old_hash = responses
-
new_hash = build_responses_new_hash(message_source)
+ # Update our internal responses with the new hash
+ # generated from the message source
+ @internal_responses = @internal_responses.merge(new_hash)
+ end
- @responses = new_hash_wins ? old_hash.merge(new_hash) : new_hash.merge(old_hash)
+ def default_responses_hash
+ {
+ :ask_on_error => "? ",
+ :mismatch => "Your entries didn't match."
+ }
end
# When updating the responses hash, it generates the new one.
@@ -260,17 +268,21 @@ class HighLine
def build_responses_new_hash(message_source)
{ :ambiguous_completion => "Ambiguous choice. Please choose one of " +
choice_error_str(message_source) + '.',
- :ask_on_error => "? ",
:invalid_type => "You must enter a valid #{message_source}.",
:no_completion => "You must choose one of " +
choice_error_str(message_source) + '.',
:not_in_range => "Your answer isn't within the expected range " +
"(#{expected_range}).",
- :mismatch => "Your entries didn't match.",
:not_valid => "Your answer isn't valid (must match " +
"#{validate.inspect})." }
end
+ # This is the actual responses hash that gets used in determining output
+ # Notice that we give @user_responses precedence over the responses
+ # generated internally via build_response
+ def final_responses
+ @internal_responses.merge(@user_responses)
+ end
#
# Returns the provided _answer_string_ after changing character case by
@@ -531,10 +543,10 @@ class HighLine
# @return [self] if :ask_on_error on responses Hash is set to :question
# @return [String] if :ask_on_error on responses Hash is set to something else
def ask_on_error_msg
- if responses[:ask_on_error] == :question
+ if final_responses[:ask_on_error] == :question
self
- elsif responses[:ask_on_error]
- responses[:ask_on_error]
+ elsif final_responses[:ask_on_error]
+ final_responses[:ask_on_error]
end
end
diff --git a/lib/highline/question_asker.rb b/lib/highline/question_asker.rb
index b8c8ebc..bb10c9e 100644
--- a/lib/highline/question_asker.rb
+++ b/lib/highline/question_asker.rb
@@ -119,7 +119,7 @@ class HighLine
## Delegate to Highline
def explain_error(error)
- @highline.say(question.responses[error]) if error
+ @highline.say(question.final_responses[error]) if error
@highline.say(question.ask_on_error_msg)
end
diff --git a/test/test_menu.rb b/test/test_menu.rb
index 1a53f28..2bcd824 100644
--- a/test/test_menu.rb
+++ b/test/test_menu.rb
@@ -440,7 +440,6 @@ class TestMenu < Minitest::Test
assert_equal(selected, 3)
end
-
def test_cancel_paging
# Tests that paging can be cancelled halfway through
@terminal.page_at = 5
@@ -460,6 +459,25 @@ class TestMenu < Minitest::Test
"Paging message appeared more than once." )
end
+ def test_autocomplete_prompt
+ @input << "lisp\nRuby\n"
+ @input.rewind
+
+ answer = @terminal.choose do |menu|
+ menu.choice(:Perl)
+ menu.choice(:Python)
+ menu.choice(:Ruby)
+ menu.prompt = "What is your favorite programming language? "
+ end
+ languages = [:Perl, :Python, :Ruby]
+ assert_equal("1. Perl\n" +
+ "2. Python\n" +
+ "3. Ruby\n" +
+ "What is your favorite programming language? " +
+ "You must choose one of [1, 2, 3, Perl, Python, Ruby].\n" +
+ "? ", @output.string )
+ end
+
# Issue #180 - https://github.com/JEG2/highline/issues/180
def test_menu_prompt
@input << "2\n1\n"