wycats-merb-core 0.9.8 → 0.9.9

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.
Files changed (58) hide show
  1. data/CHANGELOG +136 -2
  2. data/CONTRIBUTORS +6 -0
  3. data/PUBLIC_CHANGELOG +15 -0
  4. data/Rakefile +12 -14
  5. data/lib/merb-core.rb +82 -43
  6. data/lib/merb-core/bootloader.rb +268 -60
  7. data/lib/merb-core/config.rb +119 -34
  8. data/lib/merb-core/controller/abstract_controller.rb +58 -18
  9. data/lib/merb-core/controller/exceptions.rb +2 -15
  10. data/lib/merb-core/controller/merb_controller.rb +28 -1
  11. data/lib/merb-core/controller/mime.rb +4 -0
  12. data/lib/merb-core/controller/mixins/controller.rb +14 -17
  13. data/lib/merb-core/controller/mixins/render.rb +23 -28
  14. data/lib/merb-core/controller/mixins/responder.rb +0 -1
  15. data/lib/merb-core/controller/template.rb +44 -20
  16. data/lib/merb-core/core_ext/kernel.rb +8 -3
  17. data/lib/merb-core/dispatch/default_exception/default_exception.rb +1 -1
  18. data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +3 -1
  19. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +71 -67
  20. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +6 -2
  21. data/lib/merb-core/dispatch/dispatcher.rb +5 -9
  22. data/lib/merb-core/dispatch/request.rb +46 -57
  23. data/lib/merb-core/dispatch/router.rb +83 -6
  24. data/lib/merb-core/dispatch/router/behavior.rb +87 -27
  25. data/lib/merb-core/dispatch/router/resources.rb +281 -167
  26. data/lib/merb-core/dispatch/router/route.rb +141 -27
  27. data/lib/merb-core/logger.rb +213 -202
  28. data/lib/merb-core/rack.rb +3 -1
  29. data/lib/merb-core/rack/adapter.rb +7 -4
  30. data/lib/merb-core/rack/adapter/ebb.rb +12 -13
  31. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -15
  32. data/lib/merb-core/rack/adapter/irb.rb +3 -2
  33. data/lib/merb-core/rack/adapter/mongrel.rb +22 -15
  34. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +4 -16
  35. data/lib/merb-core/rack/adapter/thin.rb +21 -22
  36. data/lib/merb-core/rack/adapter/thin_turbo.rb +4 -11
  37. data/lib/merb-core/rack/adapter/webrick.rb +54 -18
  38. data/lib/merb-core/rack/handler/mongrel.rb +12 -13
  39. data/lib/merb-core/rack/middleware/csrf.rb +1 -1
  40. data/lib/merb-core/server.rb +135 -98
  41. data/lib/merb-core/tasks/gem_management.rb +50 -12
  42. data/lib/merb-core/tasks/merb.rb +1 -0
  43. data/lib/merb-core/tasks/merb_rake_helper.rb +9 -38
  44. data/lib/merb-core/tasks/stats.rake +2 -2
  45. data/lib/merb-core/test.rb +9 -3
  46. data/lib/merb-core/test/helpers.rb +1 -0
  47. data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -2
  48. data/lib/merb-core/test/helpers/request_helper.rb +40 -372
  49. data/lib/merb-core/test/helpers/route_helper.rb +15 -7
  50. data/lib/merb-core/test/matchers.rb +1 -0
  51. data/lib/merb-core/test/matchers/controller_matchers.rb +4 -247
  52. data/lib/merb-core/test/matchers/view_matchers.rb +22 -4
  53. data/lib/merb-core/test/run_specs.rb +117 -25
  54. data/lib/merb-core/version.rb +1 -1
  55. metadata +1 -1
  56. data/lib/merb-core/vendor/facets.rb +0 -2
  57. data/lib/merb-core/vendor/facets/dictionary.rb +0 -433
  58. data/lib/merb-core/vendor/facets/inflect.rb +0 -342
@@ -3,11 +3,35 @@ require 'rubygems/dependency_installer'
3
3
  require 'rubygems/uninstaller'
4
4
  require 'rubygems/dependency'
5
5
 
