merb-core 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. data/Rakefile +61 -11
  2. data/bin/merb +5 -1
  3. data/lib/merb-core.rb +202 -25
  4. data/lib/merb-core/autoload.rb +19 -17
  5. data/lib/merb-core/bootloader.rb +84 -71
  6. data/lib/merb-core/config.rb +19 -14
  7. data/lib/merb-core/controller/abstract_controller.rb +16 -17
  8. data/lib/merb-core/controller/exceptions.rb +115 -70
  9. data/lib/merb-core/controller/merb_controller.rb +62 -38
  10. data/lib/merb-core/controller/mime.rb +1 -1
  11. data/lib/merb-core/controller/mixins/authentication.rb +87 -0
  12. data/lib/merb-core/controller/mixins/controller.rb +16 -15
  13. data/lib/merb-core/controller/mixins/render.rb +113 -19
  14. data/lib/merb-core/controller/mixins/responder.rb +8 -2
  15. data/lib/merb-core/controller/template.rb +1 -1
  16. data/lib/merb-core/core_ext.rb +1 -0
  17. data/lib/merb-core/core_ext/class.rb +113 -6
  18. data/lib/merb-core/core_ext/hash.rb +43 -39
  19. data/lib/merb-core/core_ext/kernel.rb +75 -38
  20. data/lib/merb-core/core_ext/mash.rb +4 -4
  21. data/lib/merb-core/core_ext/object.rb +18 -7
  22. data/lib/merb-core/core_ext/set.rb +9 -4
  23. data/lib/merb-core/core_ext/string.rb +29 -9
  24. data/lib/merb-core/core_ext/time.rb +13 -0
  25. data/lib/merb-core/dispatch/cookies.rb +1 -2
  26. data/lib/merb-core/dispatch/dispatcher.rb +18 -10
  27. data/lib/merb-core/dispatch/exceptions.html.erb +1 -1
  28. data/lib/merb-core/dispatch/request.rb +3 -0
  29. data/lib/merb-core/dispatch/router.rb +10 -7
  30. data/lib/merb-core/dispatch/router/behavior.rb +36 -27
  31. data/lib/merb-core/dispatch/router/route.rb +7 -2
  32. data/lib/merb-core/dispatch/session/cookie.rb +4 -4
  33. data/lib/merb-core/dispatch/session/memcached.rb +17 -5
  34. data/lib/merb-core/logger.rb +2 -2
  35. data/lib/merb-core/plugins.rb +16 -4
  36. data/lib/merb-core/rack/adapter/ebb.rb +4 -1
  37. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -0
  38. data/lib/merb-core/rack/adapter/fcgi.rb +1 -0
  39. data/lib/merb-core/rack/adapter/mongrel.rb +1 -0
  40. data/lib/merb-core/rack/adapter/runner.rb +1 -0
  41. data/lib/merb-core/rack/adapter/thin.rb +3 -1
  42. data/lib/merb-core/rack/adapter/webrick.rb +1 -0
  43. data/lib/merb-core/rack/application.rb +17 -1
  44. data/lib/merb-core/server.rb +78 -28
  45. data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -3
  46. data/lib/merb-core/test/helpers/request_helper.rb +81 -27
  47. data/lib/merb-core/test/helpers/view_helper.rb +1 -1
  48. data/lib/merb-core/test/matchers/controller_matchers.rb +55 -5
  49. data/lib/merb-core/test/matchers/route_matchers.rb +8 -17
  50. data/lib/merb-core/test/matchers/view_matchers.rb +53 -11
  51. data/lib/merb-core/test/run_specs.rb +22 -14
  52. data/lib/merb-core/test/tasks/spectasks.rb +54 -33
  53. data/lib/merb-core/vendor/facets/inflect.rb +91 -2
  54. data/lib/merb-core/version.rb +2 -2
  55. data/spec/private/config/config_spec.rb +54 -26
  56. data/spec/private/core_ext/class_spec.rb +22 -0
  57. data/spec/private/core_ext/hash_spec.rb +70 -54
  58. data/spec/private/core_ext/kernel_spec.rb +149 -14
  59. data/spec/private/core_ext/object_spec.rb +92 -10
  60. data/spec/private/core_ext/string_spec.rb +162 -4
  61. data/spec/private/core_ext/time_spec.rb +16 -0
  62. data/spec/private/dispatch/bootloader_spec.rb +24 -0
  63. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +1 -1
  64. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +1 -1
  65. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +1 -1
  66. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +1 -1
  67. data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
  68. data/spec/private/dispatch/fixture/log/merb_test.log +138 -0
  69. data/spec/private/plugins/plugin_spec.rb +79 -8
  70. data/spec/private/rack/application_spec.rb +1 -1
  71. data/spec/public/abstract_controller/controllers/filters.rb +26 -0
  72. data/spec/public/abstract_controller/controllers/helpers.rb +2 -2
  73. data/spec/public/abstract_controller/controllers/partial.rb +2 -2
  74. data/spec/public/abstract_controller/controllers/render.rb +16 -4
  75. data/spec/public/abstract_controller/filter_spec.rb +8 -0
  76. data/spec/public/abstract_controller/render_spec.rb +12 -0
  77. data/spec/public/controller/authentication_spec.rb +103 -0
  78. data/spec/public/controller/base_spec.rb +4 -3
  79. data/spec/public/controller/controllers/authentication.rb +47 -0
  80. data/spec/public/controller/controllers/base.rb +1 -0
  81. data/spec/public/controller/controllers/display.rb +30 -0
  82. data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
  83. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
  84. data/spec/public/controller/display_spec.rb +17 -0
  85. data/spec/public/controller/spec_helper.rb +1 -0
  86. data/spec/public/controller/url_spec.rb +25 -7
  87. data/spec/public/core/merb_core_spec.rb +34 -0
  88. data/spec/public/directory_structure/directory/app/controllers/custom.rb +2 -2
  89. data/spec/public/directory_structure/directory/log/merb_test.log +48 -0
  90. data/spec/public/logger/logger_spec.rb +10 -4
  91. data/spec/public/reloading/directory/app/controllers/reload.rb +1 -1
  92. data/spec/public/reloading/directory/log/merb_test.log +13 -0
  93. data/spec/public/reloading/reload_spec.rb +23 -22
  94. data/spec/public/request/request_spec.rb +2 -0
  95. data/spec/public/router/nested_resources_spec.rb +7 -0
  96. data/spec/public/router/resources_spec.rb +46 -1
  97. data/spec/public/router/special_spec.rb +5 -1
  98. data/spec/public/test/controller_matchers_spec.rb +25 -1
  99. data/spec/public/test/controllers/spec_helper_controller.rb +8 -0
  100. data/spec/public/test/request_helper_spec.rb +52 -1
  101. data/spec/public/test/route_matchers_spec.rb +27 -25
  102. data/spec/public/test/view_helper_spec.rb +1 -1
  103. data/spec/public/test/view_matchers_spec.rb +148 -72
  104. metadata +23 -3
@@ -1,6 +1,6 @@
1
1
  require 'etc'
2
2
  module Merb
3
-
3
+
4
4
  # Server encapsulates the management of Merb daemons.
5
5
  class Server
6
6
  class << self
@@ -29,9 +29,9 @@ module Merb
29
29
  else
30
30
  raise "Merb is already running on port: #{port}"
31
31
  end
32
- end
32
+ end
33
33
  elsif Merb::Config[:daemonize]
34
- unless alive?(@port)
34
+ unless alive?(@port)
35
35
  remove_pid_file(@port)
36
36
  daemonize(@port)
37
37
  else
@@ -39,6 +39,7 @@ module Merb
39
39
  end
40
40
  else
41
41
  trap('TERM') { exit }
42
+ trap('INT') { puts "\nExiting"; exit }
42
43
  BootLoader.run
43
44
  Merb.adapter.start(Merb::Config.to_hash)
44
45
  end
@@ -51,8 +52,8 @@ module Merb
51
52
  # Boolean::
52
53
  # True if Merb is running on the specified port.
53
54
  def alive?(port)
54
- f = "#{Merb.log_path}" / "merb.#{port}.pid"
55
- pid = IO.read(f).chomp.to_i
55
+ pidfile = pid_file(port)
56
+ pid = IO.read(pidfile).chomp.to_i
56
57
  Process.kill(0, pid)
57
58
  true
58
59
  rescue
@@ -69,7 +70,10 @@ module Merb
69
70
  def kill(port, sig=9)
70
71
  Merb::BootLoader::BuildFramework.run
