Skip to content

Commit

Permalink
Show a message indicating what default value was returned (#2)
Browse files Browse the repository at this point in the history
* Make newlines optional

* Phew

* Here we go

* Make it output something if the question is 'skipped'

* Last updates to documentation

* Adding tests
  • Loading branch information
emmahsax authored Mar 9, 2021
1 parent 4fb74cb commit ea08d66
Show file tree
Hide file tree
Showing 13 changed files with 336 additions and 102 deletions.
195 changes: 122 additions & 73 deletions README.md

Large diffs are not rendered by default.

30 changes: 12 additions & 18 deletions lib/highline_wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ class HighlineWrapper
#
# prompt: the prompt for the question (string)
# options: various options to pass to the questions (hash)
# indicate_default_message: whether to tell the terminal what the default value selected is if the question
# is skipped (boolean - defaults to true)
# secret: whether the terminal should hide the typed value (boolean - defaults to false)
# default: the default selection (string - defaults to '')
# required: whether the question is required or not (boolean - defaults to false)
#
# Notes:
# If required == true, the question will repeat until the user answers the question
# If required == true, then the default value will be ignored
def ask(prompt, options = {})
defaults = {
indicate_default_message: true,
secret: false,
default: '',
required: false
Expand All @@ -34,14 +33,13 @@ def ask(prompt, options = {})
#
# prompt: the prompt for the question (string)
# options: various options to pass to the questions (hash)
# indicate_default_message: whether to tell the terminal what the default value selected is if the question
# is skipped (boolean - defaults to true)
# default: the default selection (boolean - defaults to true)
# required: whether the question is required or not (boolean - defaults to false)
#
# Notes:
# If required == true, the question will repeat until the user answers the question
# If required == true, then the default value will be ignored
def ask_yes_no(prompt, options = {})
defaults = {
indicate_default_message: true,
default: true,
required: false
}
Expand All @@ -56,16 +54,14 @@ def ask_yes_no(prompt, options = {})
# prompt: the prompt for the question (string)
# choices: a list of string options (array) (e.g. [ 'a', 'b', 'c' ])
# options: various options to pass to the questions (hash)
# indicate_default_message: whether to tell the terminal what the default value selected is if the question
# is skipped (boolean - defaults to true)
# with_index: whether to return the index of the selection (boolean - defaults to false)
# default: the default selection if the user skips the question (string - defaults to nil)
# required: whether the question is required or not (boolean - defaults to false)
#
# Notes:
# If required == true, the question will repeat until the user answers the question
# If required == true, then the default value will be ignored
# If default == nil and required == false, and the user skips the question, the answer will be nil
def ask_multiple_choice(prompt, choices, options = {})
defaults = {
indicate_default_message: true,
with_index: false,
default: nil,
required: false
Expand All @@ -81,16 +77,14 @@ def ask_multiple_choice(prompt, choices, options = {})
# prompt: the prompt for the question (string)
# choices: a list of string options (array) (e.g. [ 'a', 'b', 'c' ])
# options: various options to pass to the questions (hash)
# indicate_default_message: whether to tell the terminal what the default value selected is if the question
# is skipped (boolean - defaults to true)
# with_indexes: whether to return the indexes of the selections (boolean - defaults to false)
# defaults: the default selections if the user skips the question (array - defaults to [])
# required: whether the question is required or not (boolean - defaults to false)
#
# Notes:
# If required == true, the question will repeat until the user answers the question
# If required == true, then the defaults value will be ignored
# If defaults == [] and required == false, then the method will return an empty array
def ask_checkbox(prompt, choices, options = {})
defaults = {
indicate_default_message: true,
with_indexes: false,
defaults: [],
required: false
Expand Down
16 changes: 13 additions & 3 deletions lib/highline_wrapper/checkbox_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@ class CheckboxQuestion < Question
class << self
def ask(prompt, choices, options)
indices = ask_highline(format_options(prompt, choices))
puts

return format_multiple_selections(choices, indices, options[:with_indexes]) unless indices.empty?
return recurse(prompt, choices, options) if options[:required]
return options[:defaults] if options[:defaults].empty?
return return_empty_defaults(options) if options[:defaults].empty?

format_multiple_selections(choices, options[:defaults].map { |d| choices.index(d) }, options[:with_indexes])
return_defaults(choices, options)
end

private def ask_highline(prompt)
Expand All @@ -22,6 +21,17 @@ def ask(prompt, choices, options)
indices
end

private def return_defaults(choices, options)
options[:default_indexes] = options[:defaults].map { |d| choices.index(d) }
print_default_message(options, choices) if options[:indicate_default_message]
format_multiple_selections(choices, options[:default_indexes], options[:with_indexes])
end

private def print_default_message(options, choices)
defaults = options[:default_indexes].map { |i| "#{i + 1}. #{choices[i]}".strip }.join(', ')
puts "--- Defaults selected: #{defaults} ---"
end

private def format_multiple_selections(choices, indices, with_indexes)
selected = []
indices.each { |index| selected << format_selection(choices, index, with_indexes) }
Expand Down
15 changes: 12 additions & 3 deletions lib/highline_wrapper/multiple_choice_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@ class MultipleChoiceQuestion < Question
class << self
def ask(prompt, choices, options)
index = ask_highline(format_options(prompt, choices)).to_i - 1
puts

return format_selection(choices, index, options[:with_index]) unless index == -1
return recurse(prompt, choices, options) if options[:required]
return nil if options[:default].nil?
return return_empty_defaults(options) if options[:default].nil?

format_selection(choices, choices.index(options[:default]), options[:with_index])
return_defaults(choices, options)
end

private def return_defaults(choices, options)
options[:default_index] = choices.index(options[:default])
print_default_message(options) if options[:indicate_default_message]
format_selection(choices, options[:default_index], options[:with_index])
end

private def print_default_message(options)
puts "--- Default selected: #{options[:default_index] + 1}. #{options[:default]} ---"
end
end
end
Expand Down
10 changes: 9 additions & 1 deletion lib/highline_wrapper/open_ended_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ class OpenEndedQuestion < Question
class << self
def ask(prompt, options)
answer = ask_highline(prompt, secret: options[:secret]).to_s
puts unless answer.empty? && options[:secret]

return answer unless answer.empty?
return recurse(prompt, nil, options) if options[:required]

print_default_message(options) if options[:indicate_default_message]
options[:default]
end

private def print_default_message(options)
if !options[:secret]
puts "--- Default selected: #{options[:default].empty? ? 'EMPTY' : options[:default]} ---"
elsif options[:secret]
puts '--- Default selected: HIDDEN ---'
end
end
end
end
end
7 changes: 6 additions & 1 deletion lib/highline_wrapper/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@ def format_selection(choices, index, with_index)
end

def recurse(prompt, choices, options)
puts "This question is required.\n\n"
puts '--- This question is required ---'
choices.nil? ? ask(prompt, options) : ask(prompt, choices, options)
end

def return_empty_defaults(options)
puts '--- Default selected: EMPTY ---' if options[:indicate_default_message]
options[:defaults] || options[:default]
end

private def highline
@highline ||= HighLine.new
end
Expand Down
2 changes: 1 addition & 1 deletion lib/highline_wrapper/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

class HighlineWrapper
VERSION = '1.0.0'
VERSION = '1.1.0'
end
8 changes: 6 additions & 2 deletions lib/highline_wrapper/yes_no_question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,24 @@ class YesNoQuestion < Question
class << self
def ask(prompt, options)
answer = ask_highline(prompt).to_s.downcase
puts

return parse(answer, prompt, options) unless answer.empty?
return recurse(prompt, nil, options) if options[:required]

print_default_message(options) if options[:indicate_default_message]
options[:default]
end

def parse(answer, prompt, options)
private def parse(answer, prompt, options)
return true if answer.include?('y')
return false if answer.include?('n')

recurse(prompt, nil, options)
end

private def print_default_message(options)
puts "--- Default selected: #{options[:default] ? 'YES' : 'NO'} ---"
end
end
end
end
38 changes: 38 additions & 0 deletions spec/highline_wrapper/checkbox_question_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq([])
end

it 'should call the return empty defaults if the user skips' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:return_empty_defaults)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end

context 'with required set to true' do
Expand Down Expand Up @@ -97,6 +103,7 @@
context 'with defaults set' do
let(:options) do
{
indicate_default_message: true,
with_indexes: false,
defaults: ['two'],
required: false
Expand All @@ -114,6 +121,31 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq([{ value: 'two' }])
end

it 'should call to return the defaults if the user skips' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:return_defaults).and_call_original
expect(subject).to receive(:puts)
subject.ask(Faker::Lorem.sentence, choices, options)
end

context 'when the indicate_default_message is false' do
let(:options) do
{
indicate_default_message: false,
with_indexes: false,
defaults: ['two'],
required: false
}
end

it 'should call to return the defaults if the user skips' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:return_defaults)
expect(subject).not_to receive(:puts)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end
end

context 'with defaults set to []' do
Expand Down Expand Up @@ -182,6 +214,12 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq([])
end

it 'should call the return empty defaults message' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:return_empty_defaults)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end
end
end
Expand Down
38 changes: 38 additions & 0 deletions spec/highline_wrapper/multiple_choice_question_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq(nil)
end

it 'should call the return empty defaults if the user skips' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:return_empty_defaults)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end

