mack 0.5.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/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)
|