merb-core 0.9.4 → 0.9.5

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