71
72
  begin
72
- Dir[Merb.log_path/ "merb.#{port == 'all' ? '*' : port }.pid"].each do |f|
73
+ pidfiles = port == "all" ?
74
+ pid_files : [ pid_file(port) ]
75
+
76
+ pidfiles.each do |f|
73
77
  pid = IO.read(f).chomp.to_i
74
78
  begin
75
79
  Process.kill(sig, pid)
@@ -86,7 +90,7 @@ module Merb
86
90
  puts "Failed to kill PID #{pid}: #{e.message}"
87
91
  end
88
92
  end
89
- ensure
93
+ ensure
90
94
  exit
91
95
  end
92
96
  end
@@ -105,19 +109,24 @@ module Merb
105
109
  Dir.chdir Merb::Config[:merb_root]
106
110
  at_exit { remove_pid_file(port) }
107
111
  Merb::Config[:port] = port
108
- if Merb::Config[:user]
109
- if Merb::Config[:group]
110
- change_privilege(Merb::Config[:user], Merb::Config[:group])
111
- else
112
- change_privilege(Merb::Config[:user])
113
- end
114
- end
115
112
  BootLoader.run
116
113
  Merb.adapter.start(Merb::Config.to_hash)
117
114
  end
118
115
  end
119
116
 
120
- # Removes a PID file from the filesystem.
117
+ def change_privilege
118
+ if Merb::Config[:user]
119
+ if Merb::Config[:group]
120
+ _change_privilege(Merb::Config[:user], Merb::Config[:group])
121
+ else
122
+ _change_privilege(Merb::Config[:user])
123
+ end
124
+ end
125
+ end
126
+
127
+ # Removes a PID file used by the server from the filesystem.
128
+ # This uses :pid_file options from configuration when provided
129
+ # or merb.<port>.pid in log directory by default.
121
130
  #
122
131
  # ==== Parameters
123
132
  # port<~to_s>::
@@ -127,15 +136,13 @@ module Merb
127
136
  # If Merb::Config[:pid_file] has been specified, that will be used
128
137
  # instead of the port based PID file.
129
138
  def remove_pid_file(port)
130
- if Merb::Config[:pid_file]
131
- pidfile = Merb::Config[:pid_file]
132
- else
133
- pidfile = Merb.log_path / "merb.#{port}.pid"
134
- end
139
+ pidfile = pid_file(port)
135
140
  FileUtils.rm(pidfile) if File.exist?(pidfile)
136
141
  end
137
142
 
138
143
  # Stores a PID file on the filesystem.
144
+ # This uses :pid_file options from configuration when provided
145
+ # or merb.<port>.pid in log directory by default.
139
146
  #
140
147
  # ==== Parameters
141
148
  # port<~to_s>::
@@ -145,15 +152,58 @@ module Merb
145
152
  # If Merb::Config[:pid_file] has been specified, that will be used
146
153
  # instead of the port based PID file.
147
154
  def store_pid(port)
148
- FileUtils.mkdir_p(Merb.log_path) unless File.directory?(Merb.log_path)
155
+ pidfile = pid_file(port)
156
+ FileUtils.mkdir_p(File.dirname(pidfile)) unless File.directory?(File.dirname(pidfile))
157
+ File.open(pidfile, 'w'){ |f| f.write("#{Process.pid}") }
158
+ end
159
+
160
+ # Gets the pid file for the specified port.
161
+ #
162
+ # ==== Parameters
163
+ # port<~to_s>::
164
+ # The port of the Merb process to whom the the PID file belongs to.
165
+ #
166
+ # ==== Returns
167
+ # String::
168
+ # Location of pid file for specified port. If clustered and pid_file option
169
+ # is specified, it adds the port value to the path.
170
+ def pid_file(port)
149
171
  if Merb::Config[:pid_file]
150
172
  pidfile = Merb::Config[:pid_file]
173
+ if Merb::Config[:cluster]
174
+ ext = File.extname(Merb::Config[:pid_file])
175
+ base = File.basename(Merb::Config[:pid_file], ext)
176
+ dir = File.dirname(Merb::Config[:pid_file])
177
+ File.join(dir, "#{base}.#{port}#{ext}")
178
+ else
179
+ Merb::Config[:pid_file]
180
+ end
151
181
  else
