Skip to content

Instantly share code, notes, and snippets.

@fnando
Created January 28, 2011 01:52
Show Gist options
  • Select an option

  • Save fnando/799673 to your computer and use it in GitHub Desktop.

Select an option

Save fnando/799673 to your computer and use it in GitHub Desktop.
class Question
CHARS = ("a".."z").to_a
attr_accessor :description
attr_writer :right_answer, :chosen_answer
[:right_answer, :chosen_answer].each do |name|
class_eval <<-RUBY
def #{name}(*args)
@#{name} = args.first if args.any?
@#{name}
end
RUBY
end
def initialize(description = nil)
@description = description
end
def alternatives
@alternatives ||= []
end
def alternative(description)
alternatives << description
end
def shuffle!
@alternatives.shuffle!
end
def to_s
String.new.tap do |s|
s << description << "\n"
s << alternatives.each_with_index.collect {|a, i| build_alternative(i)}.join
end
end
def right?
right_answer && chosen_answer && right_answer == chosen_answer
end
private
def build_alternative(index)
String.new.tap do |s|
s << CHARS[index] << ") " << alternatives[index].to_s
s << " √" if chosen_answer == alternatives[index] && right?
s << "\n"
end
end
end
def Question(description, &block)
Question.new(description).tap do |question|
question.instance_eval(&block)
end
end
if $0 == __FILE__
require "mocha"
require "test/unit"
class QuestionTest < Test::Unit::TestCase
def setup
@question = Question.new("2 + 2?")
end
def test_set_description_from_initializer
assert_equal "My question", Question.new("My question").description
end
def test_set_right_answer
@question.right_answer = "Right answer"
assert_equal "Right answer", @question.right_answer
@question.right_answer("Correct answer")
assert_equal "Correct answer", @question.right_answer
end
def test_set_chosen_answer
@question.chosen_answer = "My answer"
assert_equal "My answer", @question.chosen_answer
@question.chosen_answer("Chosen answer")
assert_equal "Chosen answer", @question.chosen_answer
end
def test_set_new_alternative
@question.alternative 1
@question.alternative 2
@question.alternative 3
assert_equal 3, @question.alternatives.size
assert_equal 1, @question.alternatives[0]
assert_equal 2, @question.alternatives[1]
assert_equal 3, @question.alternatives[2]
end
def test_shuffle_alternatives
@question.alternatives.expects(:shuffle!).once
@question.shuffle!
end
def test_readable_question
@question.alternative(4)
@question.alternative(5)
@question.alternative("I'm not into that Math thing")
str = @question.to_s
assert_match /2 \+ 2\?\n/, str
assert_match /[a-c]\) 4\n/, str
assert_match /[a-c]\) 5\n/, str
assert_match /[a-c]\) I'm not into that Math thing\n/, str
end
def test_mark_write_answer
@question.alternative(4)
@question.alternative(5)
@question.alternative(6)
@question.chosen_answer(4)
@question.right_answer(4)
assert_match /[a-z]\) 4 √/u, @question.to_s
assert_no_match /5 √/, @question.to_s
assert_no_match /6 √/, @question.to_s
end
def test_right_question
@question.chosen_answer(4)
@question.right_answer(4)
assert @question.right?
end
def test_wrong_question
@question.chosen_answer(4)
@question.right_answer(6)
assert !@question.right?
end
def test_dsl_method
question = Question("2 + 2?") do
alternative 4
alternative 5
alternative 6
right_answer 4
chosen_answer 7
end
assert_equal "2 + 2?", question.description
assert_equal 4, question.right_answer
assert_equal 7, question.chosen_answer
assert_equal [4,5,6], question.alternatives
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment