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.
- data/CHANGELOG +136 -2
- data/CONTRIBUTORS +6 -0
- data/PUBLIC_CHANGELOG +15 -0
- data/Rakefile +12 -14
- data/lib/merb-core.rb +82 -43
- data/lib/merb-core/bootloader.rb +268 -60
- data/lib/merb-core/config.rb +119 -34
- data/lib/merb-core/controller/abstract_controller.rb +58 -18
- data/lib/merb-core/controller/exceptions.rb +2 -15
- data/lib/merb-core/controller/merb_controller.rb +28 -1
- data/lib/merb-core/controller/mime.rb +4 -0
- data/lib/merb-core/controller/mixins/controller.rb +14 -17
- data/lib/merb-core/controller/mixins/render.rb +23 -28
- data/lib/merb-core/controller/mixins/responder.rb +0 -1
- data/lib/merb-core/controller/template.rb +44 -20
- data/lib/merb-core/core_ext/kernel.rb +8 -3
- data/lib/merb-core/dispatch/default_exception/default_exception.rb +1 -1
- data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +3 -1
- data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +71 -67
- data/lib/merb-core/dispatch/default_exception/views/index.html.erb +6 -2
- data/lib/merb-core/dispatch/dispatcher.rb +5 -9
- data/lib/merb-core/dispatch/request.rb +46 -57
- data/lib/merb-core/dispatch/router.rb +83 -6
- data/lib/merb-core/dispatch/router/behavior.rb +87 -27
- data/lib/merb-core/dispatch/router/resources.rb +281 -167
- data/lib/merb-core/dispatch/router/route.rb +141 -27
- data/lib/merb-core/logger.rb +213 -202
- data/lib/merb-core/rack.rb +3 -1
- data/lib/merb-core/rack/adapter.rb +7 -4
- data/lib/merb-core/rack/adapter/ebb.rb +12 -13
- data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -15
- data/lib/merb-core/rack/adapter/irb.rb +3 -2
- data/lib/merb-core/rack/adapter/mongrel.rb +22 -15
- data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +4 -16
- data/lib/merb-core/rack/adapter/thin.rb +21 -22
- data/lib/merb-core/rack/adapter/thin_turbo.rb +4 -11
- data/lib/merb-core/rack/adapter/webrick.rb +54 -18
- data/lib/merb-core/rack/handler/mongrel.rb +12 -13
- data/lib/merb-core/rack/middleware/csrf.rb +1 -1
- data/lib/merb-core/server.rb +135 -98
- data/lib/merb-core/tasks/gem_management.rb +50 -12
- data/lib/merb-core/tasks/merb.rb +1 -0
- data/lib/merb-core/tasks/merb_rake_helper.rb +9 -38
- data/lib/merb-core/tasks/stats.rake +2 -2
- data/lib/merb-core/test.rb +9 -3
- data/lib/merb-core/test/helpers.rb +1 -0
- data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -2
- data/lib/merb-core/test/helpers/request_helper.rb +40 -372
- data/lib/merb-core/test/helpers/route_helper.rb +15 -7
- data/lib/merb-core/test/matchers.rb +1 -0
- data/lib/merb-core/test/matchers/controller_matchers.rb +4 -247
- data/lib/merb-core/test/matchers/view_matchers.rb +22 -4
- data/lib/merb-core/test/run_specs.rb +117 -25
- data/lib/merb-core/version.rb +1 -1
- metadata +1 -1
- data/lib/merb-core/vendor/facets.rb +0 -2
- data/lib/merb-core/vendor/facets/dictionary.rb +0 -433
- 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
|
-
|
71
|
+
error "Failed to install gem '#{gem} (#{version})' (#{exception.message})"
|
38
72
|
end
|
39
73
|
installer.installed_gems.each do |spec|
|
40
|
-
|
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
|
-
|
98
|
+
error "Failed to install gem '#{gem}' (#{e.message})"
|
65
99
|
end
|
66
100
|
installer.installed_gems.each do |spec|
|
67
|
-
|
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
|
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.
|
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
|
-
|
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
|
-
|
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
|
data/lib/merb-core/tasks/merb.rb
CHANGED
@@ -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}
|
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
|
data/lib/merb-core/test.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
153
|
+
mock_request(path, params, env, &block)
|
153
154
|
end
|
154
155
|
|
155
156
|
# ==== Parameters
|
@@ -1,393 +1,61 @@
|
|
1
|
-
require
|
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
|
-
|
11
|
-
#
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
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
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
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
|
-
|
327
|
-
|
328
|
-
|
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
|
-
|
334
|
-
|
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
|
-
|
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
|
-
|
363
|
-
Merb.logger.flush
|
52
|
+
@__cookie__ = rack.headers["Set-Cookie"] && rack.headers["Set-Cookie"].join
|
364
53
|
|
365
|
-
|
54
|
+
rack
|
366
55
|
end
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
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
|