152
182
  pidfile = Merb.log_path / "merb.#{port}.pid"
183
+ Merb.log_path / "merb.#{port}.pid"
153
184
  end
154
- File.open(pidfile, 'w'){ |f| f.write("#{Process.pid}") }
155
185
  end
156
-
186
+
187
+ # Get a list of the pid files.
188
+ #
189
+ # ==== Returns
190
+ # Array::
191
+ # List of pid file paths. If not clustered, array contains a single path.
192
+ def pid_files
193
+ if Merb::Config[:pid_file]
194
+ if Merb::Config[:cluster]
195
+ ext = File.extname(Merb::Config[:pid_file])
196
+ base = File.basename(Merb::Config[:pid_file], ext)
197
+ dir = File.dirname(Merb::Config[:pid_file])
198
+ Dir[dir / "#{base}.*#{ext}"]
199
+ else
200
+ [ Merb::Config[:pid_file] ]
201
+ end
202
+ else
203
+ Dir[Merb.log_path / "merb.*.pid"]
204
+ end
205
+ end
206
+
157
207
  # Change privileges of the process to the specified user and group.
158
208
  #
159
209
  # ==== Parameters
@@ -162,14 +212,14 @@ module Merb
162
212
  #
163
213
  # ==== Alternatives
164
214
  # If group is left out, the user will be used as the group.
165
- def change_privilege(user, group=user)
166
-
215
+ def _change_privilege(user, group=user)
216
+
167
217
  puts "Changing privileges to #{user}:#{group}"
168
-
218
+
169
219
  uid, gid = Process.euid, Process.egid
170
220
  target_uid = Etc.getpwnam(user).uid
171
221
  target_gid = Etc.getgrnam(group).gid
172
-
222
+
173
223
  if uid != target_uid || gid != target_gid
174
224
  # Change process ownership
175
225
  Process.initgroups(user, target_gid)
@@ -181,4 +231,4 @@ module Merb
181
231
  end
182
232
  end
183
233
  end
184
- end
234
+ end
@@ -101,7 +101,7 @@ module Merb::Test::MultipartRequestHelper
101
101
  # self.stub!(:current_user).and_return(@user)
102
102
  # end
103
103
  #
104
- # ==== Note
104
+ # ==== Notes
105
105
  # Set your option to contain a file object to simulate file uploads.
106
106
  #
107
107
  # Does not use routes.
@@ -124,7 +124,7 @@ module Merb::Test::MultipartRequestHelper
124
124
  # should go here (see +fake_request+).
125
125
  # block<Proc>:: The block is executed in the context of the controller.
126
126
  #
127
- # ==== Note
127
+ # ==== Notes
128
128
  # To include an uploaded file, put a file object as a value in params.
129
129
  def multipart_post(path, params = {}, env = {}, &block)
130
130
  env[:request_method] = "POST"
@@ -144,7 +144,7 @@ module Merb::Test::MultipartRequestHelper
144
144
  # should go here (see +fake_request+).
145
145
  # block<Proc>:: The block is executed in the context of the controller.
146
146
  #
147
- # ==== Note
147
+ # ==== Notes
148
148
  # To include an uplaoded file, put a file object as a value in params.
149
149
  def multipart_put(path, params = {}, env = {}, &block)
150
150
  env[:request_method] = "PUT"
@@ -15,7 +15,7 @@ module Merb
15
15
  env['rack.input'] = req
16
16
  super(DEFAULT_ENV.merge(env))
17
17
  end
18
-
18
+
19
19
  private
20
20
  DEFAULT_ENV = Mash.new({
21
21
  'SERVER_NAME' => 'localhost',
@@ -38,7 +38,7 @@ module Merb
38
38
  'GATEWAY_INTERFACE' => 'CGI/1.2',
39
39
  'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
40
40
  'HTTP_CONNECTION' => 'keep-alive',
41
- 'REQUEST_METHOD' => 'GET'
41
+ 'REQUEST_METHOD' => 'GET'
42
42
  }) unless defined?(DEFAULT_ENV)
43
43
  end
44
44
 
@@ -50,11 +50,11 @@ module Merb
50
50
  # :post_body<String>:: The post body for the request.
51
51
  # :req<String>::
52
52
  # The request string. This will only be used if :post_body is left out.
53
- #
53
+ #
54
54
  # ==== Returns
