merb-core 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/Rakefile +22 -13
  2. data/lib/merb-core/bootloader.rb +3 -2
  3. data/lib/merb-core/config.rb +1 -1
  4. data/lib/merb-core/constants.rb +3 -1
  5. data/lib/merb-core/controller/abstract_controller.rb +25 -39
  6. data/lib/merb-core/controller/exceptions.rb +14 -16
  7. data/lib/merb-core/controller/merb_controller.rb +2 -2
  8. data/lib/merb-core/controller/mime.rb +2 -1
  9. data/lib/merb-core/controller/mixins/render.rb +12 -0
  10. data/lib/merb-core/controller/mixins/responder.rb +31 -7
  11. data/lib/merb-core/core_ext/hash.rb +7 -0
  12. data/lib/merb-core/core_ext/kernel.rb +31 -34
  13. data/lib/merb-core/core_ext.rb +1 -0
  14. data/lib/merb-core/dispatch/default_exception/default_exception.rb +3 -3
  15. data/lib/merb-core/dispatch/dispatcher.rb +128 -135
  16. data/lib/merb-core/dispatch/request.rb +11 -11
  17. data/lib/merb-core/dispatch/router/behavior.rb +6 -6
  18. data/lib/merb-core/dispatch/router.rb +5 -5
  19. data/lib/merb-core/logger.rb +203 -202
  20. data/lib/merb-core/rack/application.rb +19 -5
  21. data/lib/merb-core/rack/middleware/conditional_get.rb +23 -0
  22. data/lib/merb-core/rack/middleware/content_length.rb +18 -0
  23. data/lib/merb-core/rack/middleware/tracer.rb +20 -0
  24. data/lib/merb-core/rack/middleware.rb +1 -7
  25. data/lib/merb-core/rack.rb +19 -16
  26. data/lib/merb-core/test/matchers/route_matchers.rb +1 -0
  27. data/lib/merb-core/test/matchers/view_matchers.rb +36 -0
  28. data/lib/merb-core/test/run_specs.rb +2 -1
  29. data/lib/merb-core/version.rb +1 -1
  30. data/lib/merb-core.rb +39 -33
  31. data/spec/private/config/merb_spec.rb +34 -0
  32. data/spec/private/dispatch/fixture/log/merb_test.log +372 -0
  33. data/spec/private/router/fixture/log/merb_test.log +42 -0
  34. data/spec/public/abstract_controller/controllers/filters.rb +50 -1
  35. data/spec/public/abstract_controller/filter_spec.rb +25 -0
  36. data/spec/public/controller/base_spec.rb +41 -1
  37. data/spec/public/controller/controllers/base.rb +16 -0
  38. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -1
  39. data/spec/public/controller/dispatcher_spec.rb +24 -25
  40. data/spec/public/controller/responder_spec.rb +6 -0
  41. data/spec/public/core_ext/kernel_spec.rb +79 -0
  42. data/spec/public/directory_structure/directory/log/merb_test.log +245 -0
  43. data/spec/public/rack/conditinal_get_middleware_spec.rb +139 -0
  44. data/spec/public/rack/rack_middleware_spec.rb +99 -0
  45. data/spec/public/rack/shared_example_groups.rb +35 -0
  46. data/spec/public/reloading/directory/log/merb_test.log +40 -0
  47. data/spec/public/request/request_spec.rb +0 -5
  48. data/spec/public/router/fixture/log/merb_test.log +348 -0
  49. data/spec/public/test/route_matchers_spec.rb +4 -0
  50. data/spec/spec_helper.rb +7 -1
  51. metadata +42 -5
  52. data/spec/private/plugins/plugin_spec.rb +0 -166
data/Rakefile CHANGED
@@ -59,13 +59,16 @@ spec = Gem::Specification.new do |s|
59
59
  #s.rdoc_options += RDOC_OPTS + ["--exclude", "^(app|uploads)"]
60
60
 
61
61
  # Dependencies
62
- s.add_dependency "extlib", ">=0.9.3"
62
+ s.add_dependency "extlib", ">=0.9.4"
63
63
  s.add_dependency "erubis"
