diff options
Diffstat (limited to 'git/test/fixtures/diff_mode_only')
| -rwxr-xr-x | git/test/fixtures/diff_mode_only | 1152 |
1 files changed, 0 insertions, 1152 deletions
diff --git a/git/test/fixtures/diff_mode_only b/git/test/fixtures/diff_mode_only deleted file mode 100755 index 6fc18f69..00000000 --- a/git/test/fixtures/diff_mode_only +++ /dev/null @@ -1,1152 +0,0 @@ -diff --git a/bin/merb b/bin/merb -old mode 100644 -new mode 100755 -diff --git a/lib/merb.rb b/lib/merb.rb -index 76cb3e269e46fdf9b63cda7cb563c6cf40fdcb15..a2ab4ed47f9cb2ab942da5c46a2b561758a0d704 100644 ---- a/lib/merb.rb -+++ b/lib/merb.rb -@@ -15,7 +15,7 @@ require 'merb_core/core_ext' - require 'merb_core/gem_ext/erubis' - require 'merb_core/logger' - require 'merb_core/version' -- -+require 'merb_core/controller/mime' - - module Merb - class << self -@@ -23,6 +23,7 @@ module Merb - def start(argv=ARGV) - Merb::Config.parse_args(argv) - BootLoader.run -+ - case Merb::Config[:adapter] - when "mongrel" - adapter = Merb::Rack::Mongrel -diff --git a/lib/merb_core/boot/bootloader.rb b/lib/merb_core/boot/bootloader.rb -index d873924860bf4da06ac93db5c6a188f63dd1c3cc..57da75f05e28e8a256922bf345ccd3902e0a0b02 100644 ---- a/lib/merb_core/boot/bootloader.rb -+++ b/lib/merb_core/boot/bootloader.rb -@@ -20,7 +20,7 @@ module Merb - end - - def run -- subclasses.each {|klass| Object.full_const_get(klass).new.run } -+ subclasses.each {|klass| Object.full_const_get(klass).run } - end - - def after(klass) -@@ -37,95 +37,128 @@ module Merb - - end - --class Merb::BootLoader::BuildFramework < Merb::BootLoader -- def run -- build_framework -+class Merb::BootLoader::LoadInit < Merb::BootLoader -+ def self.run -+ if Merb::Config[:init_file] -+ require Merb.root / Merb::Config[:init_file] -+ elsif File.exists?(Merb.root / "config" / "merb_init.rb") -+ require Merb.root / "config" / "merb_init" -+ elsif File.exists?(Merb.root / "merb_init.rb") -+ require Merb.root / "merb_init" -+ elsif File.exists?(Merb.root / "application.rb") -+ require Merb.root / "application" -+ end -+ end -+end -+ -+class Merb::BootLoader::Environment < Merb::BootLoader -+ def self.run -+ Merb.environment = Merb::Config[:environment] -+ end -+end -+ -+class Merb::BootLoader::Logger < Merb::BootLoader -+ def self.run -+ Merb.logger = Merb::Logger.new(Merb.dir_for(:log) / "test_log") -+ Merb.logger.level = Merb::Logger.const_get(Merb::Config[:log_level].upcase) rescue Merb::Logger::INFO - end -+end -+ -+class Merb::BootLoader::BuildFramework < Merb::BootLoader -+ class << self -+ def run -+ build_framework -+ end - -- # This method should be overridden in merb_init.rb before Merb.start to set up a different -- # framework structure -- def build_framework -- %[view model controller helper mailer part].each do |component| -- Merb.push_path(component.to_sym, Merb.root_path("app/#{component}s")) -+ # This method should be overridden in merb_init.rb before Merb.start to set up a different -+ # framework structure -+ def build_framework -+ %w[view model controller helper mailer part].each do |component| -+ Merb.push_path(component.to_sym, Merb.root_path("app/#{component}s")) -+ end -+ Merb.push_path(:application, Merb.root_path("app/controllers/application.rb")) -+ Merb.push_path(:config, Merb.root_path("config/router.rb")) -+ Merb.push_path(:lib, Merb.root_path("lib")) - end -- Merb.push_path(:application, Merb.root_path("app/controllers/application.rb")) -- Merb.push_path(:config, Merb.root_path("config/router.rb")) -- Merb.push_path(:lib, Merb.root_path("lib")) - end - end - - class Merb::BootLoader::LoadPaths < Merb::BootLoader - LOADED_CLASSES = {} - -- def run -- # Add models, controllers, and lib to the load path -- $LOAD_PATH.unshift Merb.load_paths[:model].first if Merb.load_paths[:model] -- $LOAD_PATH.unshift Merb.load_paths[:controller].first if Merb.load_paths[:controller] -- $LOAD_PATH.unshift Merb.load_paths[:lib].first if Merb.load_paths[:lib] -+ class << self -+ def run -+ # Add models, controllers, and lib to the load path -+ $LOAD_PATH.unshift Merb.load_paths[:model].first if Merb.load_paths[:model] -+ $LOAD_PATH.unshift Merb.load_paths[:controller].first if Merb.load_paths[:controller] -+ $LOAD_PATH.unshift Merb.load_paths[:lib].first if Merb.load_paths[:lib] - -- # Require all the files in the registered load paths -- puts Merb.load_paths.inspect -- Merb.load_paths.each do |name, path| -- Dir[path.first / path.last].each do |file| -- klasses = ObjectSpace.classes.dup -- require f -- LOADED_CLASSES[file] = ObjectSpace.classes - klasses -+ # Require all the files in the registered load paths -+ puts Merb.load_paths.inspect -+ Merb.load_paths.each do |name, path| -+ Dir[path.first / path.last].each do |file| -+ klasses = ObjectSpace.classes.dup -+ require file -+ LOADED_CLASSES[file] = ObjectSpace.classes - klasses -+ end - end - end -- end - -- def reload(file) -- if klasses = LOADED_CLASSES[file] -- klasses.each do |klass| -- remove_constant(klass) -+ def reload(file) -+ if klasses = LOADED_CLASSES[file] -+ klasses.each do |klass| -+ remove_constant(klass) -+ end - end -+ load file - end -- load file -- end - -- def remove_constant(const) -- # This is to support superclasses (like AbstractController) that track -- # their subclasses in a class variable. Classes that wish to use this -- # functionality are required to alias it to _subclasses_list. Plugins -- # for ORMs and other libraries should keep this in mind. -- if klass.superclass.respond_to?(:_subclasses_list) -- klass.superclass.send(:_subclasses_list).delete(klass) -- klass.superclass.send(:_subclasses_list).delete(klass.to_s) -- end -+ def remove_constant(const) -+ # This is to support superclasses (like AbstractController) that track -+ # their subclasses in a class variable. Classes that wish to use this -+ # functionality are required to alias it to _subclasses_list. Plugins -+ # for ORMs and other libraries should keep this in mind. -+ if klass.superclass.respond_to?(:_subclasses_list) -+ klass.superclass.send(:_subclasses_list).delete(klass) -+ klass.superclass.send(:_subclasses_list).delete(klass.to_s) -+ end - -- parts = const.to_s.split("::") -- base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::")) -- object = parts[-1].intern -- Merb.logger.debugger("Removing constant #{object} from #{base}") -- base.send(:remove_const, object) if object -+ parts = const.to_s.split("::") -+ base = parts.size == 1 ? Object : Object.full_const_get(parts[0..-2].join("::")) -+ object = parts[-1].intern -+ Merb.logger.debugger("Removing constant #{object} from #{base}") -+ base.send(:remove_const, object) if object -+ end - end - - end - - class Merb::BootLoader::Templates < Merb::BootLoader -- def run -- template_paths.each do |path| -- Merb::Template.inline_template(path) -+ class << self -+ def run -+ template_paths.each do |path| -+ Merb::Template.inline_template(path) -+ end - end -- end - -- def template_paths -- extension_glob = "{#{Merb::Template::EXTENSIONS.keys.join(',')}}" -+ def template_paths -+ extension_glob = "{#{Merb::Template::EXTENSIONS.keys.join(',')}}" - -- # This gets all templates set in the controllers template roots -- # We separate the two maps because most of controllers will have -- # the same _template_root, so it's silly to be globbing the same -- # path over and over. -- template_paths = Merb::AbstractController._abstract_subclasses.map do |klass| -- Object.full_const_get(klass)._template_root -- end.uniq.map {|path| Dir["#{path}/**/*.#{extension_glob}"] } -+ # This gets all templates set in the controllers template roots -+ # We separate the two maps because most of controllers will have -+ # the same _template_root, so it's silly to be globbing the same -+ # path over and over. -+ template_paths = Merb::AbstractController._abstract_subclasses.map do |klass| -+ Object.full_const_get(klass)._template_root -+ end.uniq.compact.map {|path| Dir["#{path}/**/*.#{extension_glob}"] } - -- # This gets the templates that might be created outside controllers -- # template roots. eg app/views/shared/* -- template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view) -+ # This gets the templates that might be created outside controllers -+ # template roots. eg app/views/shared/* -+ template_paths << Dir["#{Merb.dir_for(:view)}/**/*.#{extension_glob}"] if Merb.dir_for(:view) - -- template_paths.flatten.compact.uniq -- end -+ template_paths.flatten.compact.uniq -+ end -+ end - end - - class Merb::BootLoader::Libraries < Merb::BootLoader -@@ -145,18 +178,41 @@ class Merb::BootLoader::Libraries < Merb::BootLoader - def self.add_libraries(hsh) - @@libraries.merge!(hsh) - end -- -- def run -+ -+ def self.run - @@libraries.each do |exclude, choices| - require_first_working(*choices) unless Merb::Config[exclude] - end - end -- -- def require_first_working(first, *rest) -+ -+ def self.require_first_working(first, *rest) - p first, rest - require first - rescue LoadError - raise LoadError if rest.empty? - require_first_working rest.unshift, *rest - end -+end -+ -+class Merb::BootLoader::MimeTypes < Merb::BootLoader -+ def self.run -+ # Sets the default mime-types -+ # -+ # By default, the mime-types include: -+ # :all:: no transform, */* -+ # :yaml:: to_yaml, application/x-yaml or text/yaml -+ # :text:: to_text, text/plain -+ # :html:: to_html, text/html or application/xhtml+xml or application/html -+ # :xml:: to_xml, application/xml or text/xml or application/x-xml, adds "Encoding: UTF-8" response header -+ # :js:: to_json, text/javascript ot application/javascript or application/x-javascript -+ # :json:: to_json, application/json or text/x-json -+ Merb.available_mime_types.clear -+ Merb.add_mime_type(:all, nil, %w[*/*]) -+ Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml]) -+ Merb.add_mime_type(:text, :to_text, %w[text/plain]) -+ Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html]) -+ Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8") -+ Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript]) -+ Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json]) -+ end - end -\ No newline at end of file -diff --git a/lib/merb_core/config.rb b/lib/merb_core/config.rb -index c92f2e6f071c234551ecb16a4716d47fa92f6c7b..ab0864e0174b54833c758f9f22a840d3b53c7653 100644 ---- a/lib/merb_core/config.rb -+++ b/lib/merb_core/config.rb -@@ -92,6 +92,10 @@ module Merb - options[:cluster] = nodes - end - -+ opts.on("-I", "--init-file FILE", "Name of the file to load first") do |init_file| -+ options[:init_file] = init_file -+ end -+ - opts.on("-p", "--port PORTNUM", "Port to run merb on, defaults to 4000.") do |port| - options[:port] = port - end -@@ -261,29 +265,29 @@ module Merb - - @configuration = Merb::Config.apply_configuration_from_file options, environment_merb_yml - -- case Merb::Config[:environment].to_s -- when 'production' -- Merb::Config[:reloader] = Merb::Config.fetch(:reloader, false) -- Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, false) -- Merb::Config[:cache_templates] = true -- else -- Merb::Config[:reloader] = Merb::Config.fetch(:reloader, true) -- Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, true) -- end -- -- Merb::Config[:reloader_time] ||= 0.5 if Merb::Config[:reloader] == true -- -- -- if Merb::Config[:reloader] -- Thread.abort_on_exception = true -- Thread.new do -- loop do -- sleep( Merb::Config[:reloader_time] ) -- ::Merb::BootLoader.reload if ::Merb::BootLoader.app_loaded? -- end -- Thread.exit -- end -- end -+ # case Merb::Config[:environment].to_s -+ # when 'production' -+ # Merb::Config[:reloader] = Merb::Config.fetch(:reloader, false) -+ # Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, false) -+ # Merb::Config[:cache_templates] = true -+ # else -+ # Merb::Config[:reloader] = Merb::Config.fetch(:reloader, true) -+ # Merb::Config[:exception_details] = Merb::Config.fetch(:exception_details, true) -+ # end -+ # -+ # Merb::Config[:reloader_time] ||= 0.5 if Merb::Config[:reloader] == true -+ # -+ # -+ # if Merb::Config[:reloader] -+ # Thread.abort_on_exception = true -+ # Thread.new do -+ # loop do -+ # sleep( Merb::Config[:reloader_time] ) -+ # ::Merb::BootLoader.reload if ::Merb::BootLoader.app_loaded? -+ # end -+ # Thread.exit -+ # end -+ # end - @configuration - end - -diff --git a/lib/merb_core/controller/abstract_controller.rb b/lib/merb_core/controller/abstract_controller.rb -index fbf83372793da6da4b803b799994f0e341fddf88..f5e9a59057d67a6d56377a516a726cf51aa03d6f 100644 ---- a/lib/merb_core/controller/abstract_controller.rb -+++ b/lib/merb_core/controller/abstract_controller.rb -@@ -96,7 +96,7 @@ class Merb::AbstractController - # the superclass. - #--- - # @public -- def _template_location(action, controller = controller_name, type = nil) -+ def _template_location(action, type = nil, controller = controller_name) - "#{controller}/#{action}" - end - -@@ -106,6 +106,8 @@ class Merb::AbstractController - # own subclasses. We're using a Set so we don't have to worry about - # uniqueness. - self._abstract_subclasses = Set.new -+ self._template_root = Merb.dir_for(:view) -+ - def self.subclasses_list() _abstract_subclasses end - - class << self -@@ -114,7 +116,6 @@ class Merb::AbstractController - # The controller that is being inherited from Merb::AbstractController - def inherited(klass) - _abstract_subclasses << klass.to_s -- klass._template_root ||= Merb.dir_for(:view) - super - end - -diff --git a/lib/merb_core/controller/merb_controller.rb b/lib/merb_core/controller/merb_controller.rb -index 7283f006bb0501b29f825da129600cf045264b62..98af6ef3330a6b3f46d7bb1f8643261e28155ae5 100644 ---- a/lib/merb_core/controller/merb_controller.rb -+++ b/lib/merb_core/controller/merb_controller.rb -@@ -71,6 +71,10 @@ class Merb::Controller < Merb::AbstractController - end - end - -+ def _template_location(action, type = nil, controller = controller_name) -+ "#{controller}/#{action}.#{type}" -+ end -+ - # Sets the variables that came in through the dispatch as available to - # the controller. This is called by .build, so see it for more - # information. -@@ -107,9 +111,7 @@ class Merb::Controller < Merb::AbstractController - request.cookies[_session_id_key] = request.params[_session_id_key] - end - end -- @_request, @_response, @_status, @_headers = -- request, response, status, headers -- -+ @request, @response, @status, @headers = request, response, status, headers - nil - end - -@@ -135,7 +137,8 @@ class Merb::Controller < Merb::AbstractController - @_benchmarks[:action_time] = Time.now - start - end - -- _attr_reader :request, :response, :status, :headers -+ attr_reader :request, :response, :headers -+ attr_accessor :status - def params() request.params end - def cookies() request.cookies end - def session() request.session end -diff --git a/lib/merb_core/controller/mime.rb b/lib/merb_core/controller/mime.rb -index d17570786ca318cff7201c4b1e947ae229b01de8..ff9abe4d1c452aeabfcf5f7dc7a2c7cdd3f67035 100644 ---- a/lib/merb_core/controller/mime.rb -+++ b/lib/merb_core/controller/mime.rb -@@ -8,7 +8,7 @@ module Merb - - # Any specific outgoing headers should be included here. These are not - # the content-type header but anything in addition to it. -- # +tranform_method+ should be set to a symbol of the method used to -+ # +transform_method+ should be set to a symbol of the method used to - # transform a resource into this mime type. - # For example for the :xml mime type an object might be transformed by - # calling :to_xml, or for the :js mime type, :to_json. -@@ -71,27 +71,6 @@ module Merb - def mime_by_request_header(header) - available_mime_types.find {|key,info| info[request_headers].include?(header)}.first - end -- -- # Resets the default mime-types -- # -- # By default, the mime-types include: -- # :all:: no transform, */* -- # :yaml:: to_yaml, application/x-yaml or text/yaml -- # :text:: to_text, text/plain -- # :html:: to_html, text/html or application/xhtml+xml or application/html -- # :xml:: to_xml, application/xml or text/xml or application/x-xml, adds "Encoding: UTF-8" response header -- # :js:: to_json, text/javascript ot application/javascript or application/x-javascript -- # :json:: to_json, application/json or text/x-json -- def reset_default_mime_types! -- available_mime_types.clear -- Merb.add_mime_type(:all, nil, %w[*/*]) -- Merb.add_mime_type(:yaml, :to_yaml, %w[application/x-yaml text/yaml]) -- Merb.add_mime_type(:text, :to_text, %w[text/plain]) -- Merb.add_mime_type(:html, :to_html, %w[text/html application/xhtml+xml application/html]) -- Merb.add_mime_type(:xml, :to_xml, %w[application/xml text/xml application/x-xml], :Encoding => "UTF-8") -- Merb.add_mime_type(:js, :to_json, %w[text/javascript application/javascript application/x-javascript]) -- Merb.add_mime_type(:json, :to_json, %w[application/json text/x-json]) -- end - - end - end -\ No newline at end of file -diff --git a/lib/merb_core/controller/mixins/render.rb b/lib/merb_core/controller/mixins/render.rb -index 8e096546d4647bb597ab2e00a4b15d09db35e9c9..a298263af7d655d9ce43007554f3827046831287 100644 ---- a/lib/merb_core/controller/mixins/render.rb -+++ b/lib/merb_core/controller/mixins/render.rb -@@ -51,21 +51,22 @@ module Merb::RenderMixin - - # If you don't specify a thing to render, assume they want to render the current action - thing ||= action_name.to_sym -- -+ - # Content negotiation - opts[:format] ? (self.content_type = opts[:format]) : content_type - - # Do we have a template to try to render? - if thing.is_a?(Symbol) || opts[:template] -- -+ - # Find a template path to look up (_template_location adds flexibility here) -- template_location = _template_root / (opts[:template] || _template_location(thing)) -+ template_location = _template_root / (opts[:template] || _template_location(thing, content_type)) -+ - # Get the method name from the previously inlined list - template_method = Merb::Template.template_for(template_location) - - # Raise an error if there's no template - raise TemplateNotFound, "No template found at #{template_location}" unless -- self.respond_to?(template_method) -+ template_method && self.respond_to?(template_method) - - # Call the method in question and throw the content for later consumption by the layout - throw_content(:for_layout, self.send(template_method)) -diff --git a/lib/merb_core/controller/mixins/responder.rb b/lib/merb_core/controller/mixins/responder.rb -index e910b2b32c844ab51cf2a10d0ad26c314dbb3631..5ac67fb907aaf9f95effc7eb3cbb07b8963ce022 100644 ---- a/lib/merb_core/controller/mixins/responder.rb -+++ b/lib/merb_core/controller/mixins/responder.rb -@@ -97,6 +97,8 @@ module Merb - # and none of the provides methods can be used. - module ResponderMixin - -+ TYPES = {} -+ - class ContentTypeAlreadySet < StandardError; end - - # ==== Parameters -@@ -105,6 +107,7 @@ module Merb - base.extend(ClassMethods) - base.class_eval do - class_inheritable_accessor :class_provided_formats -+ self.class_provided_formats = [] - end - base.reset_provides - end -@@ -178,171 +181,253 @@ module Merb - def reset_provides - only_provides(:html) - end -- -- # ==== Returns -- # The current list of formats provided for this instance of the controller. -- # It starts with what has been set in the controller (or :html by default) -- # but can be modifed on a per-action basis. -- def _provided_formats -- @_provided_formats ||= class_provided_formats.dup -+ end -+ -+ # ==== Returns -+ # The current list of formats provided for this instance of the controller. -+ # It starts with what has been set in the controller (or :html by default) -+ # but can be modifed on a per-action basis. -+ def _provided_formats -+ @_provided_formats ||= class_provided_formats.dup -+ end -+ -+ # Sets the provided formats for this action. Usually, you would -+ # use a combination of +provides+, +only_provides+ and +does_not_provide+ -+ # to manage this, but you can set it directly. -+ # -+ # ==== Parameters -+ # *formats<Symbol>:: A list of formats to be passed to provides -+ # -+ # ==== Raises -+ # Merb::ResponderMixin::ContentTypeAlreadySet:: -+ # Content negotiation already occured, and the content_type is set. -+ # -+ # ==== Returns -+ # Array:: List of formats passed in -+ def _set_provided_formats(*formats) -+ if @_content_type -+ raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set" - end -- -- # Sets the provided formats for this action. Usually, you would -- # use a combination of +provides+, +only_provides+ and +does_not_provide+ -- # to manage this, but you can set it directly. -- # -- # ==== Parameters -- # *formats<Symbol>:: A list of formats to be passed to provides -- # -- # ==== Raises -- # Merb::ResponderMixin::ContentTypeAlreadySet:: -- # Content negotiation already occured, and the content_type is set. -- # -- # ==== Returns -- # Array:: List of formats passed in -- def _set_provided_formats(*formats) -- if @_content_type -- raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set" -- end -- @_provided_formats = [] -- provides(*formats) -+ @_provided_formats = [] -+ provides(*formats) -+ end -+ alias :_provided_formats= :_set_provided_formats -+ -+ # Adds formats to the list of provided formats for this particular -+ # request. Usually used to add formats to a single action. See also -+ # the controller-level provides that affects all actions in a controller. -+ # -+ # ==== Parameters -+ # *formats<Symbol>:: A list of formats to add to the per-action list -+ # of provided formats -+ # -+ # ==== Raises -+ # Merb::ResponderMixin::ContentTypeAlreadySet:: -+ # Content negotiation already occured, and the content_type is set. -+ # -+ # ==== Returns -+ # Array:: List of formats passed in -+ # -+ #--- -+ # @public -+ def provides(*formats) -+ if @_content_type -+ raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set" - end -- alias :_provided_formats= :_set_provided_formats -- -- # Adds formats to the list of provided formats for this particular -- # request. Usually used to add formats to a single action. See also -- # the controller-level provides that affects all actions in a controller. -- # -- # ==== Parameters -- # *formats<Symbol>:: A list of formats to add to the per-action list -- # of provided formats -- # -- # ==== Raises -- # Merb::ResponderMixin::ContentTypeAlreadySet:: -- # Content negotiation already occured, and the content_type is set. -- # -- # ==== Returns -- # Array:: List of formats passed in -- # -- #--- -- # @public -- def provides(*formats) -- if @_content_type -- raise ContentTypeAlreadySet, "Cannot modify provided_formats because content_type has already been set" -- end -- formats.each do |fmt| -- _provided_formats << fmt unless _provided_formats.include?(fmt) -- end -+ formats.each do |fmt| -+ _provided_formats << fmt unless _provided_formats.include?(fmt) - end -+ end - -- # Sets list of provided formats for this particular -- # request. Usually used to limit formats to a single action. See also -- # the controller-level only_provides that affects all actions -- # in a controller. -- # -- # ==== Parameters -- # *formats<Symbol>:: A list of formats to use as the per-action list -- # of provided formats -- # -- # ==== Returns -- # Array:: List of formats passed in -- # -- #--- -- # @public -- def only_provides(*formats) -- self._provided_formats = *formats -- end -- -- # Removes formats from the list of provided formats for this particular -- # request. Usually used to remove formats from a single action. See -- # also the controller-level does_not_provide that affects all actions in a -- # controller. -- # -- # ==== Parameters -- # *formats<Symbol>:: Registered mime-type -- # -- # ==== Returns -- # Array:: List of formats that remain after removing the ones not to provide -- # -- #--- -- # @public -- def does_not_provide(*formats) -- formats.flatten! -- self._provided_formats -= formats -- end -- -- # Do the content negotiation: -- # 1. if params[:format] is there, and provided, use it -- # 2. Parse the Accept header -- # 3. If it's */*, use the first provided format -- # 4. Look for one that is provided, in order of request -- # 5. Raise 406 if none found -- def _perform_content_negotiation # :nodoc: -- raise Merb::ControllerExceptions::NotAcceptable if provided_formats.empty? -- if fmt = params[:format] -- return fmt.to_sym if provided_formats.include?(fmt.to_sym) -- else -- accepts = Responder.parse(request.accept).map {|t| t.to_sym} -- return provided_formats.first if accepts.include?(:all) -- return accepts.each { |type| break type if provided_formats.include?(type) } -- end -- raise Merb::ControllerExceptions::NotAcceptable -+ # Sets list of provided formats for this particular -+ # request. Usually used to limit formats to a single action. See also -+ # the controller-level only_provides that affects all actions -+ # in a controller. -+ # -+ # ==== Parameters -+ # *formats<Symbol>:: A list of formats to use as the per-action list -+ # of provided formats -+ # -+ # ==== Returns -+ # Array:: List of formats passed in -+ # -+ #--- -+ # @public -+ def only_provides(*formats) -+ self._provided_formats = *formats -+ end -+ -+ # Removes formats from the list of provided formats for this particular -+ # request. Usually used to remove formats from a single action. See -+ # also the controller-level does_not_provide that affects all actions in a -+ # controller. -+ # -+ # ==== Parameters -+ # *formats<Symbol>:: Registered mime-type -+ # -+ # ==== Returns -+ # Array:: List of formats that remain after removing the ones not to provide -+ # -+ #--- -+ # @public -+ def does_not_provide(*formats) -+ formats.flatten! -+ self._provided_formats -= formats -+ end -+ -+ # Do the content negotiation: -+ # 1. if params[:format] is there, and provided, use it -+ # 2. Parse the Accept header -+ # 3. If it's */*, use the first provided format -+ # 4. Look for one that is provided, in order of request -+ # 5. Raise 406 if none found -+ def _perform_content_negotiation # :nodoc: -+ raise Merb::ControllerExceptions::NotAcceptable if _provided_formats.empty? -+ if fmt = params[:format] && _provided_formats.include?(fmt.to_sym) -+ return fmt.to_sym - end -+ accepts = Responder.parse(request.accept).map {|t| t.to_sym} -+ return _provided_formats.first if accepts.include?(:all) -+ (accepts & _provided_formats).first || (raise Merb::ControllerExceptions::NotAcceptable) -+ end - -- # Returns the output format for this request, based on the -- # provided formats, <tt>params[:format]</tt> and the client's HTTP -- # Accept header. -- # -- # The first time this is called, it triggers content negotiation -- # and caches the value. Once you call +content_type+ you can -- # not set or change the list of provided formats. -- # -- # Called automatically by +render+, so you should only call it if -- # you need the value, not to trigger content negotiation. -- # -- # ==== Parameters -- # fmt<String?>:: -- # An optional format to use instead of performing content negotiation. -- # This can be used to pass in the values of opts[:format] from the -- # render function to short-circuit content-negotiation when it's not -- # necessary. This optional parameter should not be considered part -- # of the public API. -- # -- # ==== Returns -- # Symbol:: The content-type that will be used for this controller. -- # -- #--- -- # @public -- def content_type(fmt = nil) -- self.content_type = (fmt || _perform_content_negotiation) unless @_content_type -- @_content_type -+ # Returns the output format for this request, based on the -+ # provided formats, <tt>params[:format]</tt> and the client's HTTP -+ # Accept header. -+ # -+ # The first time this is called, it triggers content negotiation -+ # and caches the value. Once you call +content_type+ you can -+ # not set or change the list of provided formats. -+ # -+ # Called automatically by +render+, so you should only call it if -+ # you need the value, not to trigger content negotiation. -+ # -+ # ==== Parameters -+ # fmt<String?>:: -+ # An optional format to use instead of performing content negotiation. -+ # This can be used to pass in the values of opts[:format] from the -+ # render function to short-circuit content-negotiation when it's not -+ # necessary. This optional parameter should not be considered part -+ # of the public API. -+ # -+ # ==== Returns -+ # Symbol:: The content-type that will be used for this controller. -+ # -+ #--- -+ # @public -+ def content_type(fmt = nil) -+ @_content_type = (fmt || _perform_content_negotiation) unless @_content_type -+ @_content_type -+ end -+ -+ # Sets the content type of the current response to a value based on -+ # a passed in key. The Content-Type header will be set to the first -+ # registered header for the mime-type. -+ # -+ # ==== Parameters -+ # type<Symbol>:: A type that is in the list of registered mime-types. -+ # -+ # ==== Raises -+ # ArgumentError:: "type" is not in the list of registered mime-types. -+ # -+ # ==== Returns -+ # Symbol:: The content-type that was passed in. -+ # -+ #--- -+ # @semipublic -+ def content_type=(type) -+ unless Merb.available_mime_types.has_key?(type) -+ raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{type}") -+ end -+ headers['Content-Type'] = Merb.available_mime_types[type].first -+ @_content_type = type -+ end -+ -+ end -+ -+ class Responder -+ -+ protected -+ def self.parse(accept_header) -+ # parse the raw accept header into a unique, sorted array of AcceptType objects -+ list = accept_header.to_s.split(/,/).enum_for(:each_with_index).map do |entry,index| -+ AcceptType.new(entry,index += 1) -+ end.sort.uniq -+ # firefox (and possibly other browsers) send broken default accept headers. -+ # fix them up by sorting alternate xml forms (namely application/xhtml+xml) -+ # ahead of pure xml types (application/xml,text/xml). -+ if app_xml = list.detect{|e| e.super_range == 'application/xml'} -+ list.select{|e| e.to_s =~ /\+xml/}.each { |acc_type| -+ list[list.index(acc_type)],list[list.index(app_xml)] = -+ list[list.index(app_xml)],list[list.index(acc_type)] } - end -- -- # Sets the content type of the current response to a value based on -- # a passed in key. The Content-Type header will be set to the first -- # registered header for the mime-type. -- # -- # ==== Parameters -- # type<Symbol>:: A type that is in the list of registered mime-types. -- # -- # ==== Raises -- # ArgumentError:: "type" is not in the list of registered mime-types. -- # -- # ==== Returns -- # Symbol:: The content-type that was passed in. -- # -- #--- -- # @semipublic -- def content_type=(type) -- unless Merb.available_mime_types.has_key?(type) -- raise Merb::ControllerExceptions::NotAcceptable.new("Unknown content_type for response: #{type}") -- end -- headers['Content-Type'] = Merb.available_mime_types[type].first -- @_content_type = type -+ list -+ end -+ -+ public -+ def self.params_to_query_string(value, prefix = nil) -+ case value -+ when Array -+ value.map { |v| -+ params_to_query_string(v, "#{prefix}[]") -+ } * "&" -+ when Hash -+ value.map { |k, v| -+ params_to_query_string(v, prefix ? "#{prefix}[#{Merb::Request.escape(k)}]" : Merb::Request.escape(k)) -+ } * "&" -+ else -+ "#{prefix}=#{Merb::Request.escape(value)}" - end -+ end - -- end -+ end -+ -+ class AcceptType -+ -+ attr_reader :media_range, :quality, :index, :type, :sub_type - -+ def initialize(entry,index) -+ @index = index -+ @media_range, quality = entry.split(/;\s*q=/).map{|a| a.strip } -+ @type, @sub_type = @media_range.split(/\//) -+ quality ||= 0.0 if @media_range == '*/*' -+ @quality = ((quality || 1.0).to_f * 100).to_i -+ end -+ -+ def <=>(entry) -+ c = entry.quality <=> quality -+ c = index <=> entry.index if c == 0 -+ c -+ end -+ -+ def eql?(entry) -+ synonyms.include?(entry.media_range) -+ end -+ -+ def ==(entry); eql?(entry); end -+ -+ def hash; super_range.hash; end -+ -+ def synonyms -+ @syns ||= Merb.available_mime_types.values.map do |e| -+ e[:request_headers] if e[:request_headers].include?(@media_range) -+ end.compact.flatten -+ end -+ -+ def super_range -+ synonyms.first || @media_range -+ end -+ -+ def to_sym -+ Merb.available_mime_types.select{|k,v| -+ v[:request_headers] == synonyms || v[:request_headers][0] == synonyms[0]}.flatten.first -+ end -+ -+ def to_s -+ @media_range -+ end -+ - end -+ - - end -\ No newline at end of file -diff --git a/lib/merb_core/dispatch/dispatcher.rb b/lib/merb_core/dispatch/dispatcher.rb -index c458c9f9ad454d3b0c3055d6b2a8e88b17712b44..f7fed0f539a20f9cce08b72c551725ad0563bf37 100644 ---- a/lib/merb_core/dispatch/dispatcher.rb -+++ b/lib/merb_core/dispatch/dispatcher.rb -@@ -33,10 +33,10 @@ class Merb::Dispatcher - - # this is the custom dispatch_exception; it allows failures to still be dispatched - # to the error controller -- rescue => exception -- Merb.logger.error(Merb.exception(exception)) -- exception = controller_exception(exception) -- dispatch_exception(request, response, exception) -+ # rescue => exception -+ # Merb.logger.error(Merb.exception(exception)) -+ # exception = controller_exception(exception) -+ # dispatch_exception(request, response, exception) - end - - private -@@ -49,10 +49,10 @@ class Merb::Dispatcher - def dispatch_action(klass, action, request, response, status=200) - # build controller - controller = klass.build(request, response, status) -- if @@use_mutex -- @@mutex.synchronize { controller.dispatch(action) } -+ if use_mutex -+ @@mutex.synchronize { controller._dispatch(action) } - else -- controller.dispatch(action) -+ controller._dispatch(action) - end - [controller, action] - end -diff --git a/lib/merb_core/rack/adapter.rb b/lib/merb_core/rack/adapter.rb -index ffc7117e9733e83b0567bbe4a43fac7663800b7d..217399a5382d0b3878aaea3d3e302173c5b5f119 100644 ---- a/lib/merb_core/rack/adapter.rb -+++ b/lib/merb_core/rack/adapter.rb -@@ -40,7 +40,7 @@ module Merb - begin - controller, action = ::Merb::Dispatcher.handle(request, response) - rescue Object => e -- return [500, {"Content-Type"=>"text/html"}, "Internal Server Error"] -+ return [500, {"Content-Type"=>"text/html"}, e.message + "<br/>" + e.backtrace.join("<br/>")] - end - [controller.status, controller.headers, controller.body] - end -diff --git a/lib/merb_core/test/request_helper.rb b/lib/merb_core/test/request_helper.rb -index 10a9fb3ace56eaf1db0fa300df3fb2ab88a7118a..f302a3b71539182ba142cd208fe6d6aae171b1a1 100644 ---- a/lib/merb_core/test/request_helper.rb -+++ b/lib/merb_core/test/request_helper.rb -@@ -26,8 +26,10 @@ module Merb::Test::RequestHelper - Merb::Test::FakeRequest.new(env, StringIO.new(req)) - end - -- def dispatch_to(controller_klass, action, env = {}, opt = {}, &blk) -- request = fake_request(env, opt) -+ def dispatch_to(controller_klass, action, params = {}, env = {}, &blk) -+ request = fake_request(env, -+ :query_string => Merb::Responder.params_to_query_string(params)) -+ - controller = controller_klass.build(request) - controller.instance_eval(&blk) if block_given? - controller._dispatch(action) -diff --git a/spec/public/abstract_controller/spec_helper.rb b/spec/public/abstract_controller/spec_helper.rb -index df759008d14e7572b5c44de24f77f828f83f1682..694cee2592a210a5c1fa40ca7846beeaa09725fe 100644 ---- a/spec/public/abstract_controller/spec_helper.rb -+++ b/spec/public/abstract_controller/spec_helper.rb -@@ -1,12 +1,10 @@ - __DIR__ = File.dirname(__FILE__) - require File.join(__DIR__, "..", "..", "spec_helper") - --# The framework structure *must* be set up before loading in framework --# files. - require File.join(__DIR__, "controllers", "filters") - require File.join(__DIR__, "controllers", "render") - --Merb::BootLoader::Templates.new.run -+Merb::BootLoader::Templates.run - - module Merb::Test::Behaviors - def dispatch_should_make_body(klass, body, action = :index) -diff --git a/spec/public/controller/base_spec.rb b/spec/public/controller/base_spec.rb -index 1709e612629ed2c2b6af4579a8b89684aca9aa3c..5bcdb59948cc22592639b1aee9bd233ff2c306fa 100644 ---- a/spec/public/controller/base_spec.rb -+++ b/spec/public/controller/base_spec.rb -@@ -10,11 +10,11 @@ describe Merb::Controller, " callable actions" do - end - - it "should dispatch to callable actions" do -- dispatch_to(Merb::Test::Fixtures::TestFoo, :index).body.should == "index" -+ dispatch_to(Merb::Test::Fixtures::TestBase, :index).body.should == "index" - end - - it "should not dispatch to hidden actions" do -- calling { dispatch_to(Merb::Test::Fixtures::TestFoo, :hidden) }. -+ calling { dispatch_to(Merb::Test::Fixtures::TestBase, :hidden) }. - should raise_error(Merb::ControllerExceptions::ActionNotFound) - end - -diff --git a/spec/public/controller/controllers/base.rb b/spec/public/controller/controllers/base.rb -index a1b3beb27899df781d943427d9b23945f02e14de..c4b69a440a9da3c3486208d2cb95ccb8bdb974b9 100644 ---- a/spec/public/controller/controllers/base.rb -+++ b/spec/public/controller/controllers/base.rb -@@ -3,7 +3,7 @@ module Merb::Test::Fixtures - self._template_root = File.dirname(__FILE__) / "views" - end - -- class TestFoo < ControllerTesting -+ class TestBase < ControllerTesting - def index - "index" - end -diff --git a/spec/public/controller/controllers/responder.rb b/spec/public/controller/controllers/responder.rb -new file mode 100644 -index 0000000000000000000000000000000000000000..867192e8f6e995a43fd5cd3daffa0ec11b3d31e5 ---- /dev/null -+++ b/spec/public/controller/controllers/responder.rb -@@ -0,0 +1,25 @@ -+module Merb::Test::Fixtures -+ class ControllerTesting < Merb::Controller -+ self._template_root = File.dirname(__FILE__) / "views" -+ end -+ -+ class TestResponder < ControllerTesting -+ def index -+ render -+ end -+ end -+ -+ class TestHtmlDefault < TestResponder; end -+ -+ class TestClassProvides < TestResponder; -+ provides :xml -+ end -+ -+ class TestLocalProvides < TestResponder; -+ def index -+ provides :xml -+ render -+ end -+ end -+ -+end -\ No newline at end of file -diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb -new file mode 100644 -index 0000000000000000000000000000000000000000..1bfb77d4a44c444bba6888ae7740f7df4b074c58 ---- /dev/null -+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.html.erb -@@ -0,0 +1 @@ -+This should not be rendered -\ No newline at end of file -diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb -new file mode 100644 -index 0000000000000000000000000000000000000000..7c91f633987348e87e5e34e1d9e87d9dd0e5100c ---- /dev/null -+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_class_provides/index.xml.erb -@@ -0,0 +1 @@ -+<XML:Class provides='true' /> -\ No newline at end of file -diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb -new file mode 100644 -index 0000000000000000000000000000000000000000..eb4b52bf5a7aaba8f1706de419f42789c05684a2 ---- /dev/null -+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_html_default/index.html.erb -@@ -0,0 +1 @@ -+HTML: Default -\ No newline at end of file -diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb -new file mode 100644 -index 0000000000000000000000000000000000000000..a3a841a89c62e6174038935a42da9cd24ff54413 ---- /dev/null -+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.html.erb -@@ -0,0 +1 @@ -+This should not render -\ No newline at end of file -diff --git a/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb -new file mode 100644 -index 0000000000000000000000000000000000000000..c1384ec6af0357b585cc367035d1bc3a30347ade ---- /dev/null -+++ b/spec/public/controller/controllers/views/merb/test/fixtures/test_local_provides/index.xml.erb -@@ -0,0 +1 @@ -+<XML:Local provides='true' /> -\ No newline at end of file -diff --git a/spec/public/controller/responder_spec.rb b/spec/public/controller/responder_spec.rb -index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bcf18532442e5965cf6ca8501770d7b7a1eb2429 100644 ---- a/spec/public/controller/responder_spec.rb -+++ b/spec/public/controller/responder_spec.rb -@@ -0,0 +1,31 @@ -+require File.join(File.dirname(__FILE__), "spec_helper") -+ -+describe Merb::Controller, " responds" do -+ -+ before do -+ Merb.push_path(:layout, File.dirname(__FILE__) / "controllers" / "views" / "layouts") -+ Merb::Router.prepare do |r| -+ r.default_routes -+ end -+ end -+ -+ it "should default the mime-type to HTML" do -+ dispatch_to(Merb::Test::Fixtures::TestHtmlDefault, :index).body.should == "HTML: Default" -+ end -+ -+ it "should use other mime-types if they are provided on the class level" do -+ controller = dispatch_to(Merb::Test::Fixtures::TestClassProvides, :index, {}, :http_accept => "application/xml") -+ controller.body.should == "<XML:Class provides='true' />" -+ end -+ -+ it "should fail if none of the acceptable mime-types are available" do -+ calling { dispatch_to(Merb::Test::Fixtures::TestClassProvides, :index, {}, :http_accept => "application/json") }. -+ should raise_error(Merb::ControllerExceptions::NotAcceptable) -+ end -+ -+ it "should use mime-types that are provided at the local level" do -+ controller = dispatch_to(Merb::Test::Fixtures::TestLocalProvides, :index, {}, :http_accept => "application/xml") -+ controller.body.should == "<XML:Local provides='true' />" -+ end -+ -+end -\ No newline at end of file -diff --git a/spec/public/controller/spec_helper.rb b/spec/public/controller/spec_helper.rb -index f68628a63740f4ce0235a15d71c5889e55ecaf78..e360194c1fbaf72c3298c61543c2d3a19b512b41 100644 ---- a/spec/public/controller/spec_helper.rb -+++ b/spec/public/controller/spec_helper.rb -@@ -1,4 +1,10 @@ - __DIR__ = File.dirname(__FILE__) -+require 'ruby-debug' -+ - require File.join(__DIR__, "..", "..", "spec_helper") - --require File.join(__DIR__, "controllers", "base") -\ No newline at end of file -+require File.join(__DIR__, "controllers", "base") -+require File.join(__DIR__, "controllers", "responder") -+ -+Merb::BootLoader::Templates.run -+Merb::BootLoader::MimeTypes.run -\ No newline at end of file |