55
55
  # FakeRequest:: A Request object that is built based on the parameters.
56
56
  #
57
- # ==== Note
57
+ # ==== Notes
58
58
  # If you pass a post body, the content-type will be set to URL-encoded.
59
59
  #
60
60
  #---
@@ -66,7 +66,7 @@ module Merb
66
66
  else
67
67
  req = opt[:req]
68
68
  end
69
- FakeRequest.new(env, StringIO.new(req || ''))
69
+ FakeRequest.new(env, StringIO.new(req || ''))
70
70
  end
71
71
 
72
72
  # Dispatches an action to the given class. This bypasses the router and is
@@ -91,7 +91,7 @@ module Merb
91
91
  # self.stub!(:current_user).and_return(@user)
92
92
  # end
93
93
  #
94
- # ==== Note
94
+ # ==== Notes
95
95
  # Does not use routes.
96
96
  #
97
97
  #---
@@ -104,7 +104,47 @@ module Merb
104
104
 
105
105
  dispatch_request(request, controller_klass, action, &blk)
106
106
  end
107
-
107
+
108
+
109
+ # Dispatches an action to the given class and using HTTP Basic Authentication
110
+ # This bypasses the router and is suitable for unit testing of controllers.
111
+ #
112
+ # ==== Parameters
113
+ # controller_klass<Controller>::
114
+ # The controller class object that the action should be dispatched to.
115
+ # action<Symbol>:: The action name, as a symbol.
116
+ # username<String>:: The username.
117
+ # password<String>:: The password.
118
+ # params<Hash>::
119
+ # An optional hash that will end up as params in the controller instance.
120
+ # env<Hash>::
121
+ # An optional hash that is passed to the fake request. Any request options
122
+ # should go here (see +fake_request+), including :req or :post_body
123
+ # for setting the request body itself.
124
+ # &blk::
125
+ # The controller is yielded to the block provided for actions *prior* to
126
+ # the action being dispatched.
127
+ #
128
+ # ==== Example
129
+ # dispatch_with_basic_authentication_to(MyController, :create, 'Fred', 'secret', :name => 'Homer' ) do
130
+ # self.stub!(:current_user).and_return(@user)
131
+ # end
132
+ #
133
+ # ==== Notes
134
+ # Does not use routes.
135
+ #
136
+ #---
137
+ # @public
138
+ def dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk)
139
+ action = action.to_s
140
+ request_body = { :post_body => env[:post_body], :req => env[:req] }
141
+ env["X_HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{username}:#{password}")}"
142
+ request = fake_request(env.merge(
143
+ :query_string => Merb::Request.params_to_query_string(params)), request_body)
144
+
145
+ dispatch_request(request, controller_klass, action, &blk)
146
+ end
147
+
108
148
  # An HTTP GET request that operates through the router.
109
149
  #
110
150
  # ==== Parameters
@@ -114,12 +154,14 @@ module Merb
114
154
  # env<Hash>::
115
155
  # An optional hash that is passed to the fake request. Any request options
116
156
  # should go here (see +fake_request+).
117
- # &block:: The block is executed in the context of the controller.
157
+ # &blk::
158
+ # The controller is yielded to the block provided for actions *prior* to
159
+ # the action being dispatched.
118
160
  def get(path, params = {}, env = {}, &block)
119
161
  env[:request_method] = "GET"
120
162
  request(path, params, env, &block)
121
163
  end
122
-
164
+
123
165
  # An HTTP POST request that operates through the router.
124
166
  #
125
167
  # ==== Parameters
@@ -129,12 +171,14 @@ module Merb
129
171
  # env<Hash>::
130
172
  # An optional hash that is passed to the fake request. Any request options
131
173
  # should go here (see fake_request).
132
- # &block:: The block is executed in the context of the controller.
174
+ # &blk::
175
+ # The controller is yielded to the block provided for actions *prior* to
176
+ # the action being dispatched.
133
177
  def post(path, params = {}, env = {}, &block)
134
178
  env[:request_method] = "POST"
135
179
  request(path, params, env, &block)
136
180
  end
137
-
181
+
138
182
  # An HTTP PUT request that operates through the router.
139
183
  #
140
184
  # ==== Parameters
@@ -144,12 +188,14 @@ module Merb
144
188
  # env<Hash>::