context 'with required set to true' do
Expand Down Expand Up @@ -97,6 +103,7 @@
context 'with default set' do
let(:options) do
{
indicate_default_message: true,
with_index: false,
default: 'two',
required: false
Expand All @@ -114,6 +121,31 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq({ value: 'two' })
end

it 'should call to return the defaults if the user skips' do
allow(highline).to receive(:ask).and_return(0)
expect(subject).to receive(:return_defaults).and_call_original
expect(subject).to receive(:puts)
subject.ask(Faker::Lorem.sentence, choices, options)
end

context 'when the indicate_default_message is false' do
let(:options) do
{
indicate_default_message: false,
with_indexes: false,
default: 'two',
required: false
}
end

it 'should call to return the defaults if the user skips' do
allow(highline).to receive(:ask).and_return(0)
expect(subject).to receive(:return_defaults)
expect(subject).not_to receive(:puts)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end
end

context 'with default nil' do
Expand Down Expand Up @@ -182,6 +214,12 @@
resp = subject.ask(Faker::Lorem.sentence, choices, options)
expect(resp).to eq(nil)
end

it 'should call the return empty defaults message' do
allow(highline).to receive(:ask).and_return(0)
expect(subject).to receive(:return_empty_defaults)
subject.ask(Faker::Lorem.sentence, choices, options)
end
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions spec/highline_wrapper/open_ended_question_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
context 'with the options as defaults' do
let(:options) do
{
indicate_default_message: true,
secret: false,
default: '',
required: false
Expand All @@ -44,6 +45,12 @@
resp = subject.ask(Faker::Lorem.sentence, options)
expect(resp).to eq('')
end

it 'should call to print the default message' do
allow(highline).to receive(:ask).and_return('')
expect(subject).to receive(:print_default_message)
subject.ask(Faker::Lorem.sentence, options)
end
end

context 'with required set to true' do
Expand Down Expand Up @@ -73,6 +80,7 @@
let(:default_string) { Faker::Lorem.sentence }
let(:options) do
{
indicate_default_message: false,
secret: false,
default: default_string,
required: false
Expand All @@ -90,5 +98,11 @@
allow(highline).to receive(:ask).and_return('')
expect(subject.ask(Faker::Lorem.sentence, options)).to eq(default_string)
end

it 'should not call to print the default message' do
allow(highline).to receive(:ask).and_return('')
expect(subject).not_to receive(:print_default_message)
subject.ask(Faker::Lorem.sentence, options)
end
end
end
Loading

0 comments on commit ea08d66

Please sign in to comment.