mack 0.5.5.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/README +1 -1
- data/bin/mack +7 -2
- data/lib/controller/controller.rb +371 -0
- data/lib/controller/cookie_jar.rb +2 -1
- data/lib/controller/filter.rb +3 -2
- data/lib/controller/request.rb +30 -26
- data/lib/controller/session.rb +5 -0
- data/lib/distributed/utils/rinda.rb +1 -1
- data/lib/errors/errors.rb +5 -3
- data/lib/generators/mack_application_generator/mack_application_generator.rb +4 -0
- data/lib/generators/mack_application_generator/manifest.yml +40 -7
- data/lib/generators/mack_application_generator/templates/Rakefile.template +5 -1
- data/lib/generators/mack_application_generator/templates/app/controllers/default_controller.rb.template +2 -1
- data/lib/generators/mack_application_generator/templates/app/helpers/controllers/default_controller_helper.rb.template +7 -0
- data/lib/generators/mack_application_generator/templates/app/helpers/views/application_helper.rb.template +7 -0
- data/lib/generators/mack_application_generator/templates/config/app_config/default.yml.template +2 -1
- data/lib/generators/mack_application_generator/templates/config/database.yml.template +11 -10
- data/lib/generators/mack_application_generator/templates/test/functional/default_controller_spec.rb.template +9 -0
- data/lib/generators/mack_application_generator/templates/test/functional/default_controller_test.rb.template +10 -0
- data/lib/generators/mack_application_generator/templates/test/spec.opts.template +2 -0
- data/lib/generators/mack_application_generator/templates/test/spec_helper.rb.template +8 -0
- data/lib/generators/mack_application_generator/templates/test/test_helper.rb.template +2 -1
- data/lib/initialization/application.rb +46 -0
- data/lib/initialization/configuration.rb +23 -38
- data/lib/initialization/console.rb +5 -2
- data/lib/initialization/helpers.rb +31 -0
- data/lib/initialization/logging.rb +69 -15
- data/lib/initialization/orm_support.rb +10 -4
- data/lib/initialization/plugins.rb +1 -1
- data/lib/mack.rb +18 -76
- data/lib/mack_tasks.rb +4 -1
- data/lib/rendering/engine/erubis.rb +1 -1
- data/lib/rendering/engine/registry.rb +5 -5
- data/lib/rendering/type/action.rb +3 -2
- data/lib/rendering/type/base.rb +1 -1
- data/lib/rendering/type/layout.rb +2 -2
- data/lib/rendering/type/partial.rb +1 -1
- data/lib/rendering/type/public.rb +1 -1
- data/lib/rendering/type/template.rb +1 -1
- data/lib/rendering/type/url.rb +4 -4
- data/lib/rendering/type/xml.rb +3 -2
- data/lib/rendering/view_template.rb +7 -7
- data/lib/routing/route_map.rb +27 -5
- data/lib/routing/urls.rb +1 -0
- data/lib/runner.rb +52 -17
- data/lib/tasks/cachetastic_tasks.rake +2 -2
- data/lib/tasks/mack_server_tasks.rake +2 -4
- data/lib/tasks/mack_update_tasks.rake +26 -0
- data/lib/tasks/rake_rules.rake +6 -2
- data/lib/tasks/test_tasks.rake +28 -10
- data/lib/testing/helpers.rb +187 -0
- data/lib/testing/response.rb +49 -0
- data/lib/testing/rspec.rb +20 -0
- data/lib/testing/test_assertions.rb +55 -0
- data/lib/{test_extensions → testing}/test_case.rb +9 -7
- data/lib/utils/crypt/keeper.rb +1 -1
- data/lib/utils/server.rb +2 -2
- data/lib/view_helpers/html_helpers.rb +4 -0
- metadata +26 -40
- data/lib/controller/base.rb +0 -345
- data/lib/generators/mack_application_generator/templates/app/helpers/application_helper.rb.template +0 -2
- data/lib/generators/mack_application_generator/templates/config/thin.ru.template +0 -1
- data/lib/generators/mack_application_generator/templates/config/thin.yml.template +0 -8
- data/lib/rendering/engine/haml.rb +0 -18
- data/lib/rendering/engine/markaby.rb +0 -28
- data/lib/test_extensions/test_assertions.rb +0 -55
- data/lib/test_extensions/test_helpers.rb +0 -192
data/lib/routing/route_map.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'singleton'
|
2
1
|
module Mack
|
3
2
|
|
4
3
|
module Routes
|
@@ -8,7 +7,7 @@ module Mack
|
|
8
7
|
# See Mack::Routes::RouteMap for more information.
|
9
8
|
def self.build
|
10
9
|
yield Mack::Routes::RouteMap.instance
|
11
|
-
Mack::Routes::Urls.include_safely_into(Mack::Controller
|
10
|
+
Mack::Routes::Urls.include_safely_into(Mack::Controller,
|
12
11
|
Mack::Rendering::ViewTemplate,
|
13
12
|
Test::Unit::TestCase,
|
14
13
|
Mack::Distributed::Routes::Urls)
|
@@ -129,12 +128,25 @@ module Mack
|
|
129
128
|
# hello_world_url # => "/"
|
130
129
|
# hello_world_full_url # => "http://example.org/"
|
131
130
|
# These methods act just like the ones created when you use the resource method.
|
131
|
+
#
|
132
|
+
# === Exception Routes:
|
133
|
+
# You can define a route that will catch exceptions that are raised in other controllers.
|
134
|
+
#
|
135
|
+
# Mack::Routes.build do |r|
|
136
|
+
# r.handle_error Mack::ResourceNotFound, :controller => :oops, :action => :404
|
137
|
+
# r.handle_error HollyCrapError, :controller => :oops, :action => :500
|
138
|
+
# end
|
139
|
+
# In the example if an action raises a Mack::ResourceNotFound it will be caught and rendered
|
140
|
+
# using the OopsController and the 404 action.
|
141
|
+
# If A HollyCrapError is thrown it will be caught and rendered using the OopsController and the 500 action.
|
142
|
+
# You can catch all exceptions using Exception.
|
132
143
|
class RouteMap
|
133
144
|
include Singleton
|
134
145
|
|
135
146
|
def initialize # :nodoc:
|
136
147
|
@routes_list = []
|
137
148
|
@default_routes_list = []
|
149
|
+
@handle_error_routes = {}
|
138
150
|
end
|
139
151
|
|
140
152
|
# Creates 'Rails' style default mappings:
|
@@ -158,7 +170,6 @@ module Mack
|
|
158
170
|
|
159
171
|
# Sets up mappings and named routes for a resource.
|
160
172
|
def resource(controller)
|
161
|
-
|
162
173
|
connect_with_named_route("#{controller}_index", "/#{controller}", {:controller => controller, :action => :index, :method => :get})
|
163
174
|
connect_with_named_route("#{controller}_create", "/#{controller}", {:controller => controller, :action => :create, :method => :post})
|
164
175
|
connect_with_named_route("#{controller}_new", "/#{controller}/new", {:controller => controller, :action => :new, :method => :get})
|
@@ -168,6 +179,10 @@ module Mack
|
|
168
179
|
connect_with_named_route("#{controller}_delete", "/#{controller}/:id", {:controller => controller, :action => :delete, :method => :delete})
|
169
180
|
end
|
170
181
|
|
182
|
+
def handle_error(error, options = {})
|
183
|
+
@handle_error_routes[error] = options
|
184
|
+
end
|
185
|
+
|
171
186
|
def method_missing(sym, *args) # :nodoc:
|
172
187
|
connect_with_named_route(sym, args.first, args.last)
|
173
188
|
end
|
@@ -182,7 +197,7 @@ module Mack
|
|
182
197
|
unless pattern == "/"
|
183
198
|
pattern.chop! if pattern.match(/\/$/)
|
184
199
|
end
|
185
|
-
meth = (req.params
|
200
|
+
meth = (req.params["_method"] || req.request_method.downcase).to_sym
|
186
201
|
rt = routes_list.dup
|
187
202
|
rt << @default_routes_list.dup
|
188
203
|
rt.flatten!
|
@@ -202,6 +217,12 @@ module Mack
|
|
202
217
|
raise Mack::Errors::UndefinedRoute.new(req)
|
203
218
|
end # get
|
204
219
|
|
220
|
+
# Given an error class name it will return a routing options Hash, or nil, if one
|
221
|
+
# has not been mapped.
|
222
|
+
def get_route_from_error(error)
|
223
|
+
@handle_error_routes[error]
|
224
|
+
end
|
225
|
+
|
205
226
|
attr_reader :routes_list # :nodoc:
|
206
227
|
|
207
228
|
private
|
@@ -212,7 +233,8 @@ module Mack
|
|
212
233
|
# if the pattern doesn't start with /, then add it.
|
213
234
|
pattern = "/" << pattern unless pattern.match(/^\//)
|
214
235
|
pt = pattern.downcase
|
215
|
-
Route.new(pt, regex_from_pattern(pt), meth, options)
|
236
|
+
route = Route.new(pt, regex_from_pattern(pt), meth, options)
|
237
|
+
route
|
216
238
|
end
|
217
239
|
|
218
240
|
def connect_with_named_route(n_route, pattern, options = {})
|
data/lib/routing/urls.rb
CHANGED
data/lib/runner.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'routing', 'urls')
|
1
2
|
module Mack
|
2
3
|
# This is the heart and soul of the Mack framework! This class interfaces with the Rack framework.
|
3
4
|
# It handles all the dispatching back and forth between the Rack framework and a Mack application.
|
@@ -19,27 +20,59 @@ module Mack
|
|
19
20
|
# because the route is specified to be a redirect, let's do that:
|
20
21
|
redirect_to(route)
|
21
22
|
else
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
self.request.all_params[:original_controller] = route[:controller]
|
24
|
+
self.request.all_params[:original_action] = route[:action]
|
25
|
+
run_controller(route)
|
26
|
+
end
|
27
|
+
# rescue Mack::Errors::ResourceNotFound, Mack::Errors::UndefinedRoute => e
|
28
|
+
# return try_to_find_resource(env, e)
|
29
|
+
rescue Exception => e
|
30
|
+
route = Mack::Routes::RouteMap.instance.get_route_from_error(e.class)
|
31
|
+
unless route.nil?
|
32
|
+
run_controller(route, e)
|
33
|
+
else
|
34
|
+
if e.class == Mack::Errors::ResourceNotFound || e.class == Mack::Errors::UndefinedRoute
|
35
|
+
return try_to_find_resource(env, e)
|
36
|
+
else
|
37
|
+
raise e
|
27
38
|
end
|
28
|
-
c = cont.new(self.request, self.response, self.cookies)
|
29
|
-
self.response.controller = c
|
30
|
-
self.response.write(c.run)
|
31
39
|
end
|
32
|
-
rescue Mack::Errors::ResourceNotFound, Mack::Errors::UndefinedRoute => e
|
33
|
-
return try_to_find_resource(env, e)
|
34
40
|
end
|
35
41
|
end # setup
|
36
42
|
rescue Exception => e
|
37
|
-
|
43
|
+
Mack.logger.error(e)
|
38
44
|
raise e
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
42
|
-
|
48
|
+
#--
|
49
|
+
# This method gets called after the session has been established. Override this method
|
50
|
+
# to add custom code around requests.
|
51
|
+
# def custom_dispatch_wrapper
|
52
|
+
# yield
|
53
|
+
# end
|
54
|
+
#++
|
55
|
+
|
56
|
+
#private
|
57
|
+
def run_controller(route, e = nil)
|
58
|
+
# let's handle a normal request:
|
59
|
+
begin
|
60
|
+
cont = "#{route[:controller].to_s.camelcase}Controller".constantize
|
61
|
+
rescue NameError => e
|
62
|
+
raise Mack::Errors::ResourceNotFound.new(self.request.path_info)
|
63
|
+
end
|
64
|
+
self.request.all_params[:controller] = route[:controller]
|
65
|
+
self.request.all_params[:action] = route[:action]
|
66
|
+
self.request.instance_variable_set("@params_controller", nil)
|
67
|
+
self.request.instance_variable_set("@params_action", nil)
|
68
|
+
|
69
|
+
c = cont.new(self.request, self.response, self.cookies)
|
70
|
+
c.caught_exception = e unless e.nil?
|
71
|
+
|
72
|
+
self.response.controller = c
|
73
|
+
self.response.write(c.run)
|
74
|
+
end
|
75
|
+
|
43
76
|
def log_request
|
44
77
|
s_time = Time.now
|
45
78
|
x = yield
|
@@ -48,12 +81,12 @@ module Mack
|
|
48
81
|
if app_config.log.detailed_requests
|
49
82
|
msg = "\n\t[#{@request.request_method.upcase}] '#{@request.path_info}'\n"
|
50
83
|
msg << "\tSession ID: #{@request.session.id}\n"
|
51
|
-
msg << "\tParameters: #{@request.all_params
|
84
|
+
msg << "\tParameters: #{@request.all_params}\n"
|
52
85
|
msg << "\tCompleted in #{p_time} (#{(1 / p_time).round} reqs/sec) | #{@response.status} [#{@request.full_host}]"
|
53
86
|
else
|
54
87
|
msg = "[#{@request.request_method.upcase}] '#{@request.path_info}' (#{p_time})"
|
55
88
|
end
|
56
|
-
|
89
|
+
Mack.logger.info(msg)
|
57
90
|
x
|
58
91
|
end
|
59
92
|
|
@@ -67,7 +100,9 @@ module Mack
|
|
67
100
|
@cookies = Mack::CookieJar.new(self.request, self.response)
|
68
101
|
session do
|
69
102
|
begin
|
70
|
-
|
103
|
+
# custom_dispatch_wrapper do
|
104
|
+
yield
|
105
|
+
# end
|
71
106
|
rescue Exception => e
|
72
107
|
exception = e
|
73
108
|
end
|
@@ -111,8 +146,8 @@ module Mack
|
|
111
146
|
if File.extname(env["PATH_INFO"]).blank?
|
112
147
|
env["PATH_INFO"] << ".html"
|
113
148
|
end
|
114
|
-
if File.exists?(File.join(Mack
|
115
|
-
return Rack::File.new(File.join(Mack
|
149
|
+
if File.exists?(File.join(Mack.root, "public", env["PATH_INFO"]))
|
150
|
+
return Rack::File.new(File.join(Mack.root, "public")).call(env)
|
116
151
|
else
|
117
152
|
raise exception
|
118
153
|
end
|
@@ -10,7 +10,7 @@ namespace :cachetastic do
|
|
10
10
|
when "All"
|
11
11
|
puts "About to work on ALL caches!"
|
12
12
|
# force all caches to register themselves:
|
13
|
-
["#{Mack
|
13
|
+
["#{Mack.root}/lib/caches"].each do |dir|
|
14
14
|
Find.find(dir) do |f|
|
15
15
|
# puts f
|
16
16
|
if FileTest.directory?(f) and !f.match(/.svn/)
|
@@ -48,7 +48,7 @@ namespace :cachetastic do
|
|
48
48
|
rescue MethodNotImplemented => e
|
49
49
|
msg = "Cachetastic.rake Warning: cache #{cache} does not implement #{action}. This is probably an error."
|
50
50
|
puts msg
|
51
|
-
|
51
|
+
Mack.logger.warning(msg)
|
52
52
|
rescue NoMethodError => e
|
53
53
|
rescue Exception => e
|
54
54
|
raise e
|
@@ -12,20 +12,18 @@ namespace :mack do
|
|
12
12
|
require 'fileutils'
|
13
13
|
|
14
14
|
require 'thin'
|
15
|
-
|
16
|
-
Mack::Configuration.set(:root, FileUtils.pwd) if Mack::Configuration.root.nil?
|
17
15
|
|
18
16
|
options = OpenStruct.new
|
19
17
|
options.port = (ENV["PORT"] ||= "3000") # Does NOT work with Thin!! You must edit the thin.yml file!
|
20
18
|
options.handler = (ENV["HANDLER"] ||= "thin")
|
21
19
|
|
22
20
|
|
23
|
-
# require File.join(Mack
|
21
|
+
# require File.join(Mack.root, "config", "boot.rb")
|
24
22
|
require 'mack'
|
25
23
|
|
26
24
|
if options.handler == "thin"
|
27
25
|
# thin_opts = ["start", "-r", "config/thin.ru"]
|
28
|
-
thin_opts = ["start"
|
26
|
+
thin_opts = ["start"]
|
29
27
|
Thin::Runner.new(thin_opts.flatten).run!
|
30
28
|
else
|
31
29
|
Mack::SimpleServer.run(options)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
namespace :mack do
|
2
|
+
|
3
|
+
namespace :update do
|
4
|
+
|
5
|
+
# desc "Renames thin.ru to rackup.ru and updates your thin.yml, if necessary."
|
6
|
+
# task :rackup do
|
7
|
+
# require 'fileutils'
|
8
|
+
# ru = File.join(Mack.root, "config", "thin.ru")
|
9
|
+
# if File.exists?(ru)
|
10
|
+
# FileUtils.mv(ru, File.join(Mack.root, "config", "rackup.ru"))
|
11
|
+
# end
|
12
|
+
# thin_yml = File.join(Mack.root, "config", "thin.yml")
|
13
|
+
# if File.exists?(thin_yml)
|
14
|
+
# contents = File.open(thin_yml).read
|
15
|
+
# contents.gsub!("thin.ru", "rackup.ru")
|
16
|
+
# File.open(thin_yml, "w") do |f|
|
17
|
+
# f.puts contents
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
# alias_task "mack:update", "mack:update:rackup"
|
data/lib/tasks/rake_rules.rake
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
rule /\#.*/ do |t|
|
2
2
|
env = t.name.match(/\#.*/).to_s.gsub("#", "")
|
3
|
-
|
3
|
+
ENV["MACK_ENV"] = env
|
4
4
|
name = t.name.gsub("##{env}", "")
|
5
5
|
Rake::Task[name].invoke
|
6
6
|
end
|
@@ -22,4 +22,8 @@ rule /^generate:/ do |t|
|
|
22
22
|
Rake::Task["environment"].invoke
|
23
23
|
klass = "#{klass.camelcase}Generator"
|
24
24
|
gen = klass.constantize.run(ENV.to_hash)
|
25
|
-
end
|
25
|
+
end
|
26
|
+
|
27
|
+
rule /^test:rspec/ do |t|
|
28
|
+
raise "i'm running a test task!"
|
29
|
+
end
|
data/lib/tasks/test_tasks.rake
CHANGED
@@ -1,16 +1,31 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
t.pattern = 'test/**/*_test.rb'
|
6
|
-
t.verbose = true
|
7
|
-
end
|
1
|
+
require 'rake'
|
2
|
+
require 'pathname'
|
3
|
+
require 'spec'
|
4
|
+
require 'spec/rake/spectask'
|
8
5
|
|
9
6
|
namespace :test do
|
10
7
|
|
8
|
+
task :setup do
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Run test code."
|
12
|
+
Rake::TestTask.new(:test_case) do |t|
|
13
|
+
t.libs << "test"
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = true
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Run specifications'
|
19
|
+
Spec::Rake::SpecTask.new(:rspec) do |t|
|
20
|
+
t.spec_opts << '--options' << 'test/spec.opts' if File.exists?('test/spec.opts')
|
21
|
+
t.spec_files = Dir.glob('test/**/*_spec.rb')
|
22
|
+
end
|
23
|
+
|
11
24
|
desc "Report code statistics (KLOCs, etc) from the application. Requires the rcov gem."
|
12
25
|
task :stats do |t|
|
13
|
-
|
26
|
+
ENV["MACK_ENV"] = "test"
|
27
|
+
Rake::Task["mack:environment"].invoke
|
28
|
+
x = `rcov test/**/*_#{app_config.mack.testing_framework == "rspec" ? "spec" : "test"}.rb -T --no-html -x Rakefile,config\/`
|
14
29
|
@print = false
|
15
30
|
x.each do |line|
|
16
31
|
puts line if @print
|
@@ -24,7 +39,9 @@ namespace :test do
|
|
24
39
|
|
25
40
|
desc "Generates test coverage from the application. Requires the rcov gem."
|
26
41
|
task :coverage do |t|
|
27
|
-
|
42
|
+
ENV["MACK_ENV"] = "test"
|
43
|
+
Rake::Task["mack:environment"].invoke
|
44
|
+
`rcov test/**/*_#{app_config.mack.testing_framework == "rspec" ? "spec" : "test"}.rb -x Rakefile,config\/`
|
28
45
|
`open coverage/index.html`
|
29
46
|
end
|
30
47
|
|
@@ -38,6 +55,7 @@ namespace :test do
|
|
38
55
|
|
39
56
|
end
|
40
57
|
|
41
|
-
|
58
|
+
|
59
|
+
alias_task :default, ["test:setup", "test:rspec"]
|
42
60
|
alias_task :stats, "test:stats"
|
43
61
|
alias_task :coverage, "test:coverage"
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
|
3
|
+
module Mack
|
4
|
+
module Testing # :nodoc:
|
5
|
+
module Helpers
|
6
|
+
|
7
|
+
# Runs the given rake task. Takes an optional hash that mimics command line parameters.
|
8
|
+
def rake_task(name, env = {}, tasks = [])
|
9
|
+
# set up the Rake application
|
10
|
+
rake = Rake::Application.new
|
11
|
+
Rake.application = rake
|
12
|
+
|
13
|
+
[File.join(File.dirname(__FILE__), "..", "mack_tasks.rb"), tasks].flatten.each do |task|
|
14
|
+
load(task)
|
15
|
+
end
|
16
|
+
|
17
|
+
# save the old ENV so we can revert it
|
18
|
+
old_env = ENV.to_hash
|
19
|
+
# add in the new ENV stuff
|
20
|
+
env.each_pair {|k,v| ENV[k.to_s] = v}
|
21
|
+
|
22
|
+
begin
|
23
|
+
# run the rake task
|
24
|
+
rake[name].invoke
|
25
|
+
|
26
|
+
# yield for the tests
|
27
|
+
yield if block_given?
|
28
|
+
|
29
|
+
rescue Exception => e
|
30
|
+
raise e
|
31
|
+
ensure
|
32
|
+
# empty out the ENV
|
33
|
+
ENV.clear
|
34
|
+
# revert to the ENV before the test started
|
35
|
+
old_env.to_hash.each_pair {|k,v| ENV[k] = v}
|
36
|
+
|
37
|
+
# get rid of the Rake application
|
38
|
+
Rake.application = nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Temporarily changes the application configuration. Changes are reverted after
|
43
|
+
# the yield returns.
|
44
|
+
def temp_app_config(options = {})
|
45
|
+
app_config.load_hash(options, String.randomize)
|
46
|
+
yield
|
47
|
+
app_config.revert
|
48
|
+
end
|
49
|
+
|
50
|
+
def remote_test # :nodoc:
|
51
|
+
if (app_config.run_remote_tests)
|
52
|
+
yield
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Retrieves an instance variable from the controller from a request.
|
57
|
+
def assigns(key)
|
58
|
+
$mack_app.instance_variable_get("@app").instance_variable_get("@response").instance_variable_get("@controller").instance_variable_get("@#{key}")
|
59
|
+
end
|
60
|
+
|
61
|
+
# Performs a 'get' request for the specified uri.
|
62
|
+
def get(uri, options = {})
|
63
|
+
build_response(request.get(uri, build_request_options(options)))
|
64
|
+
end
|
65
|
+
|
66
|
+
# Performs a 'put' request for the specified uri.
|
67
|
+
def put(uri, options = {})
|
68
|
+
build_response(request.put(uri, build_request_options({:input => options.to_params})))
|
69
|
+
end
|
70
|
+
|
71
|
+
# Performs a 'post' request for the specified uri.
|
72
|
+
def post(uri, options = {})
|
73
|
+
build_response(request.post(uri, build_request_options({:input => options.to_params})))
|
74
|
+
end
|
75
|
+
|
76
|
+
# Performs a 'delete' request for the specified uri.
|
77
|
+
def delete(uri, options = {})
|
78
|
+
build_response(request.delete(uri, build_request_options(options)))
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns a Rack::MockRequest. If there isn't one, a new one is created.
|
82
|
+
def request
|
83
|
+
@request ||= Rack::MockRequest.new(mack_app)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns the last Rack::MockResponse that got generated by a call.
|
87
|
+
def response
|
88
|
+
@testing_response
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns all the Rack::MockResponse objects that get generated by a call.
|
92
|
+
def responses
|
93
|
+
@responses
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns a Mack::Session from the request.
|
97
|
+
def session # :nodoc:
|
98
|
+
Cachetastic::Caches::MackSessionCache.get(cookies[app_config.mack.session_id]) do
|
99
|
+
id = String.randomize(40).downcase
|
100
|
+
set_cookie(app_config.mack.session_id, id)
|
101
|
+
sess = Mack::Session.new(id)
|
102
|
+
Cachetastic::Caches::MackSessionCache.set(id, sess)
|
103
|
+
sess
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Used to create a 'session' around a block of code. This is great of 'integration' tests.
|
108
|
+
def in_session
|
109
|
+
@_mack_in_session = true
|
110
|
+
clear_session
|
111
|
+
yield
|
112
|
+
clear_session
|
113
|
+
@_mack_in_session = false
|
114
|
+
end
|
115
|
+
|
116
|
+
# Clears all the sessions.
|
117
|
+
def clear_session
|
118
|
+
Cachetastic::Caches::MackSessionCache.expire_all
|
119
|
+
end
|
120
|
+
|
121
|
+
# Returns a Hash of cookies from the response.
|
122
|
+
def cookies
|
123
|
+
test_cookies
|
124
|
+
end
|
125
|
+
|
126
|
+
# Sets a cookie to be used for the next request
|
127
|
+
def set_cookie(name, value)
|
128
|
+
test_cookies[name] = value
|
129
|
+
end
|
130
|
+
|
131
|
+
# Removes a cookie.
|
132
|
+
def remove_cookie(name)
|
133
|
+
test_cookies.delete(name)
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
def test_cookies
|
138
|
+
@test_cookies = {} if @test_cookies.nil?
|
139
|
+
@test_cookies
|
140
|
+
end
|
141
|
+
|
142
|
+
def mack_app
|
143
|
+
if $mack_app.nil?
|
144
|
+
$mack_app = Rack::Recursive.new(Mack::Runner.new)
|
145
|
+
end
|
146
|
+
$mack_app
|
147
|
+
end
|
148
|
+
|
149
|
+
def build_request_options(options)
|
150
|
+
{"HTTP_COOKIE" => test_cookies.join("%s=%s", "; ")}.merge(options)
|
151
|
+
end
|
152
|
+
|
153
|
+
def build_response(res)
|
154
|
+
@responses = [res]
|
155
|
+
strip_cookies_from_response(res)
|
156
|
+
# only retry if it's a redirect request
|
157
|
+
if res.redirect?
|
158
|
+
until res.successful?
|
159
|
+
[res].flatten.each do |r|
|
160
|
+
strip_cookies_from_response(r)
|
161
|
+
end
|
162
|
+
res = request.get(res["Location"])
|
163
|
+
@responses << res
|
164
|
+
end
|
165
|
+
end
|
166
|
+
@testing_response = Mack::Testing::Response.new(@responses)
|
167
|
+
end
|
168
|
+
|
169
|
+
def strip_cookies_from_response(res)
|
170
|
+
unless res.original_headers["Set-Cookie"].nil?
|
171
|
+
res.original_headers["Set-Cookie"].each do |ck|
|
172
|
+
spt = ck.split("=")
|
173
|
+
name = spt.first
|
174
|
+
value = spt.last
|
175
|
+
if name == app_config.mack.session_id
|
176
|
+
value = nil unless @_mack_in_session
|
177
|
+
end
|
178
|
+
set_cookie(name, value)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end # Helpers
|
184
|
+
end # Testing
|
185
|
+
end # Mack
|
186
|
+
|
187
|
+
Test::Unit::TestCase.send(:include, Mack::Testing::Helpers)
|