+++ /dev/null
-require File.expand_path(File.dirname(__FILE__) + '/edgecase')
-
-class AboutMessagePassing < EdgeCase::Koan
-
- class MessageCatcher
- def caught?
- true
- end
- end
-
- def test_methods_can_be_called_directly
- mc = MessageCatcher.new
-
- assert mc.caught?
- end
-
- def test_methods_can_be_invoked_by_sending_the_message
- mc = MessageCatcher.new
-
- assert mc.send(:caught?)
- end
-
- def test_methods_can_be_invoked_more_dynamically
- mc = MessageCatcher.new
-
- assert mc.send("caught?")
- assert mc.send("caught" + __ ) # What do you need to add to the first string?
- assert mc.send("CAUGHT?".____ ) # What would you need to do to the string?
- end
-
- def test_send_with_underscores_will_also_send_messages
- mc = MessageCatcher.new
-
- assert_equal __, mc.__send__(:caught?)
-
- # THINK ABOUT IT:
- #
- # Why does Ruby provide both send and __send__ ?
- end
-
- def test_classes_can_be_asked_if_they_know_how_to_respond
- mc = MessageCatcher.new
-
- assert_equal __, mc.respond_to?(:caught?)
- assert_equal __, mc.respond_to?(:does_not_exist)
- end
-
- # ------------------------------------------------------------------
-
- class MessageCatcher
- def add_a_payload(*args)
- args
- end
- end
-
- def test_sending_a_message_with_arguments
- mc = MessageCatcher.new
-
- assert_equal __, mc.add_a_payload
- assert_equal __, mc.send(:add_a_payload)
-
- assert_equal __, mc.add_a_payload(3, 4, nil, 6)
- assert_equal __, mc.send(:add_a_payload, 3, 4, nil, 6)
- end
-
- # ------------------------------------------------------------------
-
- class TypicalObject
- end
-
- def test_sending_undefined_messages_to_a_typical_object_results_in_errors
- typical = TypicalObject.new
-
- exception = assert_raise(___) do
- typical.foobar
- end
- assert_match(/foobar/, exception.message)
- end
-
- def test_calling_method_missing_causes_the_no_method_error
- typical = TypicalObject.new
-
- exception = assert_raise(___) do
- typical.method_missing(:foobar)
- end
- assert_match(/foobar/, exception.message)
-
- # THINK ABOUT IT:
- #
- # If the method :method_missing causes the NoMethodError, then
- # what would happen if we redefine method_missing?
- #
- # NOTE:
- #
- # In Ruby 1.8 the method_missing method is public and can be
- # called as shown above. However, in Ruby 1.9 the method_missing
- # method is private. We explicitly made it public in the testing
- # framework so this example works in both versions of Ruby. Just
- # keep in mind you can't call method_missing like that in Ruby
- # 1.9. normally.
- #
- # Thanks. We now return you to your regularly scheduled Ruby
- # Koans.
- end
-
- # ------------------------------------------------------------------
-
- class AllMessageCatcher
- def method_missing(method_name, *args, &block)
- "Someone called #{method_name} with <#{args.join(", ")}>"
- end
- end
-
- def test_all_messages_are_caught
- catcher = AllMessageCatcher.new
-
- assert_equal __, catcher.foobar
- assert_equal __, catcher.foobaz(1)
- assert_equal __, catcher.sum(1,2,3,4,5,6)
- end
-
- def test_catching_messages_makes_respond_to_lie
- catcher = AllMessageCatcher.new
-
- assert_nothing_raised(NoMethodError) do
- catcher.any_method
- end
- assert_equal __, catcher.respond_to?(:any_method)
- end
-
- # ------------------------------------------------------------------
-
- class WellBehavedFooCatcher
- def method_missing(method_name, *args, &block)
- if method_name.to_s[0,3] == "foo"
- "Foo to you too"
- else
- super(method_name, *args, &block)
- end
- end
- end
-
- def test_foo_method_are_caught
- catcher = WellBehavedFooCatcher.new
-
- assert_equal __, catcher.foo_bar
- assert_equal __, catcher.foo_baz
- end
-
- def test_non_foo_messages_are_treated_normally
- catcher = WellBehavedFooCatcher.new
-
- assert_raise(___) do
- catcher.normal_undefined_method
- end
- end
-
- # ------------------------------------------------------------------
-
- # (note: just reopening class from above)
- class WellBehavedFooCatcher
- def respond_to?(method_name)
- if method_name.to_s[0,3] == "foo"
- true
- else
- super(method_name)
- end
- end
- end
-
- def test_explicitly_implementing_respond_to_lets_objects_tell_the_truth
- catcher = WellBehavedFooCatcher.new
-
- assert_equal __, catcher.respond_to?(:foo_bar)
- assert_equal __, catcher.respond_to?(:something_else)
- end
-
-end