64
64
  s.add_dependency "rake"
65
65
  s.add_dependency "json_pure"
66
66
  s.add_dependency "rspec"
67
67
  s.add_dependency "rack"
68
68
  s.add_dependency "mime-types"
69
+ s.add_dependency "hpricot"
70
+ s.add_development_dependency "libxml-ruby"
71
+ s.add_development_dependency "memcache-client"
69
72
  # Requirements
70
73
  s.requirements << "install the json gem to get faster json parsing"
71
74
  s.required_ruby_version = ">= 1.8.6"
@@ -80,6 +83,11 @@ task :install => :package do
80
83
  sh %{#{sudo} gem install #{install_home} --local pkg/#{GEM_NAME}-#{GEM_VERSION}.gem --no-rdoc --no-ri}
81
84
  end
82
85
 
86
+ desc "Install Merb with development dependencies"
87
+ task :dev_install => :package do
88
+ sh %{#{sudo} gem install #{install_home} --local pkg/#{GEM_NAME}-#{GEM_VERSION}.gem --no-rdoc --no-ri --development}
89
+ end
90
+
83
91
  desc "Run :package and install the resulting .gem with jruby"
84
92
  task :jinstall => :package do
85
93
  sh %{#{sudo} jruby -S gem install #{install_home} pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
@@ -176,7 +184,7 @@ task :aok => [:specs, :rcov]
176
184
  # t.spec_files = Dir["spec/**/*_spec.rb"].sort
177
185
  # end
178
186
 
179
- def setup_specs(name, spec_cmd='spec', run_opts = "-c -f s")
187
+ def setup_specs(name, spec_cmd='spec', run_opts = "-c")
180
188
  desc "Run all specs (#{name})"
181
189
  task "specs:#{name}" do
182
190
  run_specs("spec/**/*_spec.rb", spec_cmd, ENV['RSPEC_OPTS'] || run_opts)
@@ -212,9 +220,9 @@ end
212
220
  setup_specs("mri", "spec")
213
221
  setup_specs("jruby", "jruby -S spec")
214
222
 
215
- task "specs" => ["specs:mri"]
216
- task "specs:private" => ["specs:mri:private"]
217
- task "specs:public" => ["specs:mri:public"]
223
+ task "specs" => ["dev_install", "specs:mri"]
224
+ task "specs:private" => ["dev_install", "specs:mri:private"]
225
+ task "specs:public" => ["dev_install", "specs:mri:public"]
218
226
 
219
227
  desc "Run coverage suite"
220
228
  task :rcov do
@@ -233,7 +241,7 @@ end
233
241
 
234
242
  desc "Run a specific spec with TASK=xxxx"
235
243
  Spec::Rake::SpecTask.new("spec") do |t|
236
- t.spec_opts = ["--format", "specdoc", "--colour"]
244
+ t.spec_opts = ["--colour"]
237
245
  t.libs = ["lib", "server/lib" ]
238
246
  t.spec_files = (ENV["TASK"] || '').split(',').map do |task|
239
247
  "spec/**/#{task}_spec.rb"
@@ -313,9 +321,10 @@ namespace :repo do
313
321
 
314
322
  end
315
323
 
316
- def git_log(since_release = nil, log_format = "format:%an")
317
- git_log_query = "git log --pretty='format:#{log_format}' --no-merges"
318
- git_log_query << " --since='#{since_release}'" if since_release
324
+ def git_log(since_release = nil, log_format = "%an")
325
+ git_log_query = "git log"
326
+ git_log_query << " v#{since_release}..HEAD" if since_release
327
+ git_log_query << " --pretty='format:#{log_format}' --no-merges"
319
328
  puts
320
329
  puts "Running #{git_log_query}"
321
330
  puts
@@ -323,10 +332,10 @@ def git_log(since_release = nil, log_format = "format:%an")
323
332
  end
324
333
 
325
334
  def contributors(since_release = nil)
326
- @merb_contributors ||= git_log(since_release).split("\n").uniq.sort
335
+ git_log(since_release).split("\n").uniq.sort
327
336
  end
328
337
 
329
- PREVIOUS_RELEASE = '0.9.3'
338
+ PREVIOUS_RELEASE = '0.9.4'
330
339
  namespace :history do
331
340
  namespace :update do
332
341
  desc "updates contributors list"
@@ -360,7 +369,7 @@ namespace :history do
360
369
  namespace :current_release do
361
370
  desc "show changes since previous release"
362
371
  task :changes do
363
- puts git_log(PREVIOUS_RELEASE, "format:* %s")
372
+ puts git_log(PREVIOUS_RELEASE, "* %s")
364
373
  end
365
374
 
366
375
 
@@ -399,7 +408,7 @@ rule "" do |t|
399
408
 
400
409
  example = " -e '#{spec_name}'" unless spec_name.empty?
401
410
 
402
- sh "#{spec_cmd} #{run_file_name} --format specdoc --colour #{example}"
411
+ sh "#{spec_cmd} #{run_file_name} --colour #{example}"
403
412
  end
404
413
  end
405
414
 
@@ -542,7 +542,7 @@ class Merb::BootLoader::MimeTypes < Merb::BootLoader
542
542
  Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml], :charset => "utf-8")
543
543
  Merb.add_mime_type(:text, :to_text, %w[text/plain], :charset => "utf-8")
544
544
  Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html], :charset => "utf-8")