6
+ module ColorfulMessages
7
+
8
+ # red
9
+ def error(*messages)
10
+ puts messages.map { |msg| "\033[1;31m#{msg}\033[0m" }
11
+ end
12
+
13
+ # yellow
14
+ def warning(*messages)
15
+ puts messages.map { |msg| "\033[1;33m#{msg}\033[0m" }
16
+ end
17
+
18
+ # green
19
+ def success(*messages)
20
+ puts messages.map { |msg| "\033[1;32m#{msg}\033[0m" }
21
+ end
22
+
23
+ alias_method :message, :success
24
+
25
+ end
26
+
6
27
  module GemManagement
7
28
 
29
+ include ColorfulMessages
30
+
8
31
  # Install a gem - looks remotely and local gem cache;
9
32
  # won't process rdoc or ri options.
10
33
  def install_gem(gem, options = {})
34
+ refresh = options.delete(:refresh) || []
11
35
  from_cache = (options.key?(:cache) && options.delete(:cache))
12
36
  if from_cache
13
37
  install_gem_from_cache(gem, options)
@@ -18,6 +42,16 @@ module GemManagement
18
42
  update_source_index(options[:install_dir]) if options[:install_dir]
19
43
 
20
44
  installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
45
+
46
+ # Exclude gems to refresh from index - force (re)install of new version
47
+ # def installer.source_index; @source_index; end
48
+ unless refresh.empty?
49
+ source_index = installer.instance_variable_get(:@source_index)
50
+ source_index.gems.each do |name, spec|
51
+ source_index.gems.delete(name) if refresh.include?(spec.name)
52
+ end
53
+ end
54
+
21
55
  exception = nil
22
56
  begin
23
57
  installer.install gem, version
@@ -34,10 +68,10 @@ module GemManagement
34
68
  exception = e
35
69
  end
36
70
  if installer.installed_gems.empty? && exception
37
- puts "Failed to install gem '#{gem} (#{version})' (#{exception.message})"
71
+ error "Failed to install gem '#{gem} (#{version})' (#{exception.message})"
38
72
  end
39
73
  installer.installed_gems.each do |spec|
40
- puts "Successfully installed #{spec.full_name}"
74
+ success "Successfully installed #{spec.full_name}"
41
75
  end
42
76
  return !installer.installed_gems.empty?
43
77
  end
@@ -61,10 +95,10 @@ module GemManagement
61
95
  exception = e
62
96
  end
63
97
  if installer.installed_gems.empty? && exception
64
- puts "Failed to install gem '#{gem}' (#{e.message})"
98
+ error "Failed to install gem '#{gem}' (#{e.message})"
65
99
  end
66
100
  installer.installed_gems.each do |spec|
67
- puts "Successfully installed #{spec.full_name}"
101
+ success "Successfully installed #{spec.full_name}"
68
102
  end
69
103
  end
70
104
 
@@ -94,12 +128,12 @@ module GemManagement
94
128
  if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
95
129
  FileUtils.cd(File.dirname(package)) do
96
130
  install_gem(File.basename(package), options.dup)
97
- return
131
+ return true
98
132
  end
99
133
  else
100
134
  raise Gem::InstallError, "No package found for #{gem_name}"
101
135
  end
102
- # Handle standard installation through Rake
136
+ # Handle elaborate installation through Rake
103
137
  else
104
138
  # Clean and regenerate any subgems for meta gems.
105
139
  Dir[File.join(gem_src_dir, '*', 'Rakefile')].each do |rakefile|
@@ -110,30 +144,34 @@ module GemManagement
110
144
 
111
145
  # Handle the main gem install.
112
146
  if File.exists?(File.join(gem_src_dir, 'Rakefile'))
147
+ subgems = []
113
148
  # Remove any existing packages.
114
149
  FileUtils.cd(gem_src_dir) { system("#{rake} clobber_package") }
115
150
  # Create the main gem pkg dir if it doesn't exist.
116
151
  FileUtils.mkdir_p(gem_pkg_dir) unless File.directory?(gem_pkg_dir)
117
152
  # Copy any subgems to the main gem pkg dir.
118
153
  Dir[File.join(gem_src_dir, '*', 'pkg', '*.gem')].each do |subgem_pkg|
