Back ported a lot of changes made to the Koans directory.
[ruby_koans.git] / koans / about_proxy_object_project.rb
1 require File.expand_path(File.dirname(__FILE__) + '/edgecase')
2
3 # Project: Create a Proxy Class
4 #
5 # In this assignment, create a proxy class (one is started for you
6 # below).  You should be able to initialize the proxy object with any
7 # object.  Any messages sent to the proxy object should be forwarded
8 # to the target object.  As each message is sent, the proxy should
9 # record the name of the method sent.
10 #
11 # The proxy class is started for you.  You will need to add a method
12 # missing handler and any other supporting methods.  The specification
13 # of the Proxy class is given in the AboutProxyObjectProject koan.
14
15 class Proxy
16   def initialize(target_object)
17     @object = target_object
18     # ADD MORE CODE HERE
19   end
20
21   # WRITE CODE HERE
22 end
23
24 # The proxy object should pass the following Koan:
25 #
26 class AboutProxyObjectProject < EdgeCase::Koan
27   def test_proxy_method_returns_wrapped_object
28     # NOTE: The Television class is defined below
29     tv = Proxy.new(Television.new)
30
31     # HINT: Proxy class is defined above, may need tweaking...
32
33     assert tv.instance_of?(Proxy)
34   end
35
36   def test_tv_methods_still_perform_their_function
37     tv = Proxy.new(Television.new)
38
39     tv.channel = 10
40     tv.power
41
42     assert_equal 10, tv.channel
43     assert tv.on?
44   end
45
46   def test_proxy_records_messages_sent_to_tv
47     tv = Proxy.new(Television.new)
48
49     tv.power
50     tv.channel = 10
51
52     assert_equal [:power, :channel=], tv.messages
53   end
54
55   def test_proxy_handles_invalid_messages
56     tv = Proxy.new(Television.new)
57
58     assert_raise(NoMethodError) do
59       tv.no_such_method
60     end
61   end
62
63   def test_proxy_reports_methods_have_been_called
64     tv = Proxy.new(Television.new)
65
66     tv.power
67     tv.power
68
69     assert tv.called?(:power)
70     assert ! tv.called?(:channel)
71   end
72
73   def test_proxy_counts_method_calls
74     tv = Proxy.new(Television.new)
75
76     tv.power
77     tv.channel = 48
78     tv.power
79
80     assert_equal 2, tv.number_of_times_called(:power)
81     assert_equal 1, tv.number_of_times_called(:channel=)
82     assert_equal 0, tv.number_of_times_called(:on?)
83   end
84
85   def test_proxy_can_record_more_than_just_tv_objects
86     proxy = Proxy.new("Code Mash 2009")
87
88     proxy.upcase!
89     result = proxy.split
90
91     assert_equal ["CODE", "MASH", "2009"], result
92     assert_equal [:upcase!, :split], proxy.messages
93   end
94 end
95
96
97 # ====================================================================
98 # The following code is to support the testing of the Proxy class.  No
99 # changes should be necessary to anything below this comment.
100
101 # Example class using in the proxy testing above.
102 class Television
103   attr_accessor :channel
104
105   def power
106     if @power == :on
107       @power = :off
108     else
109       @power = :on
110     end
111   end
112
113   def on?
114     @power == :on
115   end
116 end
117
118 # Tests for the Television class.  All of theses tests should pass.
119 class TelevisionTest < EdgeCase::Koan
120   def test_it_turns_on
121     tv = Television.new
122
123     tv.power
124     assert tv.on?
125   end
126
127   def test_it_also_turns_off
128     tv = Television.new
129
130     tv.power
131     tv.power
132
133     assert ! tv.on?
134   end
135
136   def test_edge_case_on_off
137     tv = Television.new
138
139     tv.power
140     tv.power
141     tv.power
142
143     assert tv.on?
144
145     tv.power
146
147     assert ! tv.on?
148   end
149
150   def test_can_set_the_channel
151     tv = Television.new
152
153     tv.channel = 11
154     assert_equal 11, tv.channel
155   end
156 end