145
189
  # An optional hash that is passed to the fake request. Any request options
146
190
  # should go here (see fake_request).
147
- # &block:: The block is executed in the context of the controller.
191
+ # &blk::
192
+ # The controller is yielded to the block provided for actions *prior* to
193
+ # the action being dispatched.
148
194
  def put(path, params = {}, env = {}, &block)
149
195
  env[:request_method] = "PUT"
150
196
  request(path, params, env, &block)
151
197
  end
152
-
198
+
153
199
  # An HTTP DELETE request that operates through the router
154
200
  #
155
201
  # ==== Parameters
@@ -159,7 +205,9 @@ module Merb
159
205
  # env<Hash>::
160
206
  # An optional hash that is passed to the fake request. Any request options
161
207
  # should go here (see fake_request).
162
- # &block:: The block is executed in the context of the controller.
208
+ # &blk::
209
+ # The controller is yielded to the block provided for actions *prior* to
210
+ # the action being dispatched.
163
211
  def delete(path, params = {}, env = {}, &block)
164
212
  env[:request_method] = "DELETE"
165
213
  request(path, params, env, &block)
@@ -175,48 +223,54 @@ module Merb
175
223
  # env<Hash>::
176
224
  # An optional hash that is passed to the fake request. Any request options
177
225
  # should go here (see +fake_request+).
178
- # blk<Proc>:: The block is executed in the context of the controller.
226
+ # &blk::
227
+ # The controller is yielded to the block provided for actions *prior* to
228
+ # the action being dispatched.
179
229
  #
180
230
  # ==== Example
181
- # request(path, :create, :name => 'Homer' ) do
231
+ # request(path, { :name => 'Homer' }, { :request_method => "PUT" }) do
182
232
  # self.stub!(:current_user).and_return(@user)
183
233
  # end
184
234
  #
185
- # ==== Note
235
+ # ==== Notes
186
236
  # Uses Routes.
187
237
  #
188
238
  #---
189
- # @semi-public
239
+ # @semi-public
190
240
  def request(path, params = {}, env= {}, &block)
191
241
  env[:request_method] ||= "GET"
192
242
  env[:request_uri] = path
193
243
  multipart = env.delete(:test_with_multipart)
194
-
244
+
195
245
  request = fake_request(env)
196
-
246
+
197
247
  opts = check_request_for_route(request) # Check that the request will be routed correctly
198
- klass = Object.full_const_get(opts.delete(:controller).to_const_string)
248
+ controller_name = (opts[:namespace] ? opts.delete(:namespace) + '/' : '') + opts.delete(:controller)
249
+ klass = Object.full_const_get(controller_name.snake_case.to_const_string)
250
+
199
251
  action = opts.delete(:action).to_s
200
252
  params.merge!(opts)
201
-
253
+
202
254
  multipart.nil? ? dispatch_to(klass, action, params, env, &block) : dispatch_multipart_to(klass, action, params, env, &block)
203
255
  end
204
256
 
205
257
 
206
258
  # The workhorse for the dispatch*to helpers.
207
- #
259
+ #
208
260
  # ==== Parameters
209
261
  # request<Merb::Test::FakeRequest, Merb::Request>::
210
262
  # A request object that has been setup for testing.
211
263
  # controller_klass<Merb::Controller>::
212
264
  # The class object off the controller to dispatch the action to.
213
265
  # action<Symbol>:: The action to dispatch the request to.
214
- # blk<Proc>:: The block will execute in the context of the controller itself.
266
+ # &blk::
267
+ # The controller is yielded to the block provided for actions *prior* to
268
+ # the action being dispatched.
215
269
  #
216
270
  # ==== Returns
217
271
  # An instance of +controller_klass+ based on the parameters.
218
272
  #
219
- # ==== Note
273
+ # ==== Notes
220
274
  # Does not use routes.
221
275
  #
222
276
  #---
@@ -233,7 +287,7 @@ module Merb
233
287
  end
234
288
 
235
289
  # Checks to see that a request is routable.
236
- #
290
+ #
237
291
  # ==== Parameters
238
292
  # request<Merb::Test::FakeRequest, Merb::Request>::
239
293
  # The request object to inspect.
@@ -254,4 +308,4 @@ module Merb
254
308
  end
255
309
  end
256
310
  end
257
- end
311
+ end