154
+ if name = File.basename(subgem_pkg, '.gem')[/^(.*?)-([\d\.]+)$/, 1]
155
+ subgems << name
156
+ end
119
157
  dest = File.join(gem_pkg_dir, File.basename(subgem_pkg))
120
158
  FileUtils.copy_entry(subgem_pkg, dest, true, false, true)
121
159
  end
122
160
 
123
161
  # Finally generate the main package and install it; subgems
124
162
  # (dependencies) are local to the main package.
125
- FileUtils.cd(gem_src_dir) do
163
+ FileUtils.cd(gem_src_dir) do
126
164
  system("#{rake} package")
127
165
  FileUtils.cd(gem_pkg_dir) do
128
166
  if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
129
167
  # If the (meta) gem has it's own package, install it.
130
- install_gem(File.basename(package), options.dup)
168
+ install_gem(File.basename(package), options.merge(:refresh => subgems))
131
169
  else
132
170
  # Otherwise install each package seperately.
133
171
  Dir["*.gem"].each { |gem| install_gem(gem, options.dup) }
134
172
  end
135
173
  end
136
- return
174
+ return true
137
175
  end
138
176
  end
139
177
  end
@@ -166,7 +204,7 @@ module GemManagement
166
204
  spec = Gem::Specification.load(gemspec_path)
167
205
  spec.executables.each do |exec|
168
206
  executable = File.join(bin_dir, exec)
169
- puts "Writing executable wrapper #{executable}"
207
+ message "Writing executable wrapper #{executable}"
170
208
  File.open(executable, 'w', 0755) do |f|
171
209
  f.write(executable_wrapper(spec, exec))
172
210
  end
@@ -180,7 +218,7 @@ module GemManagement
180
218
 
181
219
  def executable_wrapper(spec, bin_file_name)
182
220
  <<-TEXT
183
- #!#{Gem.ruby}
221
+ #!/usr/bin/env ruby
184
222
  #
185
223
  # This file was generated by Merb's GemManagement
186
224
  #
@@ -226,4 +264,4 @@ TEXT
226
264
  Gem.source_index.load_gems_in(File.join(dir, 'specifications'))
227
265
  end
228
266
 
229
- end
267
+ end
@@ -1 +1,2 @@
1
+ require 'merb-core/tasks/merb_rake_helper'
1
2
  Dir[File.dirname(__FILE__) / '*.rake'].each { |ext| load ext }
@@ -28,6 +28,15 @@ module Merb
28
28
  uninstall_gem(name, defaults.merge(options))
29
29
  end
30
30
 
31
+ def self.sudo
32
+ ENV['MERB_SUDO'] ||= "sudo"
33
+ sudo = windows? ? "" : ENV['MERB_SUDO']
34
+ end
35
+
36
+ def self.windows?
37
+ (PLATFORM =~ /win32|cygwin/) rescue nil
38
+ end
39
+
31
40
  protected
32
41
 
33
42
  def self.ensure_wrapper(gemdir, name)
@@ -39,42 +48,4 @@ module Merb
39
48
  end
40
49
 
41
50
  end
