diff options
author | José Valim <jose.valim@gmail.com> | 2009-12-27 12:09:20 +0100 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2009-12-27 12:09:20 +0100 |
commit | 47e5caa96bffc04c8c0b287a975a609fb048e530 (patch) | |
tree | 653d360dc9ad7eb7c5d2338840e15ab8b28a902b /actionpack/lib/action_dispatch | |
parent | fd58a2d1da04508a7fdf825143e61d186112e63e (diff) | |
parent | d92c4a84023bc0c8dd75869c9b4d5e50277f4650 (diff) | |
download | rails-47e5caa96bffc04c8c0b287a975a609fb048e530.tar.gz rails-47e5caa96bffc04c8c0b287a975a609fb048e530.tar.bz2 rails-47e5caa96bffc04c8c0b287a975a609fb048e530.zip |
Merge Mail with latest Rails and move mail gem to Gemfile.
Diffstat (limited to 'actionpack/lib/action_dispatch')
16 files changed, 244 insertions, 187 deletions
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 7d1f5a4504..6e8a5dcb8a 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -18,7 +18,7 @@ module ActionDispatch HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM - HTTP_NEGOTIATE HTTP_PRAGMA HTTP_REFERER HTTP_USER_AGENT ].each do |env| + HTTP_NEGOTIATE HTTP_PRAGMA ].each do |env| define_method(env.sub(/^HTTP_/n, '').downcase) do @env[env] end @@ -465,6 +465,15 @@ EOM session['flash'] || {} end + # Returns the authorization header regardless of whether it was specified directly or through one of the + # proxy alternatives. + def authorization + @env['HTTP_AUTHORIZATION'] || + @env['X-HTTP_AUTHORIZATION'] || + @env['X_HTTP_AUTHORIZATION'] || + @env['REDIRECT_X_HTTP_AUTHORIZATION'] + end + # Receives an array of mimes and return the first user sent mime that # matches the order array. # diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 378fd5e61d..8524bbd993 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -60,7 +60,7 @@ module ActionDispatch # :nodoc: end def status=(status) - @status = status.to_i + @status = Rack::Utils.status_code(status) end # The response code of the request @@ -74,7 +74,7 @@ module ActionDispatch # :nodoc: end def message - StatusCodes::STATUS_CODES[@status] + Rack::Utils::HTTP_STATUS_CODES[@status] end alias_method :status_message, :message @@ -145,18 +145,6 @@ module ActionDispatch # :nodoc: cattr_accessor(:default_charset) { "utf-8" } - def assign_default_content_type_and_charset! - return if headers[CONTENT_TYPE].present? - - @content_type ||= Mime::HTML - @charset ||= self.class.default_charset - - type = @content_type.to_s.dup - type << "; charset=#{@charset}" unless @sending_file - - headers[CONTENT_TYPE] = type - end - def to_a assign_default_content_type_and_charset! handle_conditional_get! @@ -259,6 +247,18 @@ module ActionDispatch # :nodoc: !@blank && @body.respond_to?(:all?) && @body.all? { |part| part.is_a?(String) } end + def assign_default_content_type_and_charset! + return if headers[CONTENT_TYPE].present? + + @content_type ||= Mime::HTML + @charset ||= self.class.default_charset + + type = @content_type.to_s.dup + type << "; charset=#{@charset}" unless @sending_file + + headers[CONTENT_TYPE] = type + end + DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate" def set_conditional_cache_control! @@ -280,7 +280,6 @@ module ActionDispatch # :nodoc: headers["Cache-Control"] = options.join(", ") end - end end end diff --git a/actionpack/lib/action_dispatch/http/status_codes.rb b/actionpack/lib/action_dispatch/http/status_codes.rb deleted file mode 100644 index ea1475e827..0000000000 --- a/actionpack/lib/action_dispatch/http/status_codes.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'active_support/inflector' - -module ActionDispatch - module StatusCodes #:nodoc: - STATUS_CODES = Rack::Utils::HTTP_STATUS_CODES.merge({ - 102 => "Processing", - 207 => "Multi-Status", - 226 => "IM Used", - 422 => "Unprocessable Entity", - 423 => "Locked", - 424 => "Failed Dependency", - 426 => "Upgrade Required", - 507 => "Insufficient Storage", - 510 => "Not Extended" - }).freeze - - # Provides a symbol-to-fixnum lookup for converting a symbol (like - # :created or :not_implemented) into its corresponding HTTP status - # code (like 200 or 501). - SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) { |hash, (code, message)| - hash[ActiveSupport::Inflector.underscore(message.gsub(/ /, "")).to_sym] = code - hash - }.freeze - end -end diff --git a/actionpack/lib/action_dispatch/http/utils.rb b/actionpack/lib/action_dispatch/http/utils.rb deleted file mode 100644 index e04a39935e..0000000000 --- a/actionpack/lib/action_dispatch/http/utils.rb +++ /dev/null @@ -1,20 +0,0 @@ -module ActionDispatch - module Utils - # TODO: Pull this into rack core - # http://github.com/halorgium/rack/commit/feaf071c1de743fbd10bc316830180a9af607278 - def parse_config(config) - if config =~ /\.ru$/ - cfgfile = ::File.read(config) - if cfgfile[/^#\\(.*)/] - opts.parse! $1.split(/\s+/) - end - inner_app = eval "Rack::Builder.new {( " + cfgfile + "\n )}.to_app", - nil, config - else - require config - inner_app = Object.const_get(::File.basename(config, '.rb').capitalize) - end - end - module_function :parse_config - end -end diff --git a/actionpack/lib/action_dispatch/middleware/cascade.rb b/actionpack/lib/action_dispatch/middleware/cascade.rb new file mode 100644 index 0000000000..9f5c9891f0 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/cascade.rb @@ -0,0 +1,29 @@ +module ActionDispatch + class Cascade + def self.new(*apps) + apps = apps.flatten + + case apps.length + when 0 + raise ArgumentError, "app is required" + when 1 + apps.first + else + super(apps) + end + end + + def initialize(apps) + @apps = apps + end + + def call(env) + result = nil + @apps.each do |app| + result = app.call(env) + break unless result[1]["X-Cascade"] == "pass" + end + result + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 32ccb5c931..534390d4aa 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -1,4 +1,5 @@ require 'active_support/json' +require 'action_dispatch/http/request' module ActionDispatch class ParamsParser @@ -31,41 +32,39 @@ module ActionDispatch return false unless strategy case strategy - when Proc - strategy.call(request.raw_post) - when :xml_simple, :xml_node - request.body.size == 0 ? {} : Hash.from_xml(request.body).with_indifferent_access - when :yaml - YAML.load(request.body) - when :json - if request.body.size == 0 - {} - else - data = ActiveSupport::JSON.decode(request.body) - data = {:_json => data} unless data.is_a?(Hash) - data.with_indifferent_access - end + when Proc + strategy.call(request.raw_post) + when :xml_simple, :xml_node + request.body.size == 0 ? {} : Hash.from_xml(request.body).with_indifferent_access + when :yaml + YAML.load(request.body) + when :json + if request.body.size == 0 + {} else - false + data = ActiveSupport::JSON.decode(request.body) + data = {:_json => data} unless data.is_a?(Hash) + data.with_indifferent_access + end + else + false end rescue Exception => e # YAML, XML or Ruby code block errors logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{request.raw_post}" raise - { "body" => request.raw_post, - "content_type" => request.content_type, + { "body" => request.raw_post, + "content_type" => request.content_type, "content_length" => request.content_length, - "exception" => "#{e.message} (#{e.class})", - "backtrace" => e.backtrace } + "exception" => "#{e.message} (#{e.class})", + "backtrace" => e.backtrace } end def content_type_from_legacy_post_data_format_header(env) if x_post_format = env['HTTP_X_POST_DATA_FORMAT'] case x_post_format.to_s.downcase - when 'yaml' - return Mime::YAML - when 'xml' - return Mime::XML + when 'yaml' then return Mime::YAML + when 'xml' then return Mime::XML end end @@ -76,4 +75,4 @@ module ActionDispatch defined?(Rails.logger) ? Rails.logger : Logger.new($stderr) end end -end +end
\ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb index c5c06f74a2..7d4f0998ce 100644 --- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb @@ -1,4 +1,5 @@ require 'rack/utils' +require 'rack/request' module ActionDispatch module Session diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index bd552b458a..f27f22c7e7 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -1,4 +1,5 @@ -require "active_support/core_ext/hash/keys" +require 'active_support/core_ext/hash/keys' +require 'rack/request' module ActionDispatch module Session @@ -49,7 +50,7 @@ module ActionDispatch :expire_after => nil, :httponly => true }.freeze - + class OptionsHash < Hash def initialize(by, env, default_options) @session_data = env[CookieStore::ENV_SESSION_KEY] @@ -60,7 +61,7 @@ module ActionDispatch key == :id ? @session_data[:session_id] : super(key) end end - + ENV_SESSION_KEY = "rack.session".freeze ENV_SESSION_OPTIONS_KEY = "rack.session.options".freeze HTTP_SET_COOKIE = "Set-Cookie".freeze @@ -102,7 +103,7 @@ module ActionDispatch def call(env) env[ENV_SESSION_KEY] = AbstractStore::SessionHash.new(self, env) env[ENV_SESSION_OPTIONS_KEY] = OptionsHash.new(self, env, @default_options) - + status, headers, body = @app.call(env) session_data = env[ENV_SESSION_KEY] diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index bd87764f5b..4ebc8a2ab9 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -1,4 +1,5 @@ -require "active_support/core_ext/exception" +require 'active_support/core_ext/exception' +require 'action_dispatch/http/request' module ActionDispatch class ShowExceptions @@ -101,7 +102,7 @@ module ActionDispatch end def status_code(exception) - ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[@@rescue_responses[exception.class.name]] + Rack::Utils.status_code(@@rescue_responses[exception.class.name]) end def render(status, body) diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index d480af876d..e655d6a708 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -19,9 +19,9 @@ module ActionDispatch @constraints.each { |constraint| if constraint.respond_to?(:matches?) && !constraint.matches?(req) - return [417, {}, []] + return [ 404, {'X-Cascade' => 'pass'}, [] ] elsif constraint.respond_to?(:call) && !constraint.call(req) - return [417, {}, []] + return [ 404, {'X-Cascade' => 'pass'}, [] ] end } @@ -29,90 +29,138 @@ module ActionDispatch end end - module Base - def initialize(set) - @set = set + class Mapping + def initialize(set, scope, args) + @set, @scope = set, scope + @path, @options = extract_path_and_options(args) end - def root(options = {}) - match '/', options.merge(:as => :root) + def to_route + [ app, conditions, requirements, defaults, @options[:as] ] end - def match(*args) - options = args.extract_options! + private + def extract_path_and_options(args) + options = args.extract_options! - path = args.first + if args.empty? + path, to = options.find { |name, value| name.is_a?(String) } + options.merge!(:to => to).delete(path) if path + else + path = args.first + end - conditions, defaults = {}, {} + [ normalize_path(path), options ] + end - path = nil if path == "" - path = "#{@scope[:path]}#{path}" if @scope[:path] - path = Rack::Mount::Utils.normalize_path(path) if path + def normalize_path(path) + path = nil if path == "" + path = "#{@scope[:path]}#{path}" if @scope[:path] + path = Rack::Mount::Utils.normalize_path(path) if path - raise ArgumentError, "path is required" unless path + raise ArgumentError, "path is required" unless path - constraints = options[:constraints] || {} - unless constraints.is_a?(Hash) - block, constraints = constraints, {} + path end - blocks = ((@scope[:blocks] || []) + [block]).compact - constraints = (@scope[:constraints] || {}).merge(constraints) - options.each { |k, v| constraints[k] = v if v.is_a?(Regexp) } - conditions[:path_info] = path - requirements = constraints.dup - path_regexp = Rack::Mount::Strexp.compile(path, constraints, SEPARATORS) - segment_keys = Rack::Mount::RegexpWithNamedGroups.new(path_regexp).names - constraints.reject! { |k, v| segment_keys.include?(k.to_s) } - conditions.merge!(constraints) + def app + Constraints.new( + to.respond_to?(:call) ? to : Routing::RouteSet::Dispatcher.new(:defaults => defaults), + blocks + ) + end - requirements[:controller] ||= @set.controller_constraints + def conditions + { :path_info => @path }.merge(constraints).merge(request_method_condition) + end - if via = options[:via] - via = Array(via).map { |m| m.to_s.upcase } - conditions[:request_method] = Regexp.union(*via) + def requirements + @requirements ||= returning(@options[:constraints] || {}) do |requirements| + requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] + @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } + requirements[:controller] ||= @set.controller_constraints + end end - defaults[:controller] ||= @scope[:controller].to_s if @scope[:controller] + def defaults + @defaults ||= if to.respond_to?(:call) + { } + else + defaults = case to + when String + controller, action = to.split('#') + { :controller => controller, :action => action } + when Symbol + { :action => to.to_s }.merge(default_controller ? { :controller => default_controller } : {}) + else + default_controller ? { :controller => default_controller } : {} + end - app = initialize_app_endpoint(options, defaults) - validate_defaults!(app, defaults, segment_keys) - app = Constraints.new(app, blocks) + if defaults[:controller].blank? && segment_keys.exclude?("controller") + raise ArgumentError, "missing :controller" + end - @set.add_route(app, conditions, requirements, defaults, options[:as]) + if defaults[:action].blank? && segment_keys.exclude?("action") + raise ArgumentError, "missing :action" + end - self - end + defaults + end + end - private - def initialize_app_endpoint(options, defaults) - app = nil - - if options[:to].respond_to?(:call) - app = options[:to] - defaults.delete(:controller) - defaults.delete(:action) - elsif options[:to].is_a?(String) - defaults[:controller], defaults[:action] = options[:to].split('#') - elsif options[:to].is_a?(Symbol) - defaults[:action] = options[:to].to_s + + def blocks + if @options[:constraints].present? && !@options[:constraints].is_a?(Hash) + block = @options[:constraints] + else + block = nil end - app || Routing::RouteSet::Dispatcher.new(:defaults => defaults) + ((@scope[:blocks] || []) + [ block ]).compact end - def validate_defaults!(app, defaults, segment_keys) - return unless app.is_a?(Routing::RouteSet::Dispatcher) + def constraints + @constraints ||= requirements.reject { |k, v| segment_keys.include?(k.to_s) || k == :controller } + end - unless defaults.include?(:controller) || segment_keys.include?("controller") - raise ArgumentError, "missing :controller" + def request_method_condition + if via = @options[:via] + via = Array(via).map { |m| m.to_s.upcase } + { :request_method => Regexp.union(*via) } + else + { } end + end - unless defaults.include?(:action) || segment_keys.include?("action") - raise ArgumentError, "missing :action" - end + def segment_keys + @segment_keys ||= Rack::Mount::RegexpWithNamedGroups.new( + Rack::Mount::Strexp.compile(@path, requirements, SEPARATORS) + ).names + end + + def to + @options[:to] end + + def default_controller + @scope[:controller].to_s if @scope[:controller] + end + end + + module Base + def initialize(set) + @set = set + end + + def root(options = {}) + match '/', options.reverse_merge(:as => :root) + end + + def match(*args) + @set.add_route(*Mapping.new(@set, @scope, args).to_route) + self + end end module HttpHelpers @@ -132,13 +180,20 @@ module ActionDispatch map_method(:delete, *args, &block) end - def redirect(path, options = {}) - status = options[:status] || 301 - lambda { |env| - req = Rack::Request.new(env) - url = req.scheme + '://' + req.host + path - [status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']] - } + def redirect(*args, &block) + options = args.last.is_a?(Hash) ? args.pop : {} + + path = args.shift || block + path_proc = path.is_a?(Proc) ? path : proc { |params| path % params } + status = options[:status] || 301 + + lambda do |env| + req = Rack::Request.new(env) + params = path_proc.call(env["action_dispatch.request.path_parameters"]) + url = req.scheme + '://' + req.host + params + + [ status, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently'] ] + end end private @@ -201,11 +256,11 @@ module ActionDispatch self ensure - @scope[:path] = path if path_set + @scope[:path] = path if path_set @scope[:name_prefix] = name_prefix if name_prefix_set - @scope[:controller] = controller if controller_set - @scope[:options] = options - @scope[:blocks] = blocks + @scope[:controller] = controller if controller_set + @scope[:options] = options + @scope[:blocks] = blocks @scope[:constraints] = constraints end @@ -301,12 +356,12 @@ module ActionDispatch with_scope_level(:resource, resource) do yield if block_given? - get "(.:format)", :to => :show, :as => resource.member_name - post "(.:format)", :to => :create - put "(.:format)", :to => :update - delete "(.:format)", :to => :destroy - get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}" - get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}" + get "(.:format)", :to => :show, :as => resource.member_name + post "(.:format)", :to => :create + put "(.:format)", :to => :update + delete "(.:format)", :to => :destroy + get "/new(.:format)", :to => :new, :as => "new_#{resource.singular}" + get "/edit(.:format)", :to => :edit, :as => "edit_#{resource.singular}" end end @@ -336,8 +391,9 @@ module ActionDispatch yield if block_given? with_scope_level(:collection) do - get "(.:format)", :to => :index, :as => resource.collection_name + get "(.:format)", :to => :index, :as => resource.collection_name post "(.:format)", :to => :create + with_exclusive_name_prefix :new do get "/new(.:format)", :to => :new, :as => resource.singular end @@ -345,9 +401,10 @@ module ActionDispatch with_scope_level(:member) do scope("/:id") do - get "(.:format)", :to => :show, :as => resource.member_name - put "(.:format)", :to => :update + get "(.:format)", :to => :show, :as => resource.member_name + put "(.:format)", :to => :update delete "(.:format)", :to => :destroy + with_exclusive_name_prefix :edit do get "/edit(.:format)", :to => :edit, :as => resource.singular end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index bf2443c1be..bd397432ce 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -5,7 +5,7 @@ module ActionDispatch module Routing class RouteSet #:nodoc: NotFound = lambda { |env| - raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect} with #{env.inspect}" + raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}" } PARAMETERS_KEY = 'action_dispatch.request.path_parameters' @@ -21,7 +21,7 @@ module ActionDispatch prepare_params!(params) unless controller = controller(params) - return [417, {}, []] + return [404, {'X-Cascade' => 'pass'}, []] end controller.action(params[:action]).call(env) @@ -273,7 +273,7 @@ module ActionDispatch # TODO: Move this into Railties if defined?(Rails.application) # Find namespaces in controllers/ directory - Rails.application.configuration.controller_paths.each do |load_path| + Rails.application.config.controller_paths.each do |load_path| load_path = File.expand_path(load_path) Dir["#{load_path}/**/*_controller.rb"].collect do |path| namespaces << File.dirname(path).sub(/#{load_path}\/?/, '') @@ -426,7 +426,7 @@ module ActionDispatch end end - raise ActionController::RoutingError, "No route matches #{path.inspect} with #{environment.inspect}" + raise ActionController::RoutingError, "No route matches #{path.inspect}" end end end diff --git a/actionpack/lib/action_dispatch/testing/assertions/dom.rb b/actionpack/lib/action_dispatch/testing/assertions/dom.rb index 9a917f704a..9c215de743 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/dom.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/dom.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + module ActionDispatch module Assertions module DomAssertions @@ -15,7 +17,7 @@ module ActionDispatch assert_block(full_message) { expected_dom == actual_dom } end - + # The negated form of +assert_dom_equivalent+. # # ==== Examples diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 501a7c4dfb..5686bbdbde 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -28,7 +28,7 @@ module ActionDispatch assert_block("") { true } # to count the assertion elsif type.is_a?(Fixnum) && @response.response_code == type assert_block("") { true } # to count the assertion - elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type] + elsif type.is_a?(Symbol) && @response.response_code == Rack::Utils::SYMBOL_TO_STATUS_CODE[type] assert_block("") { true } # to count the assertion else assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false } diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb index d22adfa749..c2dc591ff7 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + #-- # Copyright (c) 2006 Assaf Arkin (http://labnotes.org) # Under MIT and/or CC By license. @@ -16,7 +18,7 @@ module ActionDispatch # # Use +css_select+ to select elements without making an assertions, either # from the response HTML or elements selected by the enclosing assertion. - # + # # In addition to HTML responses, you can make the following assertions: # * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations. # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions. @@ -53,8 +55,8 @@ module ActionDispatch # end # # # Selects all list items in unordered lists - # items = css_select("ul>li") - # + # items = css_select("ul>li") + # # # Selects all form tags and then all inputs inside the form # forms = css_select("form") # forms.each do |form| @@ -212,7 +214,7 @@ module ActionDispatch # Otherwise just operate on the response document. root = response_from_page_or_rjs end - + # First or second argument is the selector: string and we pass # all remaining arguments. Array and we pass the argument. Also # accepts selector itself. @@ -225,7 +227,7 @@ module ActionDispatch selector = arg else raise ArgumentError, "Expecting a selector as the first argument" end - + # Next argument is used for equality tests. equals = {} case arg = args.shift @@ -315,10 +317,10 @@ module ActionDispatch # Returns all matches elements. matches end - + def count_description(min, max) #:nodoc: pluralize = lambda {|word, quantity| word << (quantity == 1 ? '' : 's')} - + if min && max && (max != min) "between #{min} and #{max} elements" elsif min && !(min == 1 && max == 1) @@ -327,7 +329,7 @@ module ActionDispatch "at most #{max} #{pluralize['element', max]}" end end - + # :call-seq: # assert_select_rjs(id?) { |elements| ... } # assert_select_rjs(statement, id?) { |elements| ... } @@ -344,7 +346,7 @@ module ActionDispatch # that update or insert an element with that identifier. # # Use the first argument to narrow down assertions to only statements - # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>, + # of that type. Possible values are <tt>:replace</tt>, <tt>:replace_html</tt>, # <tt>:show</tt>, <tt>:hide</tt>, <tt>:toggle</tt>, <tt>:remove</tta>, # <tt>:insert_html</tt> and <tt>:redirect</tt>. # @@ -494,7 +496,7 @@ module ActionDispatch # end # end # end - # + # # # # Selects all paragraph tags from within the description of an RSS feed # assert_select_feed :rss, 2.0 do diff --git a/actionpack/lib/action_dispatch/testing/assertions/tag.rb b/actionpack/lib/action_dispatch/testing/assertions/tag.rb index b74dcb1fe4..5c735e61b2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/tag.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/tag.rb @@ -1,3 +1,5 @@ +require 'action_controller/vendor/html-scanner' + module ActionDispatch module Assertions # Pair of assertions to testing elements in the HTML output of the response. diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 5c127dfe37..2a5f5dcd5c 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -411,7 +411,7 @@ module ActionDispatch # At its simplest, you simply extend IntegrationTest and write your tests # using the get/post methods: # - # require "#{File.dirname(__FILE__)}/test_helper" + # require "test_helper" # # class ExampleTest < ActionController::IntegrationTest # fixtures :people @@ -435,7 +435,7 @@ module ActionDispatch # powerful testing DSL that is specific for your application. You can even # reference any named routes you happen to have defined! # - # require "#{File.dirname(__FILE__)}/test_helper" + # require "test_helper" # # class AdvancedTest < ActionController::IntegrationTest # fixtures :people, :rooms |