545
- Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :charset => "utf-8")
545
+ Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], {:charset => "utf-8"}, 0.9998)
546
546
  Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript], :charset => "utf-8")
547
547
  Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json], :charset => "utf-8")
548
548
  end
@@ -673,6 +673,7 @@ class Merb::BootLoader::RackUpApplication < Merb::BootLoader
673
673
  run Merb::Rack::Application.new
674
674
  }.to_app
675
675
  end
676
+
676
677
  end
677
678
  end
678
679
 
@@ -727,4 +728,4 @@ class Merb::BootLoader::ReloadTemplates < Merb::BootLoader
727
728
  Merb::Config[:reload_templates] = (Merb.environment == "development")
728
729
  end
729
730
  end
730
- end
731
+ end
@@ -1,5 +1,4 @@
1
1
  require "optparse"
2
- require "yaml"
3
2
 
4
3
  module Merb
5
4
 
@@ -93,6 +92,7 @@ module Merb
93
92
  # ==== Returns
94
93
  # String:: The config as YAML.
95
94
  def to_yaml
95
+ require "yaml"
96
96
  @configuration.to_yaml
97
97
  end
98
98
 
@@ -23,6 +23,8 @@ module Merb
23
23
  FORM_URL_ENCODED_REGEXP = %r{^application/x-www-form-urlencoded}.freeze
24
24
  UPCASE_CONTENT_TYPE = 'CONTENT_TYPE'.freeze
25
25
  CONTENT_TYPE = "Content-Type".freeze
26
+ DATE = 'Date'.freeze
27
+ ETAG = 'ETag'.freeze
26
28
  LAST_MODIFIED = "Last-Modified".freeze
27
29
  SLASH = "/".freeze
28
30
  REQUEST_METHOD = "REQUEST_METHOD".freeze
@@ -40,4 +42,4 @@ module Merb
40
42
  REQUEST_PATH = "REQUEST_PATH".freeze
41
43
  REMOTE_ADDR = "REMOTE_ADDR".freeze
42
44
  end
43
- end
45
+ end
@@ -26,38 +26,41 @@
26
26
  # ===== Examples
27
27
  # before :some_filter
28
28
  # before :authenticate, :exclude => [:login, :signup]
29
- # before :has_role, :with => ["Admin"], :exclude => [:index,:show]
29
+ # before :has_role, :with => ["Admin"], :exclude => [:index, :show]
30
30
  # before Proc.new {|c| c.some_method }, :only => :foo
31
- # before :authorize, :unless => logged_in?
31
+ # before :authorize, :unless => :logged_in?
32
32
  #