42
- end
43
-
44
- def sudo
45
- ENV['MERB_SUDO'] ||= "sudo"
46
- sudo = windows? ? "" : ENV['MERB_SUDO']
47
- end
48
-
49
- def windows?
50
- (PLATFORM =~ /win32|cygwin/) rescue nil
51
- end
52
-
53
- def install_home
54
- ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
55
- end
56
-
57
- def install_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
58
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
59
- %{#{sudo} #{Gem.ruby} -S gem install #{install_home} --local pkg/#{gem_name}-#{gem_version}.gem #{options}}
60
- end
61
-
62
- def dev_install_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
63
- options << ' --development'
64
- install_command(gem_name, gem_version, options)
65
- end
66
-
67
- def jinstall_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
68
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
69
- %{#{sudo} jruby -S gem install #{install_home} --local pkg/#{gem_name}-#{gem_version}.gem #{options}}
70
- end
71
-
72
- def dev_jinstall_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
73
- options << ' --development'
74
- jinstall_command(gem_name, gem_version, options)
75
- end
76
-
77
- def uninstall_command(gem_name, options = '')
78
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
79
- %{#{sudo} #{Gem.ruby} -S gem uninstall #{gem_name} #{options}}
80
51
  end
@@ -39,7 +39,7 @@ task :stats do
39
39
  :models => 'app/models',
40
40
  :lib => 'lib',
41
41
  :spec => 'spec'
42
- }
42
+ }.reject {|name, dir| !File.exist?(dir) }
43
43
  EMPTY_STATS = { :lines => 0, :loc => 0, :classes => 0, :modules => 0, :methods => 0 }
44
44
 
45
45
  @all = {}
@@ -66,6 +66,6 @@ task :stats do
66
66
  code_loc = [:controllers, :helpers, :models].inject(0) { |sum, e| sum += @all[e][:loc] }
67
67
  test_loc = @all[:spec][:loc]
68
68
 
69
- puts " Code LOC: #{cb}#{code_loc}#{ce} Test LOC: #{cb}#{test_loc}#{ce} Test to code radio: #{cb}1:%0.2f#{ce}" % (test_loc.to_f / code_loc.to_f)
69
+ puts " Code LOC: #{cb}#{code_loc}#{ce} Test LOC: #{cb}#{test_loc}#{ce} Code to test radio: #{cb}1:%0.2f#{ce}" % (test_loc.to_f / code_loc.to_f)
70
70
  puts
71
71
  end
@@ -1,6 +1,9 @@
1
- require "hpricot"
1
+ begin
2
+ require "hpricot"
3
+ require 'merb-core/test/test_ext/hpricot'
4
+ rescue
5
+ end
2
6
 
3
- require 'merb-core/test/test_ext/hpricot'
4
7
  require 'merb-core/test/test_ext/object'
5
8
  require 'merb-core/test/test_ext/string'
6
9
 
@@ -8,4 +11,7 @@ module Merb; module Test; end; end
8
11
 
9
12
  require 'merb-core/test/helpers'
10
13
 
11
- require 'merb-core/test/matchers'
14
+ if Merb.test_framework.to_s == "rspec"
15
+ require 'merb-core/test/test_ext/rspec'
16
+ require 'merb-core/test/matchers'
17
+ end
@@ -2,6 +2,7 @@
2
2
  # testing helpers
3
3
  module Merb::Test::Helpers; end
4
4
 
5
+ require "merb-core/test/helpers/mock_request_helper"
5
6
  require "merb-core/test/helpers/request_helper"
6
7
  require "merb-core/test/helpers/multipart_request_helper"
7
8
  require "merb-core/test/helpers/controller_helper"
@@ -1,5 +1,6 @@
1
1
  module Merb::Test::MultipartRequestHelper
2
2
  require 'rubygems'
3
+ gem "mime-types"
3
4
  require 'mime/types'
4
5
 
5
6
  class Param
@@ -129,7 +130,7 @@ module Merb::Test::MultipartRequestHelper
129
130
  def multipart_post(path, params = {}, env = {}, &block)
130
131
  env[:request_method] = "POST"
131
132
  env[:test_with_multipart] = true
132
- request(path, params, env, &block)
133
+ mock_request(path, params, env, &block)
133
134
  end
134
135
 
135
136
  # An HTTP PUT request that operates through the router and uses multipart
@@ -149,7 +150,7 @@ module Merb::Test::MultipartRequestHelper
149
150
  def multipart_put(path, params = {}, env = {}, &block)
150
151
  env[:request_method] = "PUT"
151
152
  env[:test_with_multipart] = true
152
- request(path, params, env, &block)
153
+ mock_request(path, params, env, &block)
153
154
  end
154
155
 
155
156
  # ==== Parameters
@@ -1,393 +1,61 @@
1
- require 'tempfile'
1
+ require "rack"
2
2
 
3
3
  module Merb
4
4
  module Test
5
5
  module RequestHelper
6
- # FakeRequest sets up a default enviroment which can be overridden either
7
- # by passing and env into initialize or using request['HTTP_VAR'] = 'foo'
8
- class FakeRequest < Request
9
6
 
10
- # ==== Parameters
11
- # env<Hash>:: Environment options that override the defaults.
12
- # req<StringIO>:: The request to set as input for Rack.
13
- def initialize(env = {}, req = StringIO.new)
14
- env.environmentize_keys!
15
- env['rack.input'] = req
16
- super(DEFAULT_ENV.merge(env))
17
- end
18
-
19
- private
20
- DEFAULT_ENV = Mash.new({
21
- 'SERVER_NAME' => 'localhost',
22
- 'PATH_INFO' => '/',
23
- 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate',
24
- 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.1) Gecko/20060214 Camino/1.0',
25
- 'SCRIPT_NAME' => '/',
26
- 'SERVER_PROTOCOL' => 'HTTP/1.1',
27
- 'HTTP_CACHE_CONTROL' => 'max-age=0',
28
- 'HTTP_ACCEPT_LANGUAGE' => 'en,ja;q=0.9,fr;q=0.9,de;q=0.8,es;q=0.7,it;q=0.7,nl;q=0.6,sv;q=0.5,nb;q=0.5,da;q=0.4,fi;q=0.3,pt;q=0.3,zh-Hans;q=0.2,zh-Hant;q=0.1,ko;q=0.1',
29
- 'HTTP_HOST' => 'localhost',
30
- 'REMOTE_ADDR' => '127.0.0.1',
31
- 'SERVER_SOFTWARE' => 'Mongrel 1.1',
32
- 'HTTP_KEEP_ALIVE' => '300',
33
- 'HTTP_REFERER' => 'http://localhost/',
34
- 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
35
- 'HTTP_VERSION' => 'HTTP/1.1',
36
- 'REQUEST_URI' => '/',
37
- 'SERVER_PORT' => '80',
38
- 'GATEWAY_INTERFACE' => 'CGI/1.2',
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
- 'HTTP_CONNECTION' => 'keep-alive',
41
- 'REQUEST_METHOD' => 'GET'
42
- }) unless defined?(DEFAULT_ENV)
7
+ def describe_request(rack)
8
+ "a #{rack.original_env[:method] || rack.original_env["REQUEST_METHOD"] || "GET"} to '#{rack.url}'"
43
9
  end
