Class: QandA::Question::MultipleChoice

Inherits:
Question
  • Object
show all
Defined in:
lib/question/multiple_choice.rb

Constant Summary collapse

NOT_ENOUGH_OPTIONS_ERR =
'A multiple-choice question must have an array with at least two elements.'
DEFAULT_IS_INTEGER_ERR =
'A multiple-choice default must be a valid index for its array of choices.'
MINIMUM_NO_ZERO_ERR =
'A multiple-choice minimum cannot be zero, negative, or greater than the choice count.'
MAXIMUM_NO_ZERO_ERR =
'A multiple-choice maximum cannot be zero, negative, or greater than/equal to the choice count.'
MIN_GREATER_THAN_MAX =
'A multiple-choice minimum cannot be greater than the maximum.'

Instance Method Summary collapse

Constructor Details

#initialize(choices, message = '', default = nil, minimum = 1, maximum = nil) ⇒ MultipleChoice

Returns a new instance of MultipleChoice.



10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/question/multiple_choice.rb', line 10

def initialize(choices, message = '', default = nil, minimum = 1, maximum = nil)
  @maximum = maximum.nil? ? minimum : maximum
  @minimum = minimum
  @choices    = choices
  raise InvalidQuestionError.new(NOT_ENOUGH_OPTIONS_ERR) unless choices.is_a?(Array) && choices.size > 1
  raise InvalidQuestionError.new(DEFAULT_IS_INTEGER_ERR) unless default.nil? || answer_string_is_valid?(default)
  raise InvalidQuestionError.new(MAXIMUM_NO_ZERO_ERR) unless @minimum > 0 && @maximum <= choices.size
  raise InvalidQuestionError.new(MINIMUM_NO_ZERO_ERR) unless @maximum > 0 && @minimum <= choices.size - 1
  raise InvalidQuestionError.new(MIN_GREATER_THAN_MAX) unless @maximum >= @minimum
  super(message: message, default: default)
  @validation = Proc.new { |answer| answer_string_is_valid?(answer) }
end

Instance Method Details

#answerObject



60
61
62
63
64
65
66
# File 'lib/question/multiple_choice.rb', line 60

def answer
  arr = []
  @answer.each do |i|
    arr << @choices[i].to_s
  end
  arr
end

#answer_string_is_valid?(answer) ⇒ Boolean

Returns:



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/question/multiple_choice.rb', line 23

def answer_string_is_valid?(answer)
  answer = answer.to_s.split(',').map { |i| i.strip }
  valid  = true
  valid  = false if answer.length > @maximum
  valid  = false if answer.length < @minimum
  if valid
    answer.each do |answer|
      unless answer.to_i.to_s == answer && @choices.size > answer.to_i - 1
        valid = false
        break
      end
    end
  end
  valid
end

#askObject



50
51
52
53
54
55
56
57
58
# File 'lib/question/multiple_choice.rb', line 50

def ask
  super do
    prompt
    @choices.each_with_index do |c, i|
      puts "[#{i+1}] #{c}"
    end
  end
  @answer = [*@answer.to_s.split(',').map { |i| i.strip.to_i - 1 }]
end

#promptObject



39
40
41
42
43
44
45
46
47
48
# File 'lib/question/multiple_choice.rb', line 39

def prompt
  puts "\n"
  if @maximum == 1
    puts "Select only one answer:"
  elsif @maximum == @minimum
    puts "Select exactly #{@maximum} answers, separated by commas:"
  else
    puts "Select between #{@minimum} and #{@maximum} answers, separated by commas:"
  end
end