33
- # You can use either :only => :actionname or :exclude => [:this, :that]
34
- # but not both at once. :only will only run before the listed actions
35
- # and :exclude will run for every action that is not listed.
33
+ # You can use either <code>:only => :actionname</code> or
34
+ # <code>:exclude => [:this, :that]</code> but not both at once.
35
+ # <code>:only</code> will only run before the listed actions and
36
+ # <code>:exclude</code> will run for every action that is not listed.
36
37
  #
37
38
  # Merb's before filter chain is very flexible. To halt the filter chain you
38
- # use throw :halt. If throw is called with only one argument of :halt the
39
- # return of the method filters_halted will be what is rendered to the view.
40
- # You can overide filters_halted in your own controllers to control what it
41
- # outputs. But the throw construct is much more powerful then just that.
42
- # throw :halt can also take a second argument. Here is what that second arg
43
- # can be and the behavior each type can have:
39
+ # use <code>throw :halt</code>. If <code>throw</code> is called with only one
40
+ # argument of <code>:halt</code> the return value of the method
41
+ # <code>filters_halted</code> will be what is rendered to the view. You can
42
+ # override <code>filters_halted</code> in your own controllers to control what
43
+ # it outputs. But the <code>throw</code> construct is much more powerful than
44
+ # just that.
45
+ #
46
+ # <code>throw :halt</code> can also take a second argument. Here is what that
47
+ # second argument can be and the behavior each type can have:
44
48
  #
45
49
  # * +String+:
46
- # when the second arg is a string then that string will be what
47
- # is rendered to the browser. Since merb's render method returns
50
+ # when the second argument is a string then that string will be what
51
+ # is rendered to the browser. Since merb's <code>#render</code> method returns
48
52
  # a string you can render a template or just use a plain string:
49
53
  #
50
54
  # throw :halt, "You don't have permissions to do that!"
51
55
  # throw :halt, render(:action => :access_denied)
52
56
  #
53
57
  # * +Symbol+:
54
- # If the second arg is a symbol then the method named after that
58
+ # If the second arg is a symbol, then the method named after that
55
59
  # symbol will be called
56
60
  #
57
- # throw :halt, :must_click_disclaimer
61
+ # throw :halt, :must_click_disclaimer
58
62
  #
59
63
  # * +Proc+:
60
- #
61
64
  # If the second arg is a Proc, it will be called and its return
62
65
  # value will be what is rendered to the browser:
63
66
  #
@@ -86,9 +89,9 @@
86
89
  # Filter:: <Array[Symbol, (Symbol, String, Proc)]>
87
90
  #
88
91
  # ==== params[:action] and params[:controller] deprecated
89
- # params[:action] and params[:controller] have been deprecated as of
92
+ # <code>params[:action]</code> and <code>params[:controller]</code> have been deprecated as of
90
93
  # the 0.9.0 release. They are no longer set during dispatch, and
91
- # have been replaced by action_name and controller_name respectively.
94
+ # have been replaced by <code>action_name</code> and <code>controller_name</code> respectively.
92
95
  class Merb::AbstractController
93
96
  include Merb::RenderMixin
94
97
  include Merb::InlineTemplates
@@ -96,7 +99,7 @@ class Merb::AbstractController
96
99
  class_inheritable_accessor :_layout, :_template_root, :template_roots
97
100
  class_inheritable_accessor :_before_filters, :_after_filters
98
101
 
99
- cattr_accessor :_abstract_subclasses, :_template_path_cache
102
+ cattr_accessor :_abstract_subclasses
100
103
 
101
104
  #---
102
105
  # @semipublic
@@ -157,7 +160,7 @@ class Merb::AbstractController
157
160
  # of controller/action.mime.type
158
161
  #---
159
162
  # @public
160
- def _template_location(context, type = nil, controller = controller_name)
163
+ def _template_location(context, type, controller)
161
164
  controller ? "#{controller}/#{context}" : context
162
165
  end
163
166
 
@@ -234,7 +237,7 @@ class Merb::AbstractController
234
237
  #
235
238
  # ==== Raises
236
239
  # MerbControllerError:: Invalid body content caught.