44
10
 
45
- # CookieJar keeps track of cookies in a simple Mash.
46
- class CookieJar < Mash
47
-
48
- # ==== Parameters
49
- # request<Merb::Request, Merb::FakeRequest>:: The controller request.
50
- def update_from_request(request)
51
- request.cookies.each do |key, value|
52
- if value.blank?
53
- self.delete(key)
54
- else
55
- self[key] = Merb::Request.unescape(value)
56
- end
57
- end
58
- end
59
-
60
- end
61
-
62
- # ==== Parameters
63
- # env<Hash>:: A hash of environment keys to be merged into the default list.
64
- # opt<Hash>:: A hash of options (see below).
65
- #
66
- # ==== Options (opt)
67
- # :post_body<String>:: The post body for the request.
68
- # :req<String>::
69
- # The request string. This will only be used if :post_body is left out.
70
- #
71
- # ==== Returns
72
- # FakeRequest:: A Request object that is built based on the parameters.
73
- #
74
- # ==== Notes
75
- # If you pass a post body, the content-type will be set to URL-encoded.
76
- #
77
- #---
78
- # @public
79
- def fake_request(env = {}, opt = {})
80
- if opt[:post_body]
81
- req = opt[:post_body]
82
- env[:content_type] ||= "application/x-www-form-urlencoded"
11
+ def describe_input(input)
12
+ if input.respond_to?(:controller_name)
13
+ "#{input.controller_name}##{input.action_name}"
14
+ elsif input.respond_to?(:original_env)
15
+ describe_request(input)
83
16
  else
84
- req = opt[:req]
17
+ input
85
18
  end
