omghax-test_rails 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,5 @@
1
+ === 1.0.0 / 2009-03-12
2
+
3
+ * 1 major enhancement:
4
+
5
+ * Extracted test-rails from ZenTest 3.11.1 into a separate gem.
data/Manifest.txt ADDED
@@ -0,0 +1,21 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ lib/test/rails.rb
6
+ lib/test/rails/controller_test_case.rb
7
+ lib/test/rails/functional_test_case.rb
8
+ lib/test/rails/helper_test_case.rb
9
+ lib/test/rails/ivar_proxy.rb
10
+ lib/test/rails/pp_html_document.rb
11
+ lib/test/rails/rake_tasks.rb
12
+ lib/test/rails/render_tree.rb
13
+ lib/test/rails/test_case.rb
14
+ lib/test/rails/version.rb
15
+ lib/test/rails/view_test_case.rb
16
+ lib/test/zentest_assertions.rb
17
+ test/test_help.rb
18
+ test/test_rails_controller_test_case.rb
19
+ test/test_rails_helper_test_case.rb
20
+ test/test_rails_view_test_case.rb
21
+ test/test_zentest_assertions.rb
data/README.txt ADDED
@@ -0,0 +1,110 @@
1
+ = ZenTest
2
+
3
+ * http://www.zenspider.com/ZSS/Products/ZenTest/
4
+ * http://rubyforge.org/projects/zentest/
5
+ * mailto:ryand-ruby@zenspider.com
6
+
7
+ == DESCRIPTION
8
+
9
+ ZenTest provides 4 different tools and 1 library: zentest, unit_diff,
10
+ autotest, multiruby, and Test::Rails.
11
+
12
+ ZenTest scans your target and unit-test code and writes your missing
13
+ code based on simple naming rules, enabling XP at a much quicker
14
+ pace. ZenTest only works with Ruby and Test::Unit.
15
+
16
+ unit_diff is a command-line filter to diff expected results from
17
+ actual results and allow you to quickly see exactly what is wrong.
18
+
19
+ autotest is a continous testing facility meant to be used during
20
+ development. As soon as you save a file, autotest will run the
21
+ corresponding dependent tests.
22
+
23
+ multiruby runs anything you want on multiple versions of ruby. Great
24
+ for compatibility checking! Use multiruby_setup to manage your
25
+ installed versions.
26
+
27
+ Test::Rails helps you build industrial-strength Rails code.
28
+
29
+ == STRATEGERY
30
+
31
+ There are two strategeries intended for ZenTest: test conformance
32
+ auditing and rapid XP.
33
+
34
+ For auditing, ZenTest provides an excellent means of finding methods
35
+ that have slipped through the testing process. I've run it against my
36
+ own software and found I missed a lot in a well tested
37
+ package. Writing those tests found 4 bugs I had no idea existed.
38
+
39
+ ZenTest can also be used to evaluate generated code and execute your
40
+ tests, allowing for very rapid development of both tests and
41
+ implementation.
42
+
43
+ == FEATURES
44
+
45
+ * Scans your ruby code and tests and generates missing methods for you.
46
+ * Includes a very helpful filter for Test::Unit output called unit_diff.
47
+ * Continually and intelligently test only those files you change with autotest.
48
+ * Test against multiple versions with multiruby.
49
+ * Enhance and automatically audit your rails tests using Test::Rails.
50
+ * Includes a LinuxJournal article on testing with ZenTest written by Pat Eyler.
51
+ * See also: http://blog.zenspider.com/archives/zentest/
52
+ * See also: http://blog.segment7.net/articles/category/zentest
53
+
54
+ == SYNOPSYS
55
+
56
+ ZenTest MyProject.rb TestMyProject.rb > missing.rb
57
+
58
+ ./TestMyProject.rb | unit_diff
59
+
60
+ autotest
61
+
62
+ multiruby_setup mri:svn:current
63
+ multiruby ./TestMyProject.rb
64
+
65
+ (and other stuff for Test::Rails)
66
+
67
+ == REQUIREMENTS
68
+
69
+ * Ruby 1.6+, JRuby 1.1.2+, or rubinius
70
+ * Test::Unit or miniunit
71
+ * Hoe
72
+ * rubygems
73
+ * diff.exe on windoze. Try http://gnuwin32.sourceforge.net/packages.html
74
+
75
+ == INSTALL
76
+
77
+ Using Rubygems:
78
+
79
+ * sudo gem install ZenTest
80
+
81
+ Using Rake:
82
+
83
+ * rake test
84
+ * sudo rake install
85
+
86
+ == LICENSE
87
+
88
+ (The MIT License)
89
+
90
+ Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
91
+
92
+ Permission is hereby granted, free of charge, to any person obtaining
93
+ a copy of this software and associated documentation files (the
94
+ "Software"), to deal in the Software without restriction, including
95
+ without limitation the rights to use, copy, modify, merge, publish,
96
+ distribute, sublicense, and/or sell copies of the Software, and to
97
+ permit persons to whom the Software is furnished to do so, subject to
98
+ the following conditions:
99
+
100
+ The above copyright notice and this permission notice shall be
101
+ included in all copies or substantial portions of the Software.
102
+
103
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
104
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
105
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
106
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
107
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
108
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
109
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
110
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/test/rails/version.rb'
6
+
7
+ Hoe.new('test_rails', Test::Rails::VERSION::STRING) do |test_rails|
8
+ test_rails.developer('Ryan Davis', 'ryand-ruby@zenspider.com')
9
+ test_rails.developer('Eric Hodel', 'drbrain@segment7.net')
10
+ test_rails.developer('Dray Lacy', 'dray@izea.com')
11
+ end
12
+
13
+ # vim: syntax=Ruby
@@ -0,0 +1,382 @@
1
+ ##
2
+ # ControllerTestCase allows controllers to be tested independent of their
3
+ # views.
4
+ #
5
+ # = Features
6
+ #
7
+ # * ActionMailer is already set up for you.
8
+ # * The session and flash accessors work on both sides of get/post/etc.
9
+ # * Optional automatic auditing for missing assert_assigns. See
10
+ # util_audit_assert_assigned
11
+ #
12
+ # = Naming
13
+ #
14
+ # The test class must be named after your controller class name, so if
15
+ # you're testing actions for the +RouteController+ you would name your
16
+ # test case +RouteControllerTest+.
17
+ #
18
+ # The test names should be in the form of +test_action_edgecase+ where
19
+ # 'action' corresponds to the name of the controller action, and
20
+ # 'edgecase' describes the scenario you are testing.
21
+ #
22
+ # If you are testing an action named 'show' your test should be named
23
+ # +test_show+. If your action behaves differently depending upon its
24
+ # arguments then you can make the test name descriptive like
25
+ # +test_show_photos+ and +test_show_no_photos+.
26
+ #
27
+ # = Examples
28
+ #
29
+ # == Typical Controller Test
30
+ #
31
+ # class RouteControllerTest < Test::Rails::ControllerTestCase
32
+ #
33
+ # fixtures :users, :routes, :points, :photos
34
+ #
35
+ # def test_delete
36
+ # # Store current count
37
+ # count = Route.count
38
+ # # Set up our environment
39
+ # session[:username] = users(:herbert).username
40
+ #
41
+ # # perform the delete action
42
+ # get :delete, :id => routes(:work).id
43
+ #
44
+ # # Assert we got a 200
45
+ # assert_response :success
46
+ # # Assert controller deleted route
47
+ # assert_equal count-1, Route.count
48
+ # # Ensure that @action_title is set properly
49
+ # assert_assigned :action_title, "Deleting \"#{routes(:work).name}\""
50
+ # # Ensure that @route is set properly
51
+ # assert_assigned :route, routes(:work)
52
+ # end
53
+ #
54
+ # end
55
+ #
56
+ # == ActionMailer Test
57
+ #
58
+ # class ApplicationController < ActionController::Base
59
+ #
60
+ # ##
61
+ # # Send an email when we get an unhandled exception.
62
+ #
63
+ # def log_error(exception)
64
+ # case exception
65
+ # when ::ActionController::RoutingError,
66
+ # ::ActionController::UnknownAction,
67
+ # ::ActiveRecord::RecordNotFound then
68
+ # # ignore
69
+ # else
70
+ # unless RAILS_ENV == 'development' then
71
+ # Email.deliver_error exception, params, session, @request.env
72
+ # end
73
+ # end
74
+ # end
75
+ #
76
+ # end
77
+ #
78
+ # ##
79
+ # # Dummy Controller just for testing.
80
+ #
81
+ # class DummyController < ApplicationController
82
+ #
83
+ # def error
84
+ # # Simulate a bug in our application
85
+ # raise RuntimeError
86
+ # end
87
+ #
88
+ # end
89
+ #
90
+ # class DummyControllerTest < Test::Rails::ControllerTestCase
91
+ #
92
+ # def test_error_email
93
+ # # The rescue_action added by ControllerTestCase needs to be removed so
94
+ # # that exceptions fall through to the real error handler
95
+ # @controller.class.send :remove_method, :rescue_action
96
+ #
97
+ # # Fire off a request
98
+ # get :error
99
+ #
100
+ # # We should get a 500
101
+ # assert_response 500
102
+ #
103
+ # # And one delivered email
104
+ # assert_equal 1, @deliveries.length, 'error email sent'
105
+ # end
106
+ #
107
+ # end
108
+ #
109
+ #--
110
+ # TODO: Ensure that assert_tag doesn't work
111
+ # TODO: Cookie input.
112
+
113
+ class Test::Rails::ControllerTestCase < Test::Rails::FunctionalTestCase
114
+
115
+ self.use_transactional_fixtures = true
116
+ self.use_instantiated_fixtures = false
117
+
118
+ NOTHING = Object.new # :nodoc:
119
+
120
+ DEFAULT_ASSIGNS = %w[
121
+ _cookies _flash _headers _params _request _response _session
122
+
123
+ cookies flash headers params request response session
124
+
125
+ action_name
126
+ before_filter_chain_aborted
127
+ db_rt_after_render
128
+ db_rt_before_render
129
+ ignore_missing_templates
130
+ loggedin_user
131
+ logger
132
+ rendering_runtime
133
+ request_origin
134
+ template
135
+ template_class
136
+ template_root
137
+ url
138
+ user
139
+ variables_added
140
+ ]
141
+
142
+ def setup
143
+ return if self.class == Test::Rails::ControllerTestCase
144
+
145
+ @controller_class_name ||= self.class.name.sub 'Test', ''
146
+
147
+ super
148
+
149
+ @controller_class.send(:define_method, :rescue_action) { |e| raise e }
150
+
151
+ @deliveries = []
152
+ ActionMailer::Base.deliveries = @deliveries
153
+
154
+ # used by util_audit_assert_assigns
155
+ @assigns_asserted = []
156
+ @assigns_ignored ||= [] # untested assigns to ignore
157
+ end
158
+
159
+ ##
160
+ # Excutes the request +action+ with +params+.
161
+ #
162
+ # See also: get, post, put, delete, head, xml_http_request
163
+
164
+ def process(action, parameters = nil)
165
+ parameters ||= {}
166
+
167
+ @request.recycle!
168
+ @request.env['REQUEST_METHOD'] ||= 'GET'
169
+ @request.action = action.to_s
170
+
171
+ @request.assign_parameters @controller_class.controller_path, action.to_s,
172
+ parameters
173
+
174
+ build_request_uri action, parameters
175
+
176
+ @controller.process @request, @response
177
+ end
178
+
179
+ ##
180
+ # Performs a GET request on +action+ with +params+.
181
+
182
+ def get(action, parameters = nil)
183
+ @request.env['REQUEST_METHOD'] = 'GET'
184
+ process action, parameters
185
+ end
186
+
187
+ ##
188
+ # Performs a HEAD request on +action+ with +params+.
189
+
190
+ def head(action, parameters = nil)
191
+ @request.env['REQUEST_METHOD'] = 'HEAD'
192
+ process action, parameters
193
+ end
194
+
195
+ ##
196
+ # Performs a POST request on +action+ with +params+.
197
+
198
+ def post(action, parameters = nil)
199
+ @request.env['REQUEST_METHOD'] = 'POST'
200
+ process action, parameters
201
+ end
202
+
203
+ ##
204
+ # Performs a PUT request on +action+ with +params+.
205
+
206
+ def put(action, parameters = nil)
207
+ @request.env['REQUEST_METHOD'] = 'PUT'
208
+ process action, parameters
209
+ end
210
+
211
+ ##
212
+ # Performs a DELETE request on +action+ with +params+.
213
+
214
+ def delete(action, parameters = nil)
215
+ @request.env['REQUEST_METHOD'] = 'DELETE'
216
+ process action, parameters
217
+ end
218
+
219
+ ##
220
+ # Performs a XMLHttpRequest request using +request_method+ on +action+ with
221
+ # +params+.
222
+
223
+ def xml_http_request(request_method, action, parameters = nil)
224
+ @request.env['REQUEST_METHOD'] = request_method.to_s
225
+
226
+ @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
227
+ @request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
228
+
229
+ result = process action, parameters
230
+
231
+ @request.env.delete 'HTTP_X_REQUESTED_WITH'
232
+ @request.env.delete 'HTTP_ACCEPT'
233
+
234
+ return result
235
+ end
236
+
237
+ ##
238
+ # Friendly alias for xml_http_request
239
+
240
+ alias xhr xml_http_request
241
+
242
+ ##
243
+ # Asserts that the assigns variable +ivar+ is assigned to +value+. If
244
+ # +value+ is omitted, asserts that assigns variable +ivar+ exists.
245
+
246
+ def assert_assigned(ivar, value = NOTHING)
247
+ ivar = ivar.to_s
248
+ @assigns_asserted << ivar
249
+ assert_includes assigns, ivar, "#{ivar.inspect} missing from assigns"
250
+ unless value.equal? NOTHING then
251
+ assert_equal value, assigns[ivar],
252
+ "assert_assigned #{ivar.intern.inspect}"
253
+ end
254
+ end
255
+
256
+ ##
257
+ # Asserts the response content type matches +type+.
258
+
259
+ def assert_content_type(type, message = nil)
260
+ assert_equal type, @response.headers['Content-Type'], message
261
+ end
262
+
263
+ ##
264
+ # Asserts that +key+ of flash has +content+. If +content+ is a Regexp, then
265
+ # the assertion will fail if the Regexp does not match.
266
+ #
267
+ # controller:
268
+ # flash[:notice] = 'Please log in'
269
+ #
270
+ # test:
271
+ # assert_flash :notice, 'Please log in'
272
+
273
+ def assert_flash(key, content)
274
+ assert flash.include?(key),
275
+ "#{key.inspect} missing from flash, has #{flash.keys.inspect}"
276
+
277
+ case content
278
+ when Regexp then
279
+ assert_match content, flash[key],
280
+ "Content of flash[#{key.inspect}] did not match"
281
+ else
282
+ assert_equal content, flash[key],
283
+ "Incorrect content in flash[#{key.inspect}]"
284
+ end
285
+ end
286
+
287
+ ##
288
+ # Asserts that the assigns variable +ivar+ is not set.
289
+
290
+ def deny_assigned(ivar)
291
+ ivar = ivar.to_s
292
+ deny_includes assigns, ivar
293
+ end
294
+
295
+ ##
296
+ # Checks your assert_assigned tests against the instance variables in
297
+ # assigns. Fails if the two don't match.
298
+ #
299
+ # Add util_audit_assert_assigned to your teardown. If you have instance
300
+ # variables that you don't need to set (for example, were set in a
301
+ # before_filter in ApplicationController) then add them to the
302
+ # @assigns_ignored instance variable in your setup.
303
+ #
304
+ # = Example
305
+ #
306
+ # == Controller method
307
+ #
308
+ # class UserController < ApplicationController
309
+ # def new
310
+ # # ...
311
+ #
312
+ # @login_form = false
313
+ # end
314
+ # end
315
+ #
316
+ # == Test setup:
317
+ #
318
+ # class UserControllerTest < Test::Rails::ControllerTestCase
319
+ #
320
+ # def teardown
321
+ # super
322
+ # util_audit_assert_assigned
323
+ # end
324
+ #
325
+ # def test_new
326
+ # get :new
327
+ #
328
+ # assert_response :success
329
+ # # no assert_assigns for @login_form
330
+ # end
331
+ #
332
+ # end
333
+ #
334
+ # == Output
335
+ # 1) Failure:
336
+ # test_new(UserControllerTest)
337
+ # [[...]/controller_test_case.rb:331:in `util_audit_assert_assigned'
338
+ # [...]/user_controller_test.rb:14:in `teardown_without_fixtures'
339
+ # [...]fixtures.rb:555:in `teardown']:
340
+ # You are missing these assert_assigned assertions:
341
+ # assert_assigned :login_form #, some_value
342
+ # .
343
+
344
+ def util_audit_assert_assigned
345
+ return unless @test_passed
346
+ return unless @controller.send :performed?
347
+ all_assigns = assigns.keys.sort
348
+
349
+ assigns_ignored = DEFAULT_ASSIGNS | @assigns_ignored
350
+ assigns_ignored = assigns_ignored.map { |a| a.to_s }
351
+
352
+ assigns_created = all_assigns - assigns_ignored
353
+ assigns_asserted = @assigns_asserted - assigns_ignored
354
+
355
+ assigns_missing = assigns_created - assigns_asserted
356
+
357
+ return if assigns_missing.empty?
358
+
359
+ message = []
360
+ message << "You are missing these assert_assigned assertions:"
361
+ assigns_missing.sort.each do |ivar|
362
+ message << " assert_assigned #{ivar.intern.inspect} #, :some_value"
363
+ end
364
+ message << nil # stupid '.'
365
+
366
+ flunk message.join("\n")
367
+ end
368
+
369
+ private
370
+
371
+ def build_request_uri(action, parameters)
372
+ return if @request.env['REQUEST_URI']
373
+
374
+ options = @controller.send :rewrite_options, parameters
375
+ options.update :only_path => true, :action => action
376
+
377
+ url = ActionController::UrlRewriter.new @request, parameters
378
+ @request.set_REQUEST_URI url.rewrite(options)
379
+ end
380
+
381
+ end
382
+
@@ -0,0 +1,79 @@
1
+ $TESTING_RTC = defined?($TESTING_RTC) && $TESTING_RTC
2
+
3
+ ##
4
+ # FunctionalTestCase is an abstract class that sets up a controller instance
5
+ # for its subclasses.
6
+
7
+ class Test::Rails::FunctionalTestCase < Test::Rails::TestCase
8
+
9
+ self.use_transactional_fixtures = true
10
+ self.use_instantiated_fixtures = false
11
+
12
+ ##
13
+ # Sets up instance variables to allow tests depending on a controller work.
14
+ #
15
+ # setup uses the instance variable @controller_class_name to determine which
16
+ # controller class to instantiate.
17
+ #
18
+ # setup also instantiates a new @request and @response object.
19
+ #
20
+ # If you need to perform extra setup actions, define #setup_extra and
21
+ # FunctionalTestCase will call it after performing the rest of its setup
22
+ # actions.
23
+
24
+ def setup
25
+ return if self.class.name =~ /TestCase$/ and not $TESTING_RTC
26
+ super
27
+
28
+ @controller_class = Object.path2class @controller_class_name
29
+ raise "Can't determine controller class for #{self.class}" if @controller_class.nil?
30
+
31
+ @controller = @controller_class.new
32
+
33
+ @session = ActionController::TestSession.new
34
+
35
+ @flash = ActionController::Flash::FlashHash.new
36
+ @session['flash'] = @flash
37
+
38
+ @request = ActionController::TestRequest.new
39
+ @request.session = @session
40
+
41
+ # HACK There's probably an official way to do this
42
+ @controller.instance_variable_set :@_session, @request.session
43
+
44
+ @response = ActionController::TestResponse.new
45
+
46
+ setup_extra if respond_to? :setup_extra
47
+ end
48
+
49
+ ##
50
+ # Flash accessor. The flash can be assigned to before calling process or
51
+ # render and it will Just Work (yay!)
52
+ #
53
+ # view:
54
+ # <div class="error"><%= flash[:error] %></div>
55
+ #
56
+ # test:
57
+ # flash[:error] = 'You did a bad thing.'
58
+ # render
59
+ # assert_tag :tag => 'div', :attributes => { :class => 'error' },
60
+ # :content => 'You did a bad thing.'
61
+
62
+ attr_reader :flash
63
+
64
+ ##
65
+ # Session accessor. The session can be assigned to before calling process
66
+ # or render and it will Just Work (yay!)
67
+ #
68
+ # test:
69
+ #
70
+ # def test_logout
71
+ # session[:user] = users(:herbert)
72
+ # post :logout
73
+ # assert_equal nil, session[:user]
74
+ # end
75
+
76
+ attr_reader :session
77
+
78
+ end
79
+
@@ -0,0 +1,64 @@
1
+ ##
2
+ # Stub controller for testing helpers.
3
+
4
+ class HelperTestCaseController < ApplicationController
5
+
6
+ attr_accessor :request
7
+
8
+ attr_accessor :url
9
+
10
+ ##
11
+ # Re-raise errors
12
+
13
+ def rescue_action(e)
14
+ raise e
15
+ end
16
+
17
+ end
18
+
19
+ ##
20
+ # HelperTestCase allows helpers to be easily tested.
21
+ #
22
+ # Original concept by Ryan Davis, original implementation by Geoff Grosenbach.
23
+
24
+ class Test::Rails::HelperTestCase < Test::Rails::FunctionalTestCase
25
+
26
+ self.use_transactional_fixtures = true
27
+ self.use_instantiated_fixtures = false
28
+
29
+ # Are other helpers needed?
30
+
31
+ include ActionView::Helpers::ActiveRecordHelper
32
+ include ActionView::Helpers::TagHelper
33
+ include ActionView::Helpers::FormTagHelper
34
+ include ActionView::Helpers::FormOptionsHelper
35
+ include ActionView::Helpers::FormHelper
36
+ include ActionView::Helpers::UrlHelper
37
+ include ActionView::Helpers::AssetTagHelper
38
+ include ActionView::Helpers::PrototypeHelper rescue nil # Rails 1.0 only
39
+ include ActionView::Helpers::TextHelper
40
+
41
+ ##
42
+ # Automatically includes the helper module into the test sublcass.
43
+
44
+ def self.inherited(helper_testcase)
45
+ super
46
+ helper_name = helper_testcase.name.sub 'Test', ''
47
+ helper_module = Object.path2class helper_name
48
+ helper_testcase.send :include, helper_module
49
+ rescue NameError
50
+ raise "Unable to find helper #{helper_name}"
51
+ end
52
+
53
+ def setup
54
+ return if self.class.name =~ /TestCase$/
55
+ @controller_class_name = 'HelperTestCaseController'
56
+ super
57
+ @controller.request = @request
58
+ @controller.url = ActionController::UrlRewriter.new @request, {} # url_for
59
+
60
+ ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
61
+ end
62
+
63
+ end
64
+
@@ -0,0 +1,31 @@
1
+ require 'test/rails'
2
+
3
+ ##
4
+ # A wrapper that allows instance variables to be manipulated using +[]+ and
5
+ # +[]=+
6
+
7
+ class Test::Rails::IvarProxy
8
+
9
+ ##
10
+ # Wraps +object+ allowing its instance variables to be manipulated.
11
+
12
+ def initialize(object)
13
+ @object = object
14
+ end
15
+
16
+ ##
17
+ # Retrieves +ivar+ from the wrapped object.
18
+
19
+ def [](ivar)
20
+ @object.instance_variable_get "@#{ivar}"
21
+ end
22
+
23
+ ##
24
+ # Sets +ivar+ to +val+ on the wrapped object.
25
+
26
+ def []=(ivar, val)
27
+ @object.instance_variable_set "@#{ivar}", val
28
+ end
29
+
30
+ end
31
+