237
- def _dispatch(action=:to_s)
240
+ def _dispatch(action)
238
241
  setup_session
239
242
  self.action_name = action
240
243
 
@@ -252,7 +255,7 @@ class Merb::AbstractController
252
255
  when Symbol then __send__(caught)
253
256
  when Proc then caught.call(self)
254
257
  else
255
- raise MerbControllerError, "The before filter chain is broken dude. wtf?"
258
+ raise ArgumentError, "Threw :halt, #{caught}. Expected String, nil, Symbol, Proc."
256
259
  end
257
260
  start = Time.now
258
261
  _call_filters(_after_filters)
@@ -417,23 +420,6 @@ class Merb::AbstractController
417
420
  # Method stub for finalizing up the session. This will be overriden by
418
421
  # session modules.
419
422
  def finalize_session() end
420
-
421
- # Handles the template cache (which is used by BootLoader to cache the list
422
- # of all templates).
423
- #
424
- # ==== Parameters
425
- # template<String>::
426
- # The full path to a template to add to the list of available templates
427
- def self.add_path_to_template_cache(template)
428
- return false if template.blank? || template.split("/").last.split(".").size != 3
429
- key = template.match(/(.*)\.(.*)$/)[1]
430
- self._template_path_cache[key] = template
431
- end
432
-
433
- # Resets the template_path_cache to an empty hash
434
- def self.reset_template_path_cache!
435
- self._template_path_cache = {}
436
- end
437
423
 
438
424
  # ==== Parameters
439
425
  # name<~to_sym, Hash>:: The name of the URL to generate.
@@ -24,14 +24,14 @@ end
24
24
 
25
25
  module Merb
26
26
  # ControllerExceptions are a way of simplifying controller code by placing
27
- # exceptional logic back into the MVC pattern.
27
+ # exception logic back into the MVC pattern.
28
28
  #
29
29
  # When a ControllerException is raised within your application merb will
30
30
  # attempt to re-route the request to your Exceptions controller to render
31
- # the error in a friendly mannor.
31
+ # the error in a friendly manor.
32
32
  #
33
33
  # For example you might have an action in your app that raises NotFound
34
- # if a some resource was not available
34
+ # if a resource was not available
35
35
  #
36
36
 
37
37
  # def show
@@ -41,7 +41,7 @@ module Merb
41
41
  # end
42
42
  #
43
43
  # This would halt execution of your action and re-route it over to your
44
- # Exceptions controller which might look something like
44
+ # Exceptions controller which might look something like:
45
45
  #
46
46
  # class Exceptions < Application
47
47
 
@@ -50,16 +50,16 @@ module Merb
50
50
  # end
51
51
  # end
52
52
  #
53
- # As usual the not_found action will look for a template in
53
+ # As usual, the not_found action will look for a template in
54
54
  # app/views/exceptions/not_found.html.erb
55
55
  #
56
56
  # Note: All standard ControllerExceptions have an HTTP status code associated
57
- # with them which is sent to the browser when the action it is rendered.
57
+ # with them which is sent to the browser when the action is rendered.
58
58
  #
59
59
  # Note: If you do not specifiy how to handle raised ControllerExceptions
60
60
  # or an unhandlable exception occurs within your customised exception action
61
- # then they will be rendered using the built-in error template
62
- # in development mode this "built in" template will show stack-traces for
61
+ # then they will be rendered using the built-in error template.
62
+ # In development mode this "built in" template will show stack-traces for
63
63
  # any of the ServerError family of exceptions (you can force the stack-trace
64
64
  # to display in production mode using the :exception_details config option in
65
65
  # merb.yml)
@@ -68,13 +68,13 @@ module Merb
68
68
  # ==== Internal Exceptions
69
69
  #
70
70
  # Any other rogue errors (not ControllerExceptions) that occur during the
71
- # execution of you app will be converted into the ControllerException
72
- # InternalServerError, and like all ControllerExceptions can be caught
73
- # on your Exceptions controller.
71
+ # execution of your app will be converted into the ControllerException
72
+ # InternalServerError. And like all other exceptions, the ControllerExceptions
73
+ # can be caught on your Exceptions controller.
74
74
  #