86
- FakeRequest.new(env, StringIO.new(req || ''))
87
- end
88
-
89
- # Dispatches an action to the given class. This bypasses the router and is
90
- # suitable for unit testing of controllers.
91
- #
92
- # ==== Parameters
93
- # controller_klass<Controller>::
94
- # The controller class object that the action should be dispatched to.
95
- # action<Symbol>:: The action name, as a symbol.
96
- # params<Hash>::
97
- # An optional hash that will end up as params in the controller instance.
98
- # env<Hash>::
99
- # An optional hash that is passed to the fake request. Any request options
100
- # should go here (see +fake_request+), including :req or :post_body
101
- # for setting the request body itself.
102
- # &blk::
103
- # The controller is yielded to the block provided for actions *prior* to
104
- # the action being dispatched.
105
- #
106
- # ==== Example
107
- # dispatch_to(MyController, :create, :name => 'Homer' ) do |controller|
108
- # controller.stub!(:current_user).and_return(@user)
109
- # end
110
- #
111
- # ==== Notes
112
- # Does not use routes.
113
- #
114
- #---
115
- # @public
116
- def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
117
- params = merge_controller_and_action(controller_klass, action, params)
118
- dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
119
19
  end
120
20
 
121
- # Keep track of cookie values in CookieJar within the context of the
122
- # block; you need to set this up for secific controllers.
123
- #
124
- # ==== Parameters
125
- # *controller_classes:: Controller classes to operate on in the context of the block.
126
- # &blk:: The context to operate on; optionally accepts the cookie jar as an argument.
127
- def with_cookies(*controller_classes, &blk)
128
- cookie_jar = CookieJar.new
129
- before_cb = lambda { |c| c.cookies.update(cookie_jar) }
130
- after_cb = lambda { |c| cookie_jar.update_from_request(c.request) }
131
- controller_classes.each do |klass|
132
- klass._before_dispatch_callbacks << before_cb
133
- klass._after_dispatch_callbacks << after_cb
134
- end
135
- blk.arity == 1 ? blk.call(cookie_jar) : blk.call
136
- controller_classes.each do |klass|
137
- klass._before_dispatch_callbacks.delete before_cb
138
- klass._after_dispatch_callbacks.delete after_cb
139
- end
140
- end
141
-
142
- # Dispatches an action to the given class and using HTTP Basic Authentication
143
- # This bypasses the router and is suitable for unit testing of controllers.
144
- #
145
- # ==== Parameters
146
- # controller_klass<Controller>::
147
- # The controller class object that the action should be dispatched to.
148
- # action<Symbol>:: The action name, as a symbol.
149
- # username<String>:: The username.
150
- # password<String>:: The password.
151
- # params<Hash>::
152
- # An optional hash that will end up as params in the controller instance.
153
- # env<Hash>::
154
- # An optional hash that is passed to the fake request. Any request options
155
- # should go here (see +fake_request+), including :req or :post_body
156
- # for setting the request body itself.
157
- # &blk::
158
- # The controller is yielded to the block provided for actions *prior* to
159
- # the action being dispatched.
160
- #
161
- # ==== Example
162
- # dispatch_with_basic_authentication_to(MyController, :create, 'Fred', 'secret', :name => 'Homer' ) do |controller|
163
- # controller.stub!(:current_user).and_return(@user)
164
- # end
165
- #
166
- # ==== Notes
167
- # Does not use routes.
168
- #
169
- #---
170
- # @public
171
- def dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk)
172
- env["X_HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{username}:#{password}")}"
173
-
174
- params = merge_controller_and_action(controller_klass, action, params)
175
- dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
176
- end
177
-
178
- def merge_controller_and_action(controller_klass, action, params)
179
- params[:controller] = controller_klass.name.to_const_path
180
- params[:action] = action.to_s
181
-
182
- params
183
- end
184
-
185
- # Prepares and returns a request suitable for dispatching with
186
- # dispatch_request. If you don't need to modify the request
187
- # object before dispatching (e.g. to add cookies), you probably
188
- # want to use dispatch_to instead.
189
- #
190
- # ==== Parameters
191
- # params<Hash>::
192
- # An optional hash that will end up as params in the controller instance.
193
- # env<Hash>::
194
- # An optional hash that is passed to the fake request. Any request options
195
- # should go here (see +fake_request+), including :req or :post_body
196
- # for setting the request body itself.
197
- #
198
- # ==== Example
199
- # req = build_request(:id => 1)
200
- # req.cookies['app_cookie'] = "testing"
201
- # dispatch_request(req, MyController, :edit)
202
- #
203
- # ==== Notes
204
- # Does not use routes.
205
- #
206
- #---
207
- # @public
208
- def build_request(params = {}, env = {})
209
- params = Merb::Request.params_to_query_string(params)
210
-
211
- query_string = env[:query_string] || env['QUERY_STRING']
212
- env[:query_string] = query_string ? "#{query_string}&#{params}" : params
213
-
214
- post_body = env[:post_body] || env['POST_BODY']
215
- fake_request(env, { :post_body => post_body, :req => env[:req] })
21
+ def status_code(input)
22
+ input.respond_to?(:status) ? input.status : input
216
23
  end
