1666e4596553d025e0e3cdaddec62ec3ebf806d4
[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     assert tv.instance_of?(Proxy)
32   end
33   
34   def test_tv_methods_still_perform_their_function
35     tv = Proxy.new(Television.new)
36
37     # HINT Proxy class is defined above, may need tweaking...
38     tv.channel = 10
39     tv.power
40     
41     assert_equal 10, tv.channel
42     assert tv.on?
43   end
44
45   def test_proxy_records_messages_sent_to_tv
46     tv = Proxy.new(Television.new)
47     
48     tv.power
49     tv.channel = 10
50     
51     assert_equal [:power, :channel=], tv.messages
52   end
53   
54   def test_proxy_handles_invalid_messages
55     tv = Proxy.new(Television.new)
56     
57     assert_raise(NoMethodError) do
58       tv.no_such_method
59     end
60   end
61   
62   def test_proxy_reports_methods_have_been_called
63     tv = Proxy.new(Television.new)
64     
65     tv.power
66     tv.power
67     
68     assert tv.called?(:power)
69     assert ! tv.called?(:channel)
70   end
71   
72   def test_proxy_counts_method_calls
73     tv = Proxy.new(Television.new)
74     
75     tv.power
76     tv.channel = 48
77     tv.power
78
79     assert_equal 2, tv.number_of_times_called(:power)
80     assert_equal 1, tv.number_of_times_called(:channel=)
81     assert_equal 0, tv.number_of_times_called(:on?)
82   end
83
84   def test_proxy_can_record_more_than_just_tv_objects
85     proxy = Proxy.new("Code Mash 2009")
86
87     proxy.upcase!
88     result = proxy.split
89
90     assert_equal ["CODE", "MASH", "2009"], result
91     assert_equal [:upcase!, :split], proxy.messages
92   end
93 end
94
95
96 # ====================================================================
97 # The following code is to support the testing of the Proxy class.  No
98 # changes should be necessary to anything below this comment.
99
100 # Example class using in the proxy testing above.
101 class Television
102   attr_accessor :channel
103   
104   def power
105     if @power == :on
106       @power = :off
107     else
108       @power = :on
109     end
110   end
111   
112   def on?
113     @power == :on
114   end
115 end
116
117 # Tests for the Television class.  All of theses tests should pass.
118 class TelevisionTest < EdgeCase::Koan
119   def test_it_turns_on
120     tv = Television.new
121     
122     tv.power
123     assert tv.on?
124   end
125   
126   def test_it_also_turns_off
127     tv = Television.new
128     
129     tv.power
130     tv.power
131     
132     assert ! tv.on?
133   end
134   
135   def test_edge_case_on_off
136     tv = Television.new
137     
138     tv.power
139     tv.power
140     tv.power
141         
142     assert tv.on?
143     
144     tv.power
145     
146     assert ! tv.on?
147   end
148
149   def test_can_set_the_channel
150     tv = Television.new
151
152     tv.channel = 11
153     assert_equal 11, tv.channel
154   end
155 end