75
- # InternalServerErrors return status 500, a common use for cusomizing this
75
+ # InternalServerErrors return status 500, a common use for customizing this
76
76
  # action might be to send emails to the development team, warning that their
77
- # application have exploded. Mock example:
77
+ # application has exploded. Mock example:
78
78
  #
79
79
 
80
80
  # def internal_server_error
@@ -82,7 +82,7 @@ module Merb
82
82
  # "team@cowboys.com",
83
83
  # "Exception occured at #{Time.now}",
84
84
  # params[:exception])
85
- # render 'Something is wrong, but the team are on it!'
85
+ # render 'Something is wrong, but the team is on it!'
86
86
  # end
87
87
  #
88
88
  # Note: The special param[:exception] is available in all Exception actions
@@ -290,10 +290,8 @@ module Merb
290
290
 
291
291
  class InternalServerError < Merb::ControllerExceptions::ServerError #:doc:
292
292
  self.status = 500;
293
- # DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
294
293
  def initialize(exception = nil)
295
294
  @exception = exception
296
- @coderay = CodeRay rescue nil
297
295
  end
298
296
 
299
297
  def backtrace
@@ -137,7 +137,7 @@ class Merb::Controller < Merb::AbstractController
137
137
  #
138
138
  #---
139
139
  # @public
140
- def _template_location(context, type = nil, controller = controller_name)
140
+ def _template_location(context, type, controller)
141
141
  _conditionally_append_extension(controller ? "#{controller}/#{context}" : "#{context}", type)
142
142
  end
143
143
 
@@ -256,7 +256,7 @@ class Merb::Controller < Merb::AbstractController
256
256
  private
257
257
 
258
258
  # If not already added, add the proper mime extension to the template path.
259
- def _conditionally_append_extension(template, type = nil)
259
+ def _conditionally_append_extension(template, type)
260
260
  type && !template.match(/\.#{type.to_s.escape_regexp}$/) ? "#{template}.#{type}" : template
261
261
  end
262
262
 
@@ -38,7 +38,7 @@ module Merb
38
38
  # correctly appended to the mimetype itself.
39
39
  # &block:: a block which recieves the current controller when the format
40
40
  # is set (in the controller's #content_type method)
41
- def add_mime_type(key, transform_method, mimes, new_response_headers = {}, &block)
41
+ def add_mime_type(key, transform_method, mimes, new_response_headers = {}, default_quality = 1, &block)
42
42
  enforce!(key => Symbol, mimes => Array)
43
43
 
44
44
  content_type = new_response_headers["Content-Type"] || mimes.first
@@ -52,6 +52,7 @@ module Merb
52
52
  :transform_method => transform_method,
53
53
  :content_type => content_type,
54
54
  :response_headers => new_response_headers,
55
+ :default_quality => default_quality,
55
56
  :response_block => block })
56
57
 
57
58
  mimes.each do |mime|
@@ -478,4 +478,16 @@ module Merb::RenderMixin
478
478
  @_caught_content[obj] << string.to_s << (block_given? ? capture(&block) : "")
479
479
  end
480
480
 
481
+ # Called when renderers need to be sure that existing thrown content is cleared
482
+ # before throwing new content. This prevents double rendering of content when
483
+ # multiple templates are rendered after each other.
484
+ #
485
+ # ==== Parameters
486
+ # obj<Object>:: The key in the thrown_content hash. Defaults to :for_layout.
487
+ #---
488
+ # @public
489
+ def clear_content(obj = :for_layout)
490
+ @_caught_content.delete(obj) unless @_caught_content[obj].nil?
491
+ end
492
+
481
493
  end
@@ -352,6 +352,30 @@ module Merb
352
352
 
353
353
  class Responder
354
354
 