217
24
 
218
- # An HTTP GET request that operates through the router.
219
- #
220
- # ==== Parameters
221
- # path<String>:: The path that should go to the router as the request uri.
222
- # params<Hash>::
223
- # An optional hash that will end up as params in the controller instance.
224
- # env<Hash>::
225
- # An optional hash that is passed to the fake request. Any request options
226
- # should go here (see +fake_request+).
227
- # &blk::
228
- # The controller is yielded to the block provided for actions *prior* to
229
- # the action being dispatched.
230
- #---
231
- # @public
232
- def get(path, params = {}, env = {}, &block)
233
- env[:request_method] = "GET"
234
- request(path, params, env, &block)
235
- end
236
-
237
- # An HTTP POST request that operates through the router.
238
- #
239
- # ==== Parameters
240
- # path<String>:: The path that should go to the router as the request uri.
241
- # params<Hash>::
242
- # An optional hash that will end up as params in the controller instance.
243
- # env<Hash>::
244
- # An optional hash that is passed to the fake request. Any request options
245
- # should go here (see fake_request).
246
- # &blk::
247
- # The controller is yielded to the block provided for actions *prior* to
248
- # the action being dispatched.
249
- #---
250
- # @public
251
- def post(path, params = {}, env = {}, &block)
252
- env[:request_method] = "POST"
253
- request(path, params, env, &block)
254
- end
255
-
256
- # An HTTP PUT request that operates through the router.
257
- #
258
- # ==== Parameters
259
- # path<String>:: The path that should go to the router as the request uri.
260
- # params<Hash>::
261
- # An optional hash that will end up as params in the controller instance.
262
- # env<Hash>::
263
- # An optional hash that is passed to the fake request. Any request options
264
- # should go here (see fake_request).
265
- # &blk::
266
- # The controller is yielded to the block provided for actions *prior* to
267
- # the action being dispatched.
268
- #---
269
- # @public
270
- def put(path, params = {}, env = {}, &block)
271
- env[:request_method] = "PUT"
272
- request(path, params, env, &block)
273
- end
25
+ def request(uri, env = {})
26
+ uri = url(uri) if uri.is_a?(Symbol)
274
27
 
275
- # An HTTP DELETE request that operates through the router
276
- #
277
- # ==== Parameters
278
- # path<String>:: The path that should go to the router as the request uri.
279
- # params<Hash>::
280
- # An optional hash that will end up as params in the controller instance.
281
- # env<Hash>::
282
- # An optional hash that is passed to the fake request. Any request options
283
- # should go here (see fake_request).
284
- # &blk::
285
- # The controller is yielded to the block provided for actions *prior* to
286
- # the action being dispatched.
287
- #---
288
- # @public
289
- def delete(path, params = {}, env = {}, &block)
290
- env[:request_method] = "DELETE"
291
- request(path, params, env, &block)
292
- end
293
-
294
- # A generic request that checks the router for the controller and action.
295
- # This request goes through the Merb::Router and finishes at the controller.
296
- #
297
- # ==== Parameters
298
- # path<String>:: The path that should go to the router as the request uri.
299
- # params<Hash>::
300
- # An optional hash that will end up as params in the controller instance.
301
- # env<Hash>::
302
- # An optional hash that is passed to the fake request. Any request options
303
- # should go here (see +fake_request+).
304
- # &blk::
305
- # The controller is yielded to the block provided for actions *prior* to
306
- # the action being dispatched.
307
- #
308
- # ==== Example
309
- # request(path, { :name => 'Homer' }, { :request_method => "PUT" }) do |controller|
310
- # controller.stub!(:current_user).and_return(@user)
311
- # end
312
- #
313
- # ==== Notes
314
- # Uses Routes.
315
- #
316
- #---
317
- # @semi-public
318
- def request(path, params = {}, env= {}, &block)
319
- env[:request_method] ||= "GET"
320
- env[:request_uri], env[:query_string] = path.split('?')
321
-
322
- multipart = env.delete(:test_with_multipart)
323
-
324
- request = build_request(params, env)
28
+ if (env[:method] == "POST" || env["REQUEST_METHOD"] == "POST")
29
+ params = env.delete(:body_params) if env.key?(:body_params)
30
+ params = env.delete(:params) if env.key?(:params) && !env.key?(:input)
31
+
32
+ unless env.key?(:input)
33
+ env[:input] = Merb::Request.params_to_query_string(params)
34
+ env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
35
+ end
36
+ end
325
37
 
326
- opts = check_request_for_route(request) # Check that the request will be routed correctly
327
- controller_name = (opts[:namespace] ? opts.delete(:namespace) + '/' : '') + opts.delete(:controller)
328
- klass = Object.full_const_get(controller_name.snake_case.to_const_string)
329
-
330
- action = opts.delete(:action).to_s
331
- params.merge!(opts)
38
+ if env[:params]
39
+ uri << "&#{Merb::Request.params_to_query_string(env.delete(:body_params))}"
40
+ end
332
41
 
333
- multipart.nil? ? dispatch_to(klass, action, params, env, &block) : dispatch_multipart_to(klass, action, params, env, &block)
334
- end
42
+ if @__cookie__
43
+ env["HTTP_COOKIE"] = @__cookie__
44
+ end
335
45
 
46
+ app = Merb::Rack::Application.new
47
+ rack = app.call(::Rack::MockRequest.env_for(uri, env))
336
48
 
337
- # The workhorse for the dispatch*to helpers.
338
- #
339
- # ==== Parameters
340
- # request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>::
341
- # A request object that has been setup for testing.
342
- # controller_klass<Merb::Controller>::
343
- # The class object off the controller to dispatch the action to.
344
- # action<Symbol>:: The action to dispatch the request to.
345
- # &blk::
346
- # The controller is yielded to the block provided for actions *prior* to
347
- # the action being dispatched.
348
- #
349
- # ==== Returns
350
- # An instance of +controller_klass+ based on the parameters.
351
- #
352
- # ==== Notes
353
- # Does not use routes.
354
- #
355
- #---
356
- # @public
357
- def dispatch_request(request, controller_klass, action, &blk)
358
- controller = controller_klass.new(request)
359
- yield controller if block_given?
360
- controller._dispatch(action)
49
+ rack = Struct.new(:status, :headers, :body, :url, :original_env).
50
+ new(rack[0], rack[1], rack[2], uri, env)
361
51
 
362
- Merb.logger.info controller._benchmarks.inspect
363
- Merb.logger.flush
52
+ @__cookie__ = rack.headers["Set-Cookie"] && rack.headers["Set-Cookie"].join
364
53
 
365
- controller
54
+ rack
366
55
  end
367
-
368
- # Checks to see that a request is routable.
369
- #
370
- # ==== Parameters
371
- # request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>::
372
- # The request object to inspect.
373
- #
374
- # ==== Raises
375
- # Merb::ControllerExceptions::BadRequest::
376
- # No matching route was found.
377
- #
378
- # ==== Returns
379
- # Hash:: The parameters built based on the matching route.
380
- #
381
- #---
382
- # @semi-public
383
- def check_request_for_route(request)
384
- match = ::Merb::Router.match(request)
385
- if match[0].nil? && match[1].empty?
386
- raise ::Merb::ControllerExceptions::BadRequest, "No routes match the request. Request uri: #{request.uri}"
387
- else
388
- match[1]
389
- end
390
- end # check_request_for_route
391
- end # RequestHelper
392
- end # Test
393
- end # Merb
56
+ alias requesting request
57
+ alias response_for request
58
+
59
+ end
60
+ end
61
+ end