355
+ # def self.parse(accept_header)
356
+ # headers = accept_header.split(/,/)
357
+ #
358
+ # ret = {}
359
+ # headers.each do |header|
360
+ # header =~ /\s*([^;\s]*)\s*(;\s*q=\s*([\d\.]+))?/
361
+ # quality = $3.to_f || 0 if $1 == "*/*"
362
+ # quality = quality ? quality.to_f : 1
363
+ # mime = mime(range)
364
+ # ret[mime] = [mime_name(range), quality * mime[:default_quality]]
365
+ # end
366
+ # ret.sort_by {|k,v| [v.last]}
367
+ # end
368
+ #
369
+ # def self.mime_name(range)
370
+ # @mime_names ||= {}
371
+ # @mime_names[range] ||= Merb::ResponderMixin::MIMES[@media_range]
372
+ # end
373
+ #
374
+ # def self.mime(range)
375
+ # @mime ||= {}
376
+ # @mime[range] ||= Merb.available_mime_types[mime_name(range)]
377
+ # end
378
+
355
379
  protected
356
380
 
357
381
  # Parses the raw accept header into an array of sorted AcceptType objects.
@@ -362,11 +386,6 @@ module Merb
362
386
  # ==== Returns
363
387
  # Array[AcceptType]:: The accepted types.
364
388
  def self.parse(accept_header)
365
- # FF2 is broken. If we get FF2 headers, use FF3 headers instead.
366
- if accept_header == "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
367
- accept_header = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
368
- end
369
-
370
389
  headers = accept_header.split(/,/)
371
390
  idx, list = 0, []
372
391
  while idx < headers.size
@@ -396,6 +415,7 @@ module Merb
396
415
  @type, @sub_type = @media_range.split(%r{/})
397
416
  (quality ||= 0.0) if @media_range == "*/*"
398
417
  @quality = quality ? (quality.to_f * 100).to_i : 100
418
+ @quality *= (mime && mime[:default_quality] || 1)
399
419
  end
400
420
 
401
421
  # Compares two accept types for sorting purposes.
@@ -439,12 +459,16 @@ module Merb
439
459
  # All Accept header values, such as "text/html", that match this type.
440
460
  def synonyms
441
461
  return @syns if @syns
442
- if mime = Merb.available_mime_types[Merb::ResponderMixin::MIMES[@media_range]]
443
- @syns = mime[:accepts]
462
+ if _mime = mime
463
+ @syns = _mime[:accepts]
444
464
  else
445
465
  @syns = []
446
466
  end
447
467
  end
468
+
469
+ def mime
470
+ @mime ||= Merb.available_mime_types[Merb::ResponderMixin::MIMES[@media_range]]
471
+ end
448
472
 
449
473
  # ==== Returns
450
474
  # String::
@@ -0,0 +1,7 @@
1
+ class Hash
2
+ def extract!(*args)
3
+ args.map do |arg|
4
+ self.delete(arg)
5
+ end
6
+ end
7
+ end
@@ -113,7 +113,7 @@ module Kernel
113
113
  # Mapper) you wish to use. Currently Merb has plugins to support
114
114
  # ActiveRecord, DataMapper, and Sequel.
115
115
  #
116
- # @param orm<#to_s> The ORM to use.
116
+ # @param orm<Symbol> The ORM to use.
117
117
  #
118
118
  # @example
119
119
  # use_orm :datamapper
@@ -124,9 +124,10 @@ module Kernel
124
124
  # @note
125
125
  # If for some reason this is called more than once, latter
126
126
  # call takes over other.
127
+ # @api public
127
128
  def use_orm(orm)
128
129
  begin
129
- register_orm(orm)
130
+ Merb.orm = orm
130
131
  orm_plugin = "merb_#{orm}"
131
132
  Kernel.dependency(orm_plugin)
132
133
  rescue LoadError => e
@@ -135,17 +136,6 @@ module Kernel
135
136
  end
136
137
  end
137
138
 
138
-
139
- # Registers ORM at generator scope.
140
- #
141
- # @param orm<#to_sym>
142
- # ORM alias, like :activerecord, :datamapper or :sequel.
143
- #
144
- # @api private
145
- def register_orm(orm)
146
- Merb.orm_generator_scope = orm
147
- end
148
-
149
139
  # Used in Merb.root/config/init.rb to tell Merb which testing framework to
150
140
  # use. Currently Merb has plugins to support RSpec and Test::Unit.
151
141
  #
@@ -157,32 +147,39 @@ module Kernel
157
147
  #
158
148
  # # This will now use the RSpec generator for tests
159
149
  # $ merb-gen model ActivityEvent
150
+ # @api public
160
151
  def use_test(test_framework, *test_dependencies)
161
- raise "use_test only supports :rspec and :test_unit currently" unless supported_test_framework?(test_framework)
162
- register_test_framework(test_framework)
163
-
164
- dependencies test_dependencies if Merb.env == "test" || Merb.env.nil?
152
+ Merb.test_framework = test_framework
153
+
154
+ Kernel.dependencies test_dependencies if Merb.env == "test" || Merb.env.nil?
165
155
  end
166
-
167
- # Check whether Merb supports test framework. Currently Merb has plugins to support RSpec and Test::Unit.
156
+
157
+ # Used in Merb.root/config/init.rb to tell Merb which template engine to
158
+ # prefer.
168
159
  #
169
- # @param test_framework<Symbol>
170
- # The test framework to check. Currently only supports :rspec and :test_unit.
160
+ # @param template_engine<Symbol>
161
+ # The template engine to use.
171
162
  #
172
- # @api plugin
173
- def supported_test_framework?(test_framework)
174
- [:rspec, :test_unit].include?(test_framework.to_sym)
175
- end
176
-
177
- # Register test framework at generator scope. Currently Merb has plugins to support RSpec and Test::Unit.
178
- #
179
- # @param test_framework<Symbol>
180
- # The test framework to check. Currently only supports :rspec and :test_unit but the
181
- # check is performed before registration if you use API.
163
+ # @example
164
+ # use_template_engine :haml
182
165
  #
183
- # @api private
184
- def register_test_framework(test_framework)
185
- Merb.test_framework_generator_scope = test_framework
166
+ # # This will now use haml templates in generators where available.
167
+ # $ merb-gen resource_controller Project
168
+ # @api public
169
+ def use_template_engine(template_engine)
170
+ Merb.template_engine = template_engine
171
+
172
+ if template_engine != :erb
173
+ if template_engine.in?(:haml, :builder)
174
+ template_engine_plugin = "merb-#{template_engine}"
175
+ else
176
+ template_engine_plugin = "merb_#{template_engine}"
177
+ end
178
+ Kernel.dependency(template_engine_plugin)
179
+ end
180
+ rescue LoadError => e
181
+ Merb.logger.warn!("The #{template_engine_plugin} gem was not found. You may need to install it.")
182
+ raise e
186
183
  end
187
184
 
188
185
  # @param i<Fixnum> The caller number. Defaults to 1.
@@ -6,3 +6,4 @@ rescue LoadError => e
6
6
  end
7
7
 
8
8
  require File.dirname(__FILE__) / "core_ext" / "kernel"
9
+ require File.dirname(__FILE__) / "core_ext" / "hash"
@@ -18,10 +18,10 @@ module Merb
18
18
  filename, lineno, location = line.split(":")
19
19
  if filename.index(Merb.framework_root)
20
20
  type = "framework"
21
- shortname = Pathname.new(filename).relative_path_from(Merb.framework_root)
21
+ shortname = Pathname.new(filename).relative_path_from(Pathname.new(Merb.framework_root))
22
22
  elsif filename.index(Merb.root)
23
23
  type = "app"
24
- shortname = Pathname.new(filename).relative_path_from(Merb.root)
24
+ shortname = Pathname.new(filename).relative_path_from(Pathname.new(Merb.root))
25
25
  elsif path = Gem.path.find {|p| filename.index(p)}
26
26
  type = "gem"
27
27
  shortname = Pathname.new(filename).relative_path_from(Pathname.new(path))
@@ -90,4 +90,4 @@ module Merb
90
90
  end
91
91
  end
92
92
  end
93
- end
93
+ end