mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge commit 'rails/master'
This commit is contained in:
commit
4c4fd1a60f
78 changed files with 911 additions and 514 deletions
3
Gemfile
3
Gemfile
|
@ -1,8 +1,7 @@
|
|||
path File.dirname(__FILE__)
|
||||
source 'http://rubygems.org'
|
||||
|
||||
gem "arel", :git => "git://github.com/rails/arel.git"
|
||||
gem "rails", "3.0.0.beta2"
|
||||
gem "rails", :path => File.dirname(__FILE__)
|
||||
|
||||
gem "rake", ">= 0.8.7"
|
||||
gem "mocha", ">= 0.9.8"
|
||||
|
|
|
@ -1 +1 @@
|
|||
3.0.0.beta2
|
||||
3.0.0.beta3
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
*Rails 3.0.0 [Edge] (pending)*
|
||||
|
||||
* Added all the new HTML5 form types as individual form tag methods (search, url, number, etc) #3646 [Stephen Celis]
|
||||
|
||||
* Changed the object used in routing constraints to be an instance of
|
||||
ActionDispatch::Request rather than Rack::Request
|
||||
ActionDispatch::Request rather than Rack::Request [YK]
|
||||
|
||||
* Changed ActionDispatch::Request#method to return a String, to be compatible
|
||||
with Rack::Request. Added ActionDispatch::Request#method_symbol to
|
||||
return a symbol form of the request method.
|
||||
return a symbol form of the request method. [YK]
|
||||
|
||||
* Changed ActionDispatch::Request#method to return the original
|
||||
method and #request_method to return the overridden method in the
|
||||
case of methodoverride being used (this means that #method returns
|
||||
"HEAD" and #request_method returns "GET" in HEAD requests). This
|
||||
is for compatibility with Rack::Request
|
||||
is for compatibility with Rack::Request [YK]
|
||||
|
||||
|
||||
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
|
||||
|
||||
|
|
|
@ -89,9 +89,16 @@ module AbstractController
|
|||
# Normalize arguments, options and then delegates render_to_body and
|
||||
# sticks the result in self.response_body.
|
||||
def render(*args, &block)
|
||||
self.response_body = render_to_string(*args, &block)
|
||||
end
|
||||
|
||||
# Raw rendering of a template to a string. Just convert the results of
|
||||
# render_to_body into a String.
|
||||
# :api: plugin
|
||||
def render_to_string(*args, &block)
|
||||
options = _normalize_args(*args, &block)
|
||||
_normalize_options(options)
|
||||
self.response_body = render_to_body(options)
|
||||
render_to_body(options)
|
||||
end
|
||||
|
||||
# Raw rendering of a template to a Rack-compatible body.
|
||||
|
@ -101,14 +108,6 @@ module AbstractController
|
|||
_render_template(options)
|
||||
end
|
||||
|
||||
# Raw rendering of a template to a string. Just convert the results of
|
||||
# render_to_body into a String.
|
||||
# :api: plugin
|
||||
def render_to_string(options={})
|
||||
_normalize_options(options)
|
||||
render_to_body(options)
|
||||
end
|
||||
|
||||
# Find and renders a template based on the options given.
|
||||
# :api: private
|
||||
def _render_template(options) #:nodoc:
|
||||
|
|
|
@ -2,48 +2,59 @@ module ActionController
|
|||
class Base < Metal
|
||||
abstract!
|
||||
|
||||
include AbstractController::Layouts
|
||||
include AbstractController::Translation
|
||||
def self.without_modules(*modules)
|
||||
modules = modules.map do |m|
|
||||
m.is_a?(Symbol) ? ActionController.const_get(m) : m
|
||||
end
|
||||
|
||||
include ActionController::Helpers
|
||||
|
||||
include ActionController::HideActions
|
||||
include ActionController::UrlFor
|
||||
include ActionController::Redirecting
|
||||
include ActionController::Rendering
|
||||
include ActionController::Renderers::All
|
||||
include ActionController::ConditionalGet
|
||||
include ActionController::RackDelegation
|
||||
MODULES - modules
|
||||
end
|
||||
|
||||
# Legacy modules
|
||||
include SessionManagement
|
||||
include ActionController::Caching
|
||||
include ActionController::MimeResponds
|
||||
include ActionController::PolymorphicRoutes
|
||||
MODULES = [
|
||||
AbstractController::Layouts,
|
||||
AbstractController::Translation,
|
||||
|
||||
Helpers,
|
||||
HideActions,
|
||||
UrlFor,
|
||||
Redirecting,
|
||||
Rendering,
|
||||
Renderers::All,
|
||||
ConditionalGet,
|
||||
RackDelegation,
|
||||
SessionManagement,
|
||||
Caching,
|
||||
MimeResponds,
|
||||
PolymorphicRoutes,
|
||||
ImplicitRender,
|
||||
|
||||
Cookies,
|
||||
Flash,
|
||||
Verification,
|
||||
RequestForgeryProtection,
|
||||
Streaming,
|
||||
RecordIdentifier,
|
||||
HttpAuthentication::Basic::ControllerMethods,
|
||||
HttpAuthentication::Digest::ControllerMethods,
|
||||
|
||||
# Add instrumentations hooks at the bottom, to ensure they instrument
|
||||
# all the methods properly.
|
||||
Instrumentation,
|
||||
|
||||
# Before callbacks should also be executed the earliest as possible, so
|
||||
# also include them at the bottom.
|
||||
AbstractController::Callbacks,
|
||||
|
||||
# The same with rescue, append it at the end to wrap as much as possible.
|
||||
Rescue
|
||||
]
|
||||
|
||||
MODULES.each do |mod|
|
||||
include mod
|
||||
end
|
||||
|
||||
# Rails 2.x compatibility
|
||||
include ActionController::Compatibility
|
||||
include ActionController::ImplicitRender
|
||||
|
||||
include ActionController::Cookies
|
||||
include ActionController::Flash
|
||||
include ActionController::Verification
|
||||
include ActionController::RequestForgeryProtection
|
||||
include ActionController::Streaming
|
||||
include ActionController::RecordIdentifier
|
||||
include ActionController::HttpAuthentication::Basic::ControllerMethods
|
||||
include ActionController::HttpAuthentication::Digest::ControllerMethods
|
||||
|
||||
# Add instrumentations hooks at the bottom, to ensure they instrument
|
||||
# all the methods properly.
|
||||
include ActionController::Instrumentation
|
||||
|
||||
# Before callbacks should also be executed the earliest as possible, so
|
||||
# also include them at the bottom.
|
||||
include AbstractController::Callbacks
|
||||
|
||||
# The same with rescue, append it at the end to wrap as much as possible.
|
||||
include ActionController::Rescue
|
||||
|
||||
def self.inherited(klass)
|
||||
::ActionController::Base.subclasses << klass.to_s
|
||||
|
@ -55,15 +66,6 @@ module ActionController
|
|||
@subclasses ||= []
|
||||
end
|
||||
|
||||
# This method has been moved to ActionDispatch::Request.filter_parameters
|
||||
def self.filter_parameter_logging(*args, &block)
|
||||
ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
|
||||
filter = Rails.application.config.filter_parameters
|
||||
filter.concat(args)
|
||||
filter << block if block
|
||||
filter
|
||||
end
|
||||
|
||||
ActiveSupport.run_load_hooks(:action_controller, self)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,15 @@ module ActionController
|
|||
deprecated_config_writer(option, message)
|
||||
end
|
||||
|
||||
# This method has been moved to ActionDispatch::Request.filter_parameters
|
||||
def filter_parameter_logging(*args, &block)
|
||||
ActiveSupport::Deprecation.warn("Setting filter_parameter_logging in ActionController is deprecated and has no longer effect, please set 'config.filter_parameters' in config/application.rb instead", caller)
|
||||
filter = Rails.application.config.filter_parameters
|
||||
filter.concat(args)
|
||||
filter << block if block
|
||||
filter
|
||||
end
|
||||
|
||||
def deprecated_config_reader(option, message = nil)
|
||||
message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \
|
||||
"Please read it from config.#{option}"
|
||||
|
@ -68,14 +77,11 @@ module ActionController
|
|||
|
||||
def cookie_verifier_secret=(value)
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret= is deprecated. " <<
|
||||
"Please configure it on your application with config.cookie_secret=", caller
|
||||
ActionController::Base.config.secret = value
|
||||
"Please configure it on your application with config.secret_token=", caller
|
||||
end
|
||||
|
||||
def cookie_verifier_secret
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated. " <<
|
||||
"Please use ActionController::Base.config.secret instead.", caller
|
||||
ActionController::Base.config.secret
|
||||
ActiveSupport::Deprecation.warn "ActionController::Base.cookie_verifier_secret is deprecated.", caller
|
||||
end
|
||||
|
||||
def trusted_proxies=(value)
|
||||
|
|
|
@ -10,8 +10,7 @@ module ActionController #:nodoc:
|
|||
|
||||
private
|
||||
def cookies
|
||||
raise "You must set config.cookie_secret in your app's config" if config.secret.blank?
|
||||
request.cookie_jar(:signing_secret => config.secret)
|
||||
request.cookie_jar
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -159,7 +159,7 @@ module ActionController
|
|||
|
||||
# Authenticate with HTTP Digest, returns true or false
|
||||
def authenticate_with_http_digest(realm = "Application", &password_procedure)
|
||||
HttpAuthentication::Digest.authenticate(config.secret, request, realm, &password_procedure)
|
||||
HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
|
||||
end
|
||||
|
||||
# Render output including the HTTP Digest authentication header
|
||||
|
@ -169,14 +169,15 @@ module ActionController
|
|||
end
|
||||
|
||||
# Returns false on a valid response, true otherwise
|
||||
def authenticate(secret_key, request, realm, &password_procedure)
|
||||
request.authorization && validate_digest_response(secret_key, request, realm, &password_procedure)
|
||||
def authenticate(request, realm, &password_procedure)
|
||||
request.authorization && validate_digest_response(request, realm, &password_procedure)
|
||||
end
|
||||
|
||||
# Returns false unless the request credentials response value matches the expected value.
|
||||
# First try the password as a ha1 digest password. If this fails, then try it as a plain
|
||||
# text password.
|
||||
def validate_digest_response(secret_key, request, realm, &password_procedure)
|
||||
def validate_digest_response(request, realm, &password_procedure)
|
||||
secret_key = secret_token(request)
|
||||
credentials = decode_credentials_header(request)
|
||||
valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])
|
||||
|
||||
|
@ -225,7 +226,7 @@ module ActionController
|
|||
end
|
||||
|
||||
def authentication_header(controller, realm)
|
||||
secret_key = controller.config.secret
|
||||
secret_key = secret_token(controller.request)
|
||||
nonce = self.nonce(secret_key)
|
||||
opaque = opaque(secret_key)
|
||||
controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
|
||||
|
@ -238,6 +239,12 @@ module ActionController
|
|||
controller.status = 401
|
||||
end
|
||||
|
||||
def secret_token(request)
|
||||
secret = request.env["action_dispatch.secret_token"]
|
||||
raise "You must set config.secret_token in your app's config" if secret.blank?
|
||||
secret
|
||||
end
|
||||
|
||||
# Uses an MD5 digest based on time to generate a value to be used only once.
|
||||
#
|
||||
# A server-specified data string which should be uniquely generated each time a 401 response is made.
|
||||
|
|
|
@ -51,7 +51,6 @@ module ActionController
|
|||
ac.assets_dir = paths.public.to_a.first
|
||||
ac.javascripts_dir = paths.public.javascripts.to_a.first
|
||||
ac.stylesheets_dir = paths.public.stylesheets.to_a.first
|
||||
ac.secret = app.config.cookie_secret
|
||||
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
self.config.merge!(ac)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
require "active_support/core_ext/object/blank"
|
||||
|
||||
module ActionDispatch
|
||||
class Request
|
||||
def cookie_jar(config = {})
|
||||
env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self, config)
|
||||
def cookie_jar
|
||||
env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -51,17 +53,17 @@ module ActionDispatch
|
|||
# only HTTP. Defaults to +false+.
|
||||
class Cookies
|
||||
class CookieJar < Hash #:nodoc:
|
||||
def self.build(request, config = {})
|
||||
new(config).tap do |hash|
|
||||
def self.build(request)
|
||||
secret = request.env["action_dispatch.secret_token"]
|
||||
new(secret).tap do |hash|
|
||||
hash.update(request.cookies)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(config = {})
|
||||
@config = config
|
||||
def initialize(secret=nil)
|
||||
@secret = secret
|
||||
@set_cookies = {}
|
||||
@delete_cookies = {}
|
||||
|
||||
super()
|
||||
end
|
||||
|
||||
|
@ -112,7 +114,7 @@ module ActionDispatch
|
|||
# cookies.permanent.signed[:remember_me] = current_user.id
|
||||
# # => Set-Cookie: discount=BAhU--848956038e692d7046deab32b7131856ab20e14e; path=/; expires=Sun, 16-Dec-2029 03:24:16 GMT
|
||||
def permanent
|
||||
@permanent ||= PermanentCookieJar.new(self, @config)
|
||||
@permanent ||= PermanentCookieJar.new(self, @secret)
|
||||
end
|
||||
|
||||
# Returns a jar that'll automatically generate a signed representation of cookie value and verify it when reading from
|
||||
|
@ -120,7 +122,7 @@ module ActionDispatch
|
|||
# cookie was tampered with by the user (or a 3rd party), an ActiveSupport::MessageVerifier::InvalidSignature exception will
|
||||
# be raised.
|
||||
#
|
||||
# This jar requires that you set a suitable secret for the verification on your app's config.cookie_secret.
|
||||
# This jar requires that you set a suitable secret for the verification on your app's config.secret_token.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
|
@ -129,7 +131,7 @@ module ActionDispatch
|
|||
#
|
||||
# cookies.signed[:discount] # => 45
|
||||
def signed
|
||||
@signed ||= SignedCookieJar.new(self, @config)
|
||||
@signed ||= SignedCookieJar.new(self, @secret)
|
||||
end
|
||||
|
||||
def write(response)
|
||||
|
@ -139,9 +141,8 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
class PermanentCookieJar < CookieJar #:nodoc:
|
||||
def initialize(parent_jar, config = {})
|
||||
@parent_jar = parent_jar
|
||||
@config = config
|
||||
def initialize(parent_jar, secret)
|
||||
@parent_jar, @secret = parent_jar, secret
|
||||
end
|
||||
|
||||
def []=(key, options)
|
||||
|
@ -156,7 +157,7 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
def signed
|
||||
@signed ||= SignedCookieJar.new(self, @config)
|
||||
@signed ||= SignedCookieJar.new(self, @secret)
|
||||
end
|
||||
|
||||
def method_missing(method, *arguments, &block)
|
||||
|
@ -165,11 +166,10 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
class SignedCookieJar < CookieJar #:nodoc:
|
||||
def initialize(parent_jar, config = {})
|
||||
raise 'Missing cookie signing secret' if config[:signing_secret].blank?
|
||||
def initialize(parent_jar, secret)
|
||||
raise "You must set config.secret_token in your app's config" if secret.blank?
|
||||
@parent_jar = parent_jar
|
||||
@config = config
|
||||
@verifier = ActiveSupport::MessageVerifier.new(config[:signing_secret])
|
||||
@verifier = ActiveSupport::MessageVerifier.new(secret)
|
||||
end
|
||||
|
||||
def [](name)
|
||||
|
|
|
@ -192,7 +192,7 @@ module ActionDispatch
|
|||
if secret.blank?
|
||||
raise ArgumentError, "A secret is required to generate an " +
|
||||
"integrity hash for cookie session data. Use " +
|
||||
"config.cookie_secret = \"some secret phrase of at " +
|
||||
"config.secret_token = \"some secret phrase of at " +
|
||||
"least #{SECRET_MIN_LENGTH} characters\"" +
|
||||
"in config/application.rb"
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'stringio'
|
||||
require 'uri'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'rack/test'
|
||||
require 'test/unit/assertions'
|
||||
|
||||
|
@ -137,7 +137,10 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
# The hostname used in the last request.
|
||||
attr_accessor :host
|
||||
def host
|
||||
@host || DEFAULT_HOST
|
||||
end
|
||||
attr_writer :host
|
||||
|
||||
# The remote_addr used in the last request.
|
||||
attr_accessor :remote_addr
|
||||
|
@ -148,7 +151,7 @@ module ActionDispatch
|
|||
# A map of the cookies returned by the last response, and which will be
|
||||
# sent with the next request.
|
||||
def cookies
|
||||
@mock_session.cookie_jar
|
||||
_mock_session.cookie_jar
|
||||
end
|
||||
|
||||
# A reference to the controller instance used by the last request.
|
||||
|
@ -189,8 +192,8 @@ module ActionDispatch
|
|||
# session.reset!
|
||||
def reset!
|
||||
@https = false
|
||||
@mock_session = Rack::MockSession.new(@app, DEFAULT_HOST)
|
||||
@controller = @request = @response = nil
|
||||
@_mock_session = nil
|
||||
@request_count = 0
|
||||
|
||||
self.host = DEFAULT_HOST
|
||||
|
@ -234,6 +237,9 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
private
|
||||
def _mock_session
|
||||
@_mock_session ||= Rack::MockSession.new(@app, host)
|
||||
end
|
||||
|
||||
# Performs the actual request.
|
||||
def process(method, path, parameters = nil, rack_environment = nil)
|
||||
|
@ -254,7 +260,7 @@ module ActionDispatch
|
|||
:method => method,
|
||||
:params => parameters,
|
||||
|
||||
"SERVER_NAME" => host,
|
||||
"SERVER_NAME" => host.split(':')[0],
|
||||
"SERVER_PORT" => (https? ? "443" : "80"),
|
||||
"HTTPS" => https? ? "on" : "off",
|
||||
"rack.url_scheme" => https? ? "https" : "http",
|
||||
|
@ -266,17 +272,25 @@ module ActionDispatch
|
|||
"HTTP_ACCEPT" => accept
|
||||
}
|
||||
|
||||
session = Rack::Test::Session.new(@mock_session)
|
||||
session = Rack::Test::Session.new(_mock_session)
|
||||
|
||||
(rack_environment || {}).each do |key, value|
|
||||
env[key] = value
|
||||
end
|
||||
|
||||
session.request(path, env)
|
||||
# NOTE: rack-test v0.5 doesn't build a default uri correctly
|
||||
# Make sure requested path is always a full uri
|
||||
uri = URI.parse('/')
|
||||
uri.scheme ||= env['rack.url_scheme']
|
||||
uri.host ||= env['SERVER_NAME']
|
||||
uri.port ||= env['SERVER_PORT'].try(:to_i)
|
||||
uri += path
|
||||
|
||||
session.request(uri.to_s, env)
|
||||
|
||||
@request_count += 1
|
||||
@request = ActionDispatch::Request.new(session.last_request.env)
|
||||
response = @mock_session.last_response
|
||||
response = _mock_session.last_response
|
||||
@response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body)
|
||||
@html_document = nil
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/hash/reverse_merge'
|
||||
|
||||
module ActionDispatch
|
||||
class TestRequest < Request
|
||||
|
@ -9,6 +10,7 @@ module ActionDispatch
|
|||
end
|
||||
|
||||
def initialize(env = {})
|
||||
env = Rails.application.env_defaults.merge(env) if defined?(Rails.application)
|
||||
super(DEFAULT_ENV.merge(env))
|
||||
|
||||
self.host = 'test.host'
|
||||
|
|
|
@ -300,15 +300,16 @@ module ActionView
|
|||
|
||||
case record_or_name_or_array
|
||||
when String, Symbol
|
||||
ActiveSupport::Deprecation.warn("Using form_for(:name, @resource) is deprecated. Please use form_for(@resource, :as => :name) instead.", caller) unless args.empty?
|
||||
object_name = record_or_name_or_array
|
||||
when Array
|
||||
object = record_or_name_or_array.last
|
||||
object_name = ActionController::RecordIdentifier.singular_class_name(object)
|
||||
object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
|
||||
apply_form_for_options!(record_or_name_or_array, options)
|
||||
args.unshift object
|
||||
else
|
||||
object = record_or_name_or_array
|
||||
object_name = ActionController::RecordIdentifier.singular_class_name(object)
|
||||
object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
|
||||
apply_form_for_options!([object], options)
|
||||
args.unshift object
|
||||
end
|
||||
|
@ -326,9 +327,13 @@ module ActionView
|
|||
|
||||
html_options =
|
||||
if object.respond_to?(:persisted?) && object.persisted?
|
||||
{ :class => dom_class(object, :edit), :id => dom_id(object, :edit), :method => :put }
|
||||
{ :class => options[:as] ? "#{options[:as]}_edit" : dom_class(object, :edit),
|
||||
:id => options[:as] ? "#{options[:as]}_edit" : dom_id(object, :edit),
|
||||
:method => :put }
|
||||
else
|
||||
{ :class => dom_class(object, :new), :id => dom_id(object), :method => :post }
|
||||
{ :class => options[:as] ? "#{options[:as]}_new" : dom_class(object, :new),
|
||||
:id => options[:as] ? "#{options[:as]}_new" : dom_id(object),
|
||||
:method => :post }
|
||||
end
|
||||
|
||||
options[:html] ||= {}
|
||||
|
@ -779,6 +784,56 @@ module ActionView
|
|||
def radio_button(object_name, method, tag_value, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_radio_button_tag(tag_value, options)
|
||||
end
|
||||
|
||||
# Returns a text_field of type "search".
|
||||
def search_field(object_name, method, options = {})
|
||||
options = options.stringify_keys
|
||||
|
||||
if options["autosave"]
|
||||
if options["autosave"] == true
|
||||
options["autosave"] = request.host.split(".").reverse.join(".")
|
||||
end
|
||||
options["results"] ||= 10
|
||||
end
|
||||
|
||||
if options["onsearch"]
|
||||
options["incremental"] = true unless options.has_key?("incremental")
|
||||
end
|
||||
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("search", options)
|
||||
end
|
||||
|
||||
# Returns a text_field of type "tel".
|
||||
def telephone_field(object_name, method, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("tel", options)
|
||||
end
|
||||
alias phone_field telephone_field
|
||||
|
||||
# Returns a text_field of type "url".
|
||||
def url_field(object_name, method, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("url", options)
|
||||
end
|
||||
|
||||
# Returns a text_field of type "email".
|
||||
def email_field(object_name, method, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("email", options)
|
||||
end
|
||||
|
||||
# Returns an input tag of type "number".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts same options as number_field_tag
|
||||
def number_field(object_name, method, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("number", options)
|
||||
end
|
||||
|
||||
# Returns an input tag of type "range".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts same options as range_field_tag
|
||||
def range_field(object_name, method, options = {})
|
||||
InstanceTag.new(object_name, method, self, options.delete(:object)).to_number_field_tag("range", options)
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceTagMethods #:nodoc:
|
||||
|
@ -842,6 +897,14 @@ module ActionView
|
|||
tag("input", options)
|
||||
end
|
||||
|
||||
def to_number_field_tag(field_type, options = {})
|
||||
options = options.stringify_keys
|
||||
if range = options.delete("in") || options.delete("within")
|
||||
options.update("min" => range.min, "max" => range.max)
|
||||
end
|
||||
to_input_field_tag(field_type, options)
|
||||
end
|
||||
|
||||
def to_radio_button_tag(tag_value, options = {})
|
||||
options = DEFAULT_RADIO_OPTIONS.merge(options.stringify_keys)
|
||||
options["type"] = "radio"
|
||||
|
|
|
@ -457,6 +457,69 @@ module ActionView
|
|||
output.safe_concat("</fieldset>")
|
||||
end
|
||||
|
||||
# Creates a text field of type "search".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as text_field_tag.
|
||||
def search_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "search"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "tel".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as text_field_tag.
|
||||
def telephone_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "tel"))
|
||||
end
|
||||
alias phone_field_tag telephone_field_tag
|
||||
|
||||
# Creates a text field of type "url".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as text_field_tag.
|
||||
def url_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "url"))
|
||||
end
|
||||
|
||||
# Creates a text field of type "email".
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as text_field_tag.
|
||||
def email_field_tag(name, value = nil, options = {})
|
||||
text_field_tag(name, value, options.stringify_keys.update("type" => "email"))
|
||||
end
|
||||
|
||||
# Creates a number field.
|
||||
#
|
||||
# ==== Options
|
||||
# * <tt>:min</tt> - The minimum acceptable value.
|
||||
# * <tt>:max</tt> - The maximum acceptable value.
|
||||
# * <tt>:in</tt> - A range specifying the <tt>:min</tt> and
|
||||
# <tt>:max</tt> values.
|
||||
# * <tt>:step</tt> - The acceptable value granularity.
|
||||
# * Otherwise accepts the same options as text_field_tag.
|
||||
#
|
||||
# ==== Examples
|
||||
# number_field_tag 'quantity', nil, :in => 1...10
|
||||
# => <input id="quantity" name="quantity" min="1" max="9" />
|
||||
def number_field_tag(name, value = nil, options = {})
|
||||
options = options.stringify_keys
|
||||
options["type"] ||= "number"
|
||||
if range = options.delete("in") || options.delete("within")
|
||||
options.update("min" => range.min, "max" => range.max)
|
||||
end
|
||||
text_field_tag(name, value, options)
|
||||
end
|
||||
|
||||
# Creates a range form element.
|
||||
#
|
||||
# ==== Options
|
||||
# * Accepts the same options as number_field_tag.
|
||||
def range_field_tag(name, value = nil, options = {})
|
||||
number_field_tag(name, value, options.stringify_keys.update("type" => "range"))
|
||||
end
|
||||
|
||||
private
|
||||
def html_options_for_form(url_for_options, options, *parameters_for_url)
|
||||
returning options.stringify_keys do |html_options|
|
||||
|
|
|
@ -2,21 +2,21 @@ require 'abstract_unit'
|
|||
|
||||
module AbstractController
|
||||
module Testing
|
||||
|
||||
|
||||
# Test basic dispatching.
|
||||
# ====
|
||||
# * Call process
|
||||
# * Test that the response_body is set correctly
|
||||
class SimpleController < AbstractController::Base
|
||||
end
|
||||
|
||||
|
||||
class Me < SimpleController
|
||||
def index
|
||||
self.response_body = "Hello world"
|
||||
"Something else"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestBasic < ActiveSupport::TestCase
|
||||
test "dispatching works" do
|
||||
controller = Me.new
|
||||
|
@ -24,7 +24,7 @@ module AbstractController
|
|||
assert_equal "Hello world", controller.response_body
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Test Render mixin
|
||||
# ====
|
||||
class RenderingController < AbstractController::Base
|
||||
|
@ -36,24 +36,28 @@ module AbstractController
|
|||
if options.is_a?(String)
|
||||
options = {:_template_name => options}
|
||||
end
|
||||
|
||||
|
||||
options[:_prefix] = _prefix
|
||||
super
|
||||
end
|
||||
|
||||
append_view_path File.expand_path(File.join(File.dirname(__FILE__), "views"))
|
||||
end
|
||||
|
||||
|
||||
class Me2 < RenderingController
|
||||
def index
|
||||
render "index.erb"
|
||||
end
|
||||
|
||||
|
||||
def index_to_string
|
||||
self.response_body = render_to_string "index.erb"
|
||||
end
|
||||
|
||||
def action_with_ivars
|
||||
@my_ivar = "Hello"
|
||||
render "action_with_ivars.erb"
|
||||
end
|
||||
|
||||
|
||||
def naked_render
|
||||
render
|
||||
end
|
||||
|
@ -76,12 +80,17 @@ module AbstractController
|
|||
@controller.process(:index)
|
||||
assert_equal "Hello from index.erb", @controller.response_body
|
||||
end
|
||||
|
||||
|
||||
test "render_to_string works with a String as an argument" do
|
||||
@controller.process(:index_to_string)
|
||||
assert_equal "Hello from index.erb", @controller.response_body
|
||||
end
|
||||
|
||||
test "rendering passes ivars to the view" do
|
||||
@controller.process(:action_with_ivars)
|
||||
assert_equal "Hello from index_with_ivars.erb", @controller.response_body
|
||||
end
|
||||
|
||||
|
||||
test "rendering with no template name" do
|
||||
@controller.process(:naked_render)
|
||||
assert_equal "Hello from naked_render.erb", @controller.response_body
|
||||
|
@ -97,7 +106,7 @@ module AbstractController
|
|||
assert_equal "Hello from naked_render.erb", @controller.response_body
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Test rendering with prefixes
|
||||
# ====
|
||||
# * self._prefix is used when defined
|
||||
|
@ -106,23 +115,23 @@ module AbstractController
|
|||
def self.prefix
|
||||
name.underscore
|
||||
end
|
||||
|
||||
|
||||
def _prefix
|
||||
self.class.prefix
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Me3 < PrefixedViews
|
||||
def index
|
||||
render
|
||||
end
|
||||
|
||||
|
||||
def formatted
|
||||
self.formats = [:html]
|
||||
render
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestPrefixedViews < ActiveSupport::TestCase
|
||||
def setup
|
||||
@controller = Me3.new
|
||||
|
@ -138,13 +147,13 @@ module AbstractController
|
|||
assert_equal "Hello from me3/formatted.html.erb", @controller.response_body
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Test rendering with layouts
|
||||
# ====
|
||||
# self._layout is used when defined
|
||||
class WithLayouts < PrefixedViews
|
||||
include Layouts
|
||||
|
||||
|
||||
private
|
||||
def self.layout(formats)
|
||||
begin
|
||||
|
@ -160,21 +169,21 @@ module AbstractController
|
|||
def render_to_body(options = {})
|
||||
options[:_layout] = options[:layout] || _default_layout({})
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Me4 < WithLayouts
|
||||
def index
|
||||
render
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class Me5 < WithLayouts
|
||||
def index
|
||||
render
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestLayouts < ActiveSupport::TestCase
|
||||
test "layouts are included" do
|
||||
controller = Me4.new
|
||||
|
@ -182,7 +191,7 @@ module AbstractController
|
|||
assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", controller.response_body
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# respond_to_action?(action_name)
|
||||
# ====
|
||||
# * A method can be used as an action only if this method
|
||||
|
@ -191,7 +200,7 @@ module AbstractController
|
|||
class DefaultRespondToActionController < AbstractController::Base
|
||||
def index() self.response_body = "success" end
|
||||
end
|
||||
|
||||
|
||||
class ActionMissingRespondToActionController < AbstractController::Base
|
||||
# No actions
|
||||
private
|
||||
|
@ -199,19 +208,19 @@ module AbstractController
|
|||
self.response_body = "success"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class RespondToActionController < AbstractController::Base;
|
||||
def index() self.response_body = "success" end
|
||||
|
||||
|
||||
def fail() self.response_body = "fail" end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def method_for_action(action_name)
|
||||
action_name.to_s != "fail" && action_name
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
class TestRespondToAction < ActiveSupport::TestCase
|
||||
|
||||
def assert_dispatch(klass, body = "success", action = :index)
|
||||
|
@ -219,27 +228,27 @@ module AbstractController
|
|||
controller.process(action)
|
||||
assert_equal body, controller.response_body
|
||||
end
|
||||
|
||||
|
||||
test "an arbitrary method is available as an action by default" do
|
||||
assert_dispatch DefaultRespondToActionController, "success", :index
|
||||
end
|
||||
|
||||
|
||||
test "raises ActionNotFound when method does not exist and action_missing is not defined" do
|
||||
assert_raise(ActionNotFound) { DefaultRespondToActionController.new.process(:fail) }
|
||||
end
|
||||
|
||||
|
||||
test "dispatches to action_missing when method does not exist and action_missing is defined" do
|
||||
assert_dispatch ActionMissingRespondToActionController, "success", :ohai
|
||||
end
|
||||
|
||||
|
||||
test "a method is available as an action if respond_to_action? returns true" do
|
||||
assert_dispatch RespondToActionController, "success", :index
|
||||
end
|
||||
|
||||
|
||||
test "raises ActionNotFound if method is defined but respond_to_action? returns false" do
|
||||
assert_raise(ActionNotFound) { RespondToActionController.new.process(:fail) }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -192,10 +192,6 @@ end
|
|||
|
||||
# Temporary base class
|
||||
class Rack::TestCase < ActionController::IntegrationTest
|
||||
setup do
|
||||
ActionController::Base.config.secret = "abc" * 30
|
||||
end
|
||||
|
||||
def self.testing(klass = nil)
|
||||
if klass
|
||||
@testing = "/#{klass.name.underscore}".sub!(/_controller$/, '')
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
require 'abstract_unit'
|
||||
|
||||
ActionController::Base.config.secret = "thisISverySECRET123"
|
||||
|
||||
class CookieTest < ActionController::TestCase
|
||||
class TestController < ActionController::Base
|
||||
def authenticate
|
||||
|
@ -76,6 +74,7 @@ class CookieTest < ActionController::TestCase
|
|||
|
||||
def setup
|
||||
super
|
||||
@request.env["action_dispatch.secret_token"] = "thisISverySECRET123"
|
||||
@request.host = "www.nextangle.com"
|
||||
end
|
||||
|
||||
|
|
|
@ -41,8 +41,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
|
|||
setup do
|
||||
# Used as secret in generating nonce to prevent tampering of timestamp
|
||||
@secret = "session_options_secret"
|
||||
@controller.config.secret = @secret
|
||||
# @old_secret, ActionController::Base.config.secret[:secret] = ActionController::Base.session_options[:secret], @secret
|
||||
@request.env["action_dispatch.secret_token"] = @secret
|
||||
end
|
||||
|
||||
teardown do
|
||||
|
@ -206,7 +205,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase
|
|||
|
||||
test "validate_digest_response should fail with nil returning password_procedure" do
|
||||
@request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil)
|
||||
assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@secret, @request, "SuperSecret"){nil}
|
||||
assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil}
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -245,6 +245,15 @@ class IntegrationProcessTest < ActionController::IntegrationTest
|
|||
render :text => "Gone", :status => 410
|
||||
end
|
||||
|
||||
def set_cookie
|
||||
cookies["foo"] = 'bar'
|
||||
head :ok
|
||||
end
|
||||
|
||||
def get_cookie
|
||||
render :text => cookies["foo"]
|
||||
end
|
||||
|
||||
def redirect
|
||||
redirect_to :action => "get"
|
||||
end
|
||||
|
@ -292,6 +301,42 @@ class IntegrationProcessTest < ActionController::IntegrationTest
|
|||
end
|
||||
end
|
||||
|
||||
test 'cookie persist to next request' do
|
||||
with_test_route_set do
|
||||
get '/set_cookie'
|
||||
assert_response :success
|
||||
|
||||
assert_equal "foo=bar; path=/", headers["Set-Cookie"]
|
||||
assert_equal({"foo"=>"bar"}, cookies.to_hash)
|
||||
|
||||
get '/get_cookie'
|
||||
assert_response :success
|
||||
assert_equal "bar", body
|
||||
|
||||
assert_equal nil, headers["Set-Cookie"]
|
||||
assert_equal({"foo"=>"bar"}, cookies.to_hash)
|
||||
end
|
||||
end
|
||||
|
||||
test 'cookie persist to next request on another domain' do
|
||||
with_test_route_set do
|
||||
host! "37s.backpack.test"
|
||||
|
||||
get '/set_cookie'
|
||||
assert_response :success
|
||||
|
||||
assert_equal "foo=bar; path=/", headers["Set-Cookie"]
|
||||
assert_equal({"foo"=>"bar"}, cookies.to_hash)
|
||||
|
||||
get '/get_cookie'
|
||||
assert_response :success
|
||||
assert_equal "bar", body
|
||||
|
||||
assert_equal nil, headers["Set-Cookie"]
|
||||
assert_equal({"foo"=>"bar"}, cookies.to_hash)
|
||||
end
|
||||
end
|
||||
|
||||
def test_redirect
|
||||
with_test_route_set do
|
||||
get '/redirect'
|
||||
|
|
|
@ -8,4 +8,4 @@ module ERBTest
|
|||
assert_equal "<form action=\"/blah/update\" method=\"post\"></form>", output
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -349,6 +349,36 @@ class FormHelperTest < ActionView::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_search_field
|
||||
expected = %{<input id="contact_notes_query" size="30" name="contact[notes_query]" type="search" />}
|
||||
assert_dom_equal(expected, search_field("contact", "notes_query"))
|
||||
end
|
||||
|
||||
def test_telephone_field
|
||||
expected = %{<input id="user_cell" size="30" name="user[cell]" type="tel" />}
|
||||
assert_dom_equal(expected, telephone_field("user", "cell"))
|
||||
end
|
||||
|
||||
def test_url_field
|
||||
expected = %{<input id="user_homepage" size="30" name="user[homepage]" type="url" />}
|
||||
assert_dom_equal(expected, url_field("user", "homepage"))
|
||||
end
|
||||
|
||||
def test_email_field
|
||||
expected = %{<input id="user_address" size="30" name="user[address]" type="email" />}
|
||||
assert_dom_equal(expected, email_field("user", "address"))
|
||||
end
|
||||
|
||||
def test_number_field
|
||||
expected = %{<input name="order[quantity]" size="30" max="9" id="order_quantity" type="number" min="1" />}
|
||||
assert_dom_equal(expected, number_field("order", "quantity", :in => 1...10))
|
||||
end
|
||||
|
||||
def test_range_input
|
||||
expected = %{<input name="hifi[volume]" step="0.1" size="30" max="11" id="hifi_volume" type="range" min="0" />}
|
||||
assert_dom_equal(expected, range_field("hifi", "volume", :in => 0..11, :step => 0.1))
|
||||
end
|
||||
|
||||
def test_explicit_name
|
||||
assert_dom_equal(
|
||||
'<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
|
||||
|
@ -416,12 +446,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
concat f.submit('Create post')
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
concat f.submit('Create post')
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -437,11 +469,35 @@ class FormHelperTest < ActionView::TestCase
|
|||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_method
|
||||
form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
|
||||
def test_form_for_with_symbol_object_name
|
||||
form_for(@post, :as => "other_name", :html => { :id => 'create-post' }) do |f|
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
concat f.submit('Create post')
|
||||
end
|
||||
|
||||
expected =
|
||||
"<form class='other_name_edit' method='post' action='/posts/123' id='create-post'>" +
|
||||
"<div style='margin:0;padding:0;display:inline'><input name='_method' value='put' type='hidden' /></div>" +
|
||||
"<label for='other_name_title'>Title</label>" +
|
||||
"<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" +
|
||||
"<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||
"<input name='other_name[secret]' value='0' type='hidden' />" +
|
||||
"<input name='other_name[secret]' checked='checked' id='other_name_secret' value='1' type='checkbox' />" +
|
||||
"<input name='commit' id='other_name_submit' value='Create post' type='submit' /></form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_method
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -457,10 +513,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_remote
|
||||
form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -494,16 +552,18 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_index
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
assert_deprecated do
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.label(:title)
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
"<form action='http://www.example.com' method='post'>" +
|
||||
"<label for=\"post_123_title\">Title</label>" +
|
||||
"<label for='post_123_title'>Title</label>" +
|
||||
"<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
|
||||
"<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
|
||||
"<input name='post[123][secret]' type='hidden' value='0' />" +
|
||||
|
@ -514,10 +574,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_nil_index_option_override
|
||||
form_for("post[]", @post, :index => nil) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
assert_deprecated do
|
||||
form_for("post[]", @post, :index => nil) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -535,8 +597,10 @@ class FormHelperTest < ActionView::TestCase
|
|||
old_locale, I18n.locale = I18n.locale, :submit
|
||||
|
||||
@post.persisted = false
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.submit
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.submit
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -550,8 +614,10 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_submit_with_object_as_existing_record_and_locale_strings
|
||||
old_locale, I18n.locale = I18n.locale, :submit
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.submit
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.submit
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -580,8 +646,10 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_submit_with_object_and_nested_lookup
|
||||
old_locale, I18n.locale = I18n.locale, :submit
|
||||
|
||||
form_for(:another_post, @post) do |f|
|
||||
concat f.submit
|
||||
assert_deprecated do
|
||||
form_for(:another_post, @post) do |f|
|
||||
concat f.submit
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -593,10 +661,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -607,11 +677,13 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_nested_collections
|
||||
form_for('post[]', @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for('comment[]', @comment) { |c|
|
||||
concat c.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for('post[]', @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for('comment[]', @comment) { |c|
|
||||
concat c.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -623,11 +695,13 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_index_and_parent_fields
|
||||
form_for('post', @post, :index => 1) do |c|
|
||||
concat c.text_field(:title)
|
||||
concat c.fields_for('comment', @comment, :index => 1) { |r|
|
||||
concat r.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for('post', @post, :index => 1) do |c|
|
||||
concat c.text_field(:title)
|
||||
concat c.fields_for('comment', @comment, :index => 1) { |r|
|
||||
concat r.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -639,10 +713,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_index_and_nested_fields_for
|
||||
output_buffer = form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
output_buffer = form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -653,10 +729,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_index_on_both
|
||||
form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -667,10 +745,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_auto_index
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.fields_for(:comment, @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -681,10 +761,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_index_radio_button
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.radio_button(:title, "hello")
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.radio_button(:title, "hello")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -695,10 +777,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_auto_index_on_both
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.fields_for("comment[]", @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for("post[]", @post) do |f|
|
||||
concat f.fields_for("comment[]", @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
|
@ -709,36 +793,40 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_index_and_auto_index
|
||||
output_buffer = form_for("post[]", @post) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
assert_deprecated do
|
||||
output_buffer = form_for("post[]", @post) do |f|
|
||||
concat f.fields_for(:comment, @post, :index => 5) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
|
||||
output_buffer << form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for("comment[]", @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
|
||||
"</form>" +
|
||||
"<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
output_buffer << form_for(:post, @post, :index => 1) do |f|
|
||||
concat f.fields_for("comment[]", @post) { |c|
|
||||
concat c.text_field(:title)
|
||||
}
|
||||
end
|
||||
|
||||
expected = "<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
|
||||
"</form>" +
|
||||
"<form action='http://www.example.com' method='post'>" +
|
||||
"<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
|
||||
"</form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
|
||||
@post.author = Author.new
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -750,10 +838,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
|
||||
form_for(:post, @post) do |f|
|
||||
f.fields_for(:author, Author.new(123)) do |af|
|
||||
assert_not_nil af.object
|
||||
assert_equal 123, af.object.id
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
f.fields_for(:author, Author.new(123)) do |af|
|
||||
assert_not_nil af.object
|
||||
assert_equal 123, af.object.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -761,11 +851,13 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
|
||||
@post.author = Author.new(321)
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -780,12 +872,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
|
||||
@post.author = Author.new(321)
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.hidden_field(:id)
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:author) { |af|
|
||||
concat af.hidden_field(:id)
|
||||
concat af.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -800,12 +894,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
|
||||
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -823,13 +919,15 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
|
||||
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.hidden_field(:id)
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.hidden_field(:id)
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -847,12 +945,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
|
||||
@post.comments = [Comment.new, Comment.new]
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -868,12 +968,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
|
||||
@post.comments = [Comment.new(321), Comment.new]
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
@post.comments.each do |comment|
|
||||
concat f.fields_for(:comments, comment) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -888,10 +990,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_nested_fields_for_with_an_empty_supplied_attributes_collection
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
f.fields_for(:comments, []) do |cf|
|
||||
concat cf.text_field(:name)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
f.fields_for(:comments, []) do |cf|
|
||||
concat cf.text_field(:name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -905,11 +1009,13 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
|
||||
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments, @post.comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments, @post.comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -927,11 +1033,13 @@ class FormHelperTest < ActionView::TestCase
|
|||
comments = Array.new(2) { |id| Comment.new(id + 1) }
|
||||
@post.comments = []
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments, comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments, comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -949,12 +1057,14 @@ class FormHelperTest < ActionView::TestCase
|
|||
@post.comments = [Comment.new(321), Comment.new]
|
||||
yielded_comments = []
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
yielded_comments << cf.object
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.fields_for(:comments) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
yielded_comments << cf.object
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -971,10 +1081,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
|
||||
@post.comments = []
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
|
||||
concat cf.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -991,25 +1103,28 @@ class FormHelperTest < ActionView::TestCase
|
|||
@post.comments[0].relevances = []
|
||||
@post.tags[0].relevances = []
|
||||
@post.tags[1].relevances = []
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comments, @post.comments[0]) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
|
||||
concat crf.text_field(:value)
|
||||
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.fields_for(:comments, @post.comments[0]) { |cf|
|
||||
concat cf.text_field(:name)
|
||||
concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
|
||||
concat crf.text_field(:value)
|
||||
}
|
||||
}
|
||||
}
|
||||
concat f.fields_for(:tags, @post.tags[0]) { |tf|
|
||||
concat tf.text_field(:value)
|
||||
concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
|
||||
concat trf.text_field(:value)
|
||||
concat f.fields_for(:tags, @post.tags[0]) { |tf|
|
||||
concat tf.text_field(:value)
|
||||
concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
|
||||
concat trf.text_field(:value)
|
||||
}
|
||||
}
|
||||
}
|
||||
concat f.fields_for('tags', @post.tags[1]) { |tf|
|
||||
concat tf.text_field(:value)
|
||||
concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
|
||||
concat trf.text_field(:value)
|
||||
concat f.fields_for('tags', @post.tags[1]) { |tf|
|
||||
concat tf.text_field(:value)
|
||||
concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
|
||||
concat trf.text_field(:value)
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected = '<form action="http://www.example.com" method="post">' +
|
||||
|
@ -1153,13 +1268,15 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_and_fields_for
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
|
||||
concat fields_for(:parent_post, @post) { |parent_fields|
|
||||
concat parent_fields.check_box(:secret)
|
||||
}
|
||||
concat fields_for(:parent_post, @post) { |parent_fields|
|
||||
concat parent_fields.check_box(:secret)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -1174,13 +1291,15 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_and_fields_for_with_object
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
|
||||
concat post_form.text_field(:title)
|
||||
concat post_form.text_area(:body)
|
||||
|
||||
concat post_form.fields_for(@comment) { |comment_fields|
|
||||
concat comment_fields.text_field(:name)
|
||||
}
|
||||
concat post_form.fields_for(@comment) { |comment_fields|
|
||||
concat comment_fields.text_field(:name)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -1205,10 +1324,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_labelled_builder
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -1225,10 +1346,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
old_default_form_builder, ActionView::Base.default_form_builder =
|
||||
ActionView::Base.default_form_builder, LabelledFormBuilder
|
||||
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.text_field(:title)
|
||||
concat f.text_area(:body)
|
||||
concat f.check_box(:secret)
|
||||
end
|
||||
end
|
||||
|
||||
expected =
|
||||
|
@ -1244,9 +1367,11 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_default_form_builder_with_active_record_helpers
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
assert_deprecated do
|
||||
form_for(:post, @post) do |f|
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
end
|
||||
end
|
||||
|
||||
expected = %(<form action='http://www.example.com' method='post'>) +
|
||||
|
@ -1262,9 +1387,11 @@ class FormHelperTest < ActionView::TestCase
|
|||
post = @post
|
||||
@post = nil
|
||||
|
||||
form_for(:post, post) do |f|
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
assert_deprecated do
|
||||
form_for(:post, post) do |f|
|
||||
concat f.error_message_on('author_name')
|
||||
concat f.error_messages
|
||||
end
|
||||
end
|
||||
|
||||
expected = %(<form action='http://www.example.com' method='post'>) +
|
||||
|
@ -1294,10 +1421,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
|
||||
klass = nil
|
||||
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new) do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new) do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1307,10 +1436,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
|
||||
klass = nil
|
||||
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1322,10 +1453,12 @@ class FormHelperTest < ActionView::TestCase
|
|||
def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
|
||||
klass = nil
|
||||
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
|
||||
f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
|
||||
klass = nested_fields.class
|
||||
''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1333,27 +1466,35 @@ class FormHelperTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
def test_form_for_with_html_options_adds_options_to_form_tag
|
||||
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
|
||||
end
|
||||
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
|
||||
|
||||
assert_dom_equal expected, output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_string_url_option
|
||||
form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
|
||||
end
|
||||
|
||||
assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
|
||||
end
|
||||
|
||||
def test_form_for_with_hash_url_option
|
||||
form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
|
||||
end
|
||||
|
||||
assert_equal 'controller', @url_for_options[:controller]
|
||||
assert_equal 'action', @url_for_options[:action]
|
||||
end
|
||||
|
||||
def test_form_for_with_record_url_option
|
||||
form_for(:post, @post, :url => @post) do |f| end
|
||||
assert_deprecated do
|
||||
form_for(:post, @post, :url => @post) do |f| end
|
||||
end
|
||||
|
||||
expected = "<form action=\"/posts/123\" method=\"post\"></form>"
|
||||
assert_equal expected, output_buffer
|
||||
|
|
|
@ -335,6 +335,36 @@ class FormTagHelperTest < ActionView::TestCase
|
|||
)
|
||||
end
|
||||
|
||||
def test_search_field_tag
|
||||
expected = %{<input id="query" name="query" type="search" />}
|
||||
assert_dom_equal(expected, search_field_tag("query"))
|
||||
end
|
||||
|
||||
def telephone_field_tag
|
||||
expected = %{<input id="cell" name="cell" type="tel" />}
|
||||
assert_dom_equal(expected, telephone_field_tag("cell"))
|
||||
end
|
||||
|
||||
def test_url_field_tag
|
||||
expected = %{<input id="homepage" name="homepage" type="url" />}
|
||||
assert_dom_equal(expected, url_field_tag("homepage"))
|
||||
end
|
||||
|
||||
def test_email_field_tag
|
||||
expected = %{<input id="address" name="address" type="email" />}
|
||||
assert_dom_equal(expected, email_field_tag("address"))
|
||||
end
|
||||
|
||||
def test_number_field_tag
|
||||
expected = %{<input name="quantity" max="9" id="quantity" type="number" min="1" />}
|
||||
assert_dom_equal(expected, number_field_tag("quantity", nil, :in => 1...10))
|
||||
end
|
||||
|
||||
def test_range_input_tag
|
||||
expected = %{<input name="volume" step="0.1" max="11" id="volume" type="range" min="0" />}
|
||||
assert_dom_equal(expected, range_field_tag("volume", nil, :in => 0..11, :step => 0.1))
|
||||
end
|
||||
|
||||
def test_pass
|
||||
assert_equal 1, 1
|
||||
end
|
||||
|
|
|
@ -405,6 +405,9 @@ module ActiveRecord
|
|||
else
|
||||
super
|
||||
end
|
||||
elsif @reflection.klass.scopes[method]
|
||||
@_scopes ||= {}
|
||||
@_scopes[method] ||= with_scope(construct_scope) { @reflection.klass.send(method, *args) }
|
||||
else
|
||||
with_scope(construct_scope) do
|
||||
if block_given?
|
||||
|
|
|
@ -11,7 +11,7 @@ require 'active_support/core_ext/hash/deep_merge'
|
|||
require 'active_support/core_ext/hash/indifferent_access'
|
||||
require 'active_support/core_ext/hash/slice'
|
||||
require 'active_support/core_ext/string/behavior'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/object/duplicable'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
|
|
|
@ -291,7 +291,7 @@ module ActiveRecord
|
|||
# Remove the index named by_branch_party in the accounts table.
|
||||
# remove_index :accounts, :name => :by_branch_party
|
||||
def remove_index(table_name, options = {})
|
||||
execute "DROP INDEX #{quote_column_name(index_name(table_name, options))} ON #{table_name}"
|
||||
execute "DROP INDEX #{quote_column_name(index_name(table_name, options))} ON #{quote_table_name(table_name)}"
|
||||
end
|
||||
|
||||
def index_name(table_name, options) #:nodoc:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
|
||||
module ActiveRecord
|
||||
# Exception that can be raised to stop migrations from going backwards.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'active_support/core_ext/array'
|
||||
require 'active_support/core_ext/hash/except'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
|
||||
module ActiveRecord
|
||||
|
|
|
@ -413,6 +413,15 @@ class NamedScopeTest < ActiveRecord::TestCase
|
|||
Topic.approved.by_lifo.replied.written_before(Time.now).all
|
||||
end
|
||||
end
|
||||
|
||||
def test_named_scopes_are_cached_on_associations
|
||||
post = posts(:welcome)
|
||||
|
||||
assert_equal post.comments.containing_the_letter_e.object_id, post.comments.containing_the_letter_e.object_id
|
||||
|
||||
post.comments.containing_the_letter_e.all # force load
|
||||
assert_no_queries { post.comments.containing_the_letter_e.all }
|
||||
end
|
||||
end
|
||||
|
||||
class DynamicScopeMatchTest < ActiveRecord::TestCase
|
||||
|
|
|
@ -251,6 +251,9 @@ module ActiveResource
|
|||
# The logger for diagnosing and tracing Active Resource calls.
|
||||
cattr_accessor :logger
|
||||
|
||||
# Controls the top-level behavior of JSON serialization
|
||||
cattr_accessor :include_root_in_json, :instance_writer => false
|
||||
|
||||
class << self
|
||||
# Creates a schema for this resource - setting the attributes that are
|
||||
# known prior to fetching an instance from the remote system.
|
||||
|
@ -1240,6 +1243,12 @@ module ActiveResource
|
|||
case self.class.format
|
||||
when ActiveResource::Formats::XmlFormat
|
||||
self.class.format.encode(attributes, {:root => self.class.element_name}.merge(options))
|
||||
when ActiveResource::Formats::JsonFormat
|
||||
if ActiveResource::Base.include_root_in_json
|
||||
self.class.format.encode({self.class.element_name => attributes}, options)
|
||||
else
|
||||
self.class.format.encode(attributes, options)
|
||||
end
|
||||
else
|
||||
self.class.format.encode(attributes, options)
|
||||
end
|
||||
|
|
|
@ -4,20 +4,22 @@ require "fixtures/customer"
|
|||
require "fixtures/street_address"
|
||||
require "fixtures/beast"
|
||||
require "fixtures/proxy"
|
||||
require 'active_support/json'
|
||||
require 'active_support/core_ext/hash/conversions'
|
||||
require 'mocha'
|
||||
|
||||
class BaseTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
||||
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
|
||||
@greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
|
||||
@addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
|
||||
@default_request_headers = { 'Content-Type' => 'application/xml' }
|
||||
@rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
|
||||
@matz = { :id => 1, :name => 'Matz' }.to_xml(:root => 'person')
|
||||
@david = { :id => 2, :name => 'David' }.to_xml(:root => 'person')
|
||||
@greg = { :id => 3, :name => 'Greg' }.to_xml(:root => 'person')
|
||||
@addy = { :id => 1, :street => '12345 Street', :country => 'Australia' }.to_xml(:root => 'address')
|
||||
@rick = { :name => "Rick", :age => 25 }.to_xml(:root => "person")
|
||||
@joe = { 'person' => { :id => 6, :name => 'Joe' }}.to_json
|
||||
@people = [{ :id => 1, :name => 'Matz' }, { :id => 2, :name => 'David' }].to_xml(:root => 'people')
|
||||
@people_david = [{ :id => 2, :name => 'David' }].to_xml(:root => 'people')
|
||||
@addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')
|
||||
@addresses = [{ :id => 1, :street => '12345 Street', :country => 'Australia' }].to_xml(:root => 'addresses')
|
||||
|
||||
# - deep nested resource -
|
||||
# - Luis (Customer)
|
||||
|
@ -66,6 +68,7 @@ class BaseTest < Test::Unit::TestCase
|
|||
ActiveResource::HttpMock.respond_to do |mock|
|
||||
mock.get "/people/1.xml", {}, @matz
|
||||
mock.get "/people/2.xml", {}, @david
|
||||
mock.get "/people/6.json", {}, @joe
|
||||
mock.get "/people/5.xml", {}, @marty
|
||||
mock.get "/people/Greg.xml", {}, @greg
|
||||
mock.get "/people/4.xml", {'key' => 'value'}, nil, 404
|
||||
|
@ -1012,6 +1015,16 @@ class BaseTest < Test::Unit::TestCase
|
|||
assert xml.include?('<id type="integer">1</id>')
|
||||
end
|
||||
|
||||
|
||||
def test_to_json_including_root
|
||||
Person.include_root_in_json = true
|
||||
Person.format = :json
|
||||
joe = Person.find(6)
|
||||
json = joe.encode
|
||||
Person.format = :xml
|
||||
assert_equal json, '{"person":{"person":{"name":"Joe","id":6}}}'
|
||||
end
|
||||
|
||||
def test_to_param_quacks_like_active_record
|
||||
new_person = Person.new
|
||||
assert_nil new_person.to_param
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require 'active_support/core_ext/array/wrap'
|
||||
require 'active_support/core_ext/class/inheritable_attributes'
|
||||
require 'active_support/core_ext/kernel/reporting'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
|
||||
module ActiveSupport
|
||||
# Callbacks are hooks into the lifecycle of an object that allow you to trigger logic
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/module/delegation'
|
||||
require 'active_support/core_ext/module/remove_method'
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/array/extract_options'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/module/remove_method'
|
||||
|
||||
class Class
|
||||
|
|
|
@ -2,3 +2,4 @@ require 'active_support/core_ext/kernel/reporting'
|
|||
require 'active_support/core_ext/kernel/agnostics'
|
||||
require 'active_support/core_ext/kernel/requires'
|
||||
require 'active_support/core_ext/kernel/debugger'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
class Object
|
||||
module Kernel
|
||||
# Returns the object's singleton class.
|
||||
def singleton_class
|
||||
class << self
|
||||
self
|
||||
end
|
||||
end unless respond_to?(:singleton_class)
|
||||
end unless respond_to?(:singleton_class) # exists in 1.9.2
|
||||
|
||||
# class_eval on an object acts like singleton_class_eval.
|
||||
# class_eval on an object acts like singleton_class.class_eval.
|
||||
def class_eval(*args, &block)
|
||||
singleton_class.class_eval(*args, &block)
|
||||
end
|
|
@ -5,7 +5,6 @@ require 'active_support/core_ext/object/try'
|
|||
|
||||
require 'active_support/core_ext/object/conversions'
|
||||
require 'active_support/core_ext/object/instance_variables'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/object/misc'
|
||||
require 'active_support/core_ext/object/extending'
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require 'erb'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
|
||||
class ERB
|
||||
module Util
|
||||
|
|
|
@ -51,6 +51,6 @@ module ActiveSupport
|
|||
inflect.irregular('move', 'moves')
|
||||
inflect.irregular('cow', 'kine')
|
||||
|
||||
inflect.uncountable(%w(equipment information rice money species series fish sheep))
|
||||
inflect.uncountable(%w(equipment information rice money species series fish sheep jeans))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -148,7 +148,7 @@ module ActiveSupport
|
|||
def singularize(word)
|
||||
result = word.to_s.dup
|
||||
|
||||
if inflections.uncountables.include?(result.downcase)
|
||||
if inflections.uncountables.any? { |inflection| result =~ /#{inflection}\Z/i }
|
||||
result
|
||||
else
|
||||
inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/module/aliasing'
|
||||
|
||||
module ActiveSupport
|
||||
|
|
|
@ -41,6 +41,17 @@ class KernelTest < Test::Unit::TestCase
|
|||
def test_silence_stderr_with_return_value
|
||||
assert_equal 1, silence_stderr { 1 }
|
||||
end
|
||||
|
||||
def test_singleton_class
|
||||
o = Object.new
|
||||
assert_equal class << o; self end, o.singleton_class
|
||||
end
|
||||
|
||||
def test_class_eval
|
||||
o = Object.new
|
||||
class << o; @x = 1; end
|
||||
assert_equal 1, o.class_eval { @x }
|
||||
end
|
||||
end
|
||||
|
||||
class KernelSupressTest < Test::Unit::TestCase
|
||||
|
|
|
@ -118,11 +118,6 @@ class ObjectTests < ActiveSupport::TestCase
|
|||
assert duck.acts_like?(:time)
|
||||
assert !duck.acts_like?(:date)
|
||||
end
|
||||
|
||||
def test_singleton_class
|
||||
o = Object.new
|
||||
assert_equal class << o; self end, o.singleton_class
|
||||
end
|
||||
end
|
||||
|
||||
class ObjectInstanceVariableTest < Test::Unit::TestCase
|
||||
|
|
|
@ -12,6 +12,8 @@ module InflectorTestCases
|
|||
"stack" => "stacks",
|
||||
"wish" => "wishes",
|
||||
"fish" => "fish",
|
||||
"jeans" => "jeans",
|
||||
"funky jeans" => "funky jeans",
|
||||
|
||||
"category" => "categories",
|
||||
"query" => "queries",
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
* A new application now comes with a layout and a stylesheet. [JV]
|
||||
|
||||
* Renamed config.cookie_secret to config.secret_token and pass it as env key. [JV]
|
||||
|
||||
*Rails 3.0.0 [beta 2] (April 1st, 2010)*
|
||||
|
||||
* Session store configuration has changed [YK & CL]
|
||||
|
@ -6,12 +10,11 @@
|
|||
config.cookie_secret = "fdsfhisdghfidugnfdlg"
|
||||
|
||||
* railtie_name and engine_name are deprecated. You can now add any object to
|
||||
the configuration object: config.your_plugin = {} [JK]
|
||||
the configuration object: config.your_plugin = {} [JV]
|
||||
|
||||
* Added config.generators.templates to provide alternative paths for the generators
|
||||
to look for templates [JV]
|
||||
|
||||
|
||||
*Rails 3.0.0 [beta 1] (February 4, 2010)*
|
||||
|
||||
* Added "rake about" as a replacement for script/about [DHH]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require 'active_support/core_ext/hash/reverse_merge'
|
||||
require 'fileutils'
|
||||
require 'rails/plugin'
|
||||
require 'rails/engine'
|
||||
|
@ -128,8 +129,14 @@ module Rails
|
|||
end
|
||||
|
||||
def call(env)
|
||||
env["action_dispatch.parameter_filter"] = config.filter_parameters
|
||||
app.call(env)
|
||||
app.call(env.reverse_merge!(env_defaults))
|
||||
end
|
||||
|
||||
def env_defaults
|
||||
@env_defaults ||= {
|
||||
"action_dispatch.parameter_filter" => config.filter_parameters,
|
||||
"action_dispatch.secret_token" => config.secret_token
|
||||
}
|
||||
end
|
||||
|
||||
def initializers
|
||||
|
|
|
@ -6,7 +6,7 @@ module Rails
|
|||
include ::Rails::Configuration::Deprecated
|
||||
|
||||
attr_accessor :allow_concurrency, :cache_classes, :cache_store,
|
||||
:cookie_secret, :consider_all_requests_local, :dependency_loading,
|
||||
:secret_token, :consider_all_requests_local, :dependency_loading,
|
||||
:filter_parameters, :log_level, :logger, :metals,
|
||||
:plugins, :preload_frameworks, :reload_engines, :reload_plugins,
|
||||
:serve_static_assets, :time_zone, :whiny_nils
|
||||
|
@ -37,6 +37,7 @@ module Rails
|
|||
paths.app.controllers << builtin_controller if builtin_controller
|
||||
paths.config.database "config/database.yml"
|
||||
paths.config.environment "config/environments", :glob => "#{Rails.env}.rb"
|
||||
paths.lib.templates "lib/templates"
|
||||
paths.log "log/#{Rails.env}.log"
|
||||
paths.tmp "tmp"
|
||||
paths.tmp.cache "tmp/cache"
|
||||
|
@ -123,7 +124,7 @@ module Rails
|
|||
|
||||
def session_options
|
||||
return @session_options unless @session_store == :cookie_store
|
||||
@session_options.merge(:secret => @cookie_secret)
|
||||
@session_options.merge(:secret => @secret_token)
|
||||
end
|
||||
|
||||
def default_middleware_stack
|
||||
|
|
|
@ -3,6 +3,10 @@ module Rails
|
|||
module Finisher
|
||||
include Initializable
|
||||
|
||||
initializer :add_generator_templates do
|
||||
config.generators.templates.unshift(*paths.lib.templates.to_a)
|
||||
end
|
||||
|
||||
initializer :ensure_load_once_paths_as_subset do
|
||||
extra = ActiveSupport::Dependencies.load_once_paths -
|
||||
ActiveSupport::Dependencies.load_paths
|
||||
|
|
|
@ -13,7 +13,7 @@ module Rails
|
|||
|
||||
add_gem_filters
|
||||
|
||||
add_silencer { |line| !APP_DIRS.any? { |dir| line =~ /^#{dir}/ } }
|
||||
add_silencer { |line| !APP_DIRS.any? { |dir| line =~ /^\/?#{dir}/ } }
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -104,6 +104,18 @@ module Rails
|
|||
"please do paths.app.controllers instead", caller
|
||||
paths.app.controllers.to_a.uniq
|
||||
end
|
||||
|
||||
def cookie_secret=(value)
|
||||
ActiveSupport::Deprecation.warn "config.cookie_secret= is deprecated, " <<
|
||||
"please use config.secret_token= instead", caller
|
||||
self.secret_token = value
|
||||
end
|
||||
|
||||
def cookie_secret
|
||||
ActiveSupport::Deprecation.warn "config.cookie_secret is deprecated, " <<
|
||||
"please use config.secret_token instead", caller
|
||||
self.secret_token
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,6 @@ module Rails
|
|||
# # lib/my_engine.rb
|
||||
# module MyEngine
|
||||
# class Engine < Rails::Engine
|
||||
# engine_name :my_engine
|
||||
# end
|
||||
# end
|
||||
#
|
||||
|
@ -38,11 +37,12 @@ module Rails
|
|||
# Example:
|
||||
#
|
||||
# class MyEngine < Rails::Engine
|
||||
# # config.middleware is shared configururation
|
||||
# config.middleware.use MyEngine::Middleware
|
||||
#
|
||||
# # Add a load path for this specific Engine
|
||||
# config.load_paths << File.expand_path("../lib/some/path", __FILE__)
|
||||
#
|
||||
# initializer "my_engine.add_middleware" do |app|
|
||||
# app.middlewares.use MyEngine::Middleware
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# == Paths
|
||||
|
@ -193,17 +193,13 @@ module Rails
|
|||
app.metal_loader.paths.unshift(*paths.app.metals.to_a)
|
||||
end
|
||||
|
||||
initializer :add_generator_templates do |app|
|
||||
config.generators.templates.unshift(*paths.lib.templates.to_a)
|
||||
end
|
||||
|
||||
initializer :load_application_initializers do
|
||||
initializer :load_config_initializers do
|
||||
paths.config.initializers.to_a.sort.each do |initializer|
|
||||
load(initializer)
|
||||
end
|
||||
end
|
||||
|
||||
initializer :load_application_classes do |app|
|
||||
initializer :load_app_classes do |app|
|
||||
next if $rails_rake_task
|
||||
|
||||
if app.config.cache_classes
|
||||
|
|
|
@ -20,10 +20,9 @@ module Rails
|
|||
paths.app.models "app/models", :eager_load => true
|
||||
paths.app.mailers "app/mailers", :eager_load => true
|
||||
paths.app.metals "app/metal", :eager_load => true
|
||||
paths.app.views "app/views", :eager_load => true
|
||||
paths.app.views "app/views"
|
||||
paths.lib "lib", :load_path => true
|
||||
paths.lib.tasks "lib/tasks", :glob => "**/*.rake"
|
||||
paths.lib.templates "lib/templates"
|
||||
paths.config "config"
|
||||
paths.config.initializers "config/initializers", :glob => "**/*.rb"
|
||||
paths.config.locales "config/locales", :glob => "*.{rb,yml}"
|
||||
|
|
|
@ -3,7 +3,7 @@ $:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.inc
|
|||
|
||||
require 'active_support'
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require 'active_support/core_ext/object/singleton_class'
|
||||
require 'active_support/core_ext/kernel/singleton_class'
|
||||
require 'active_support/core_ext/array/extract_options'
|
||||
require 'active_support/core_ext/hash/deep_merge'
|
||||
require 'active_support/core_ext/module/attribute_accessors'
|
||||
|
@ -26,7 +26,6 @@ module Rails
|
|||
:orm => '-o',
|
||||
:resource_controller => '-c',
|
||||
:scaffold_controller => '-c',
|
||||
:stylesheets => '-y',
|
||||
:template_engine => '-e',
|
||||
:test_framework => '-t'
|
||||
},
|
||||
|
@ -42,21 +41,15 @@ module Rails
|
|||
}
|
||||
|
||||
DEFAULT_OPTIONS = {
|
||||
:erb => {
|
||||
:layout => true
|
||||
},
|
||||
|
||||
:rails => {
|
||||
:force_plural => false,
|
||||
:helper => true,
|
||||
:layout => true,
|
||||
:orm => nil,
|
||||
:integration_tool => nil,
|
||||
:performance_tool => nil,
|
||||
:resource_controller => :controller,
|
||||
:scaffold_controller => :scaffold_controller,
|
||||
:singleton => false,
|
||||
:stylesheets => true,
|
||||
:test_framework => nil,
|
||||
:template_engine => :erb
|
||||
},
|
||||
|
|
|
@ -8,7 +8,6 @@ module Erb
|
|||
|
||||
argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
|
||||
|
||||
class_option :layout, :type => :boolean
|
||||
class_option :singleton, :type => :boolean, :desc => "Supply to skip index view"
|
||||
|
||||
def create_root_folder
|
||||
|
@ -25,12 +24,6 @@ module Erb
|
|||
end
|
||||
end
|
||||
|
||||
def copy_layout_file
|
||||
return unless options[:layout]
|
||||
template filename_with_extensions(:layout),
|
||||
File.join("app/views/layouts", controller_class_path, filename_with_extensions(controller_file_name))
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def available_views
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><%= controller_class_name %>: <%%= controller.action_name %></title>
|
||||
<%%= stylesheet_link_tag 'scaffold' %>
|
||||
<%%= javascript_include_tag :defaults %>
|
||||
<%%= csrf_meta_tag %>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p class="notice"><%%= notice %></p>
|
||||
<p class="alert"><%%= alert %></p>
|
||||
|
||||
<%%= yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -137,7 +137,7 @@ module Rails::Generators
|
|||
end
|
||||
|
||||
def create_public_stylesheets_files
|
||||
empty_directory_with_gitkeep "public/stylesheets"
|
||||
directory "public/stylesheets"
|
||||
end
|
||||
|
||||
def create_prototype_files
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
protect_from_forgery
|
||||
layout 'application'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><%= controller_name.humanize %>: <%= action_name %></title>
|
||||
<%= stylesheet_link_tag 'application' %>
|
||||
<%= javascript_include_tag :defaults %>
|
||||
<%= csrf_meta_tag %>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<p class="notice"><%= notice %></p>
|
||||
<p class="alert"><%= alert %></p>
|
||||
|
||||
<%=raw yield %>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -4,4 +4,4 @@
|
|||
# If you change this key, all old signed cookies will become invalid!
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
Rails.application.config.cookie_secret = '<%= app_secret %>'
|
||||
Rails.application.config.secret_token = '<%= app_secret %>'
|
|
@ -1,8 +1,6 @@
|
|||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Rails.application.config.session_store :cookie_store, {
|
||||
:key => '_<%= app_name %>_session',
|
||||
}
|
||||
Rails.application.config.session_store :cookie_store, :key => '_<%= app_name %>_session'
|
||||
|
||||
# Use the database for sessions instead of the cookie-based default,
|
||||
# which shouldn't be used to store highly confidential information
|
||||
|
|
|
@ -7,7 +7,6 @@ module Rails
|
|||
remove_class_option :actions
|
||||
|
||||
hook_for :scaffold_controller, :required => true
|
||||
hook_for :stylesheets
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
Description:
|
||||
Copies scaffold stylesheets to public/stylesheets/.
|
||||
|
||||
Examples:
|
||||
`rails generate stylesheets`
|
|
@ -1,9 +0,0 @@
|
|||
module Rails
|
||||
module Generators
|
||||
class StylesheetsGenerator < Base
|
||||
def copy_stylesheets_file
|
||||
template "scaffold.css", "public/stylesheets/scaffold.css" if behavior == :invoke
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,8 @@ require 'set'
|
|||
module Rails
|
||||
module Paths
|
||||
module PathParent
|
||||
attr_reader :children
|
||||
|
||||
def method_missing(id, *args)
|
||||
name = id.to_s
|
||||
|
||||
|
@ -37,15 +39,15 @@ module Rails
|
|||
end
|
||||
|
||||
def load_once
|
||||
filter { |path| path.paths if path.load_once? }
|
||||
filter_by(:load_once?)
|
||||
end
|
||||
|
||||
def eager_load
|
||||
filter { |path| path.paths if path.eager_load? }
|
||||
filter_by(:eager_load?)
|
||||
end
|
||||
|
||||
def load_paths
|
||||
filter { |path| path.paths if path.load_path? }
|
||||
filter_by(:load_path?)
|
||||
end
|
||||
|
||||
def push(*)
|
||||
|
@ -58,8 +60,16 @@ module Rails
|
|||
|
||||
protected
|
||||
|
||||
def filter(&block)
|
||||
all_paths.map(&block).compact.flatten.uniq.select { |p| File.exists?(p) }
|
||||
def filter_by(constraint)
|
||||
all_paths.map do |path|
|
||||
if path.send(constraint)
|
||||
paths = path.paths
|
||||
paths -= path.children.values.map { |p| p.send(constraint) ? [] : p.paths }.flatten
|
||||
paths
|
||||
else
|
||||
[]
|
||||
end
|
||||
end.flatten.uniq.select { |p| File.exists?(p) }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -129,10 +139,12 @@ module Rails
|
|||
|
||||
def paths
|
||||
raise "You need to set a path root" unless @root.path
|
||||
|
||||
result = @paths.map do |p|
|
||||
path = File.expand_path(p, @root.path)
|
||||
@glob ? Dir[File.join(path, @glob)] : path
|
||||
end
|
||||
|
||||
result.flatten!
|
||||
result.uniq!
|
||||
result
|
||||
|
|
|
@ -61,7 +61,7 @@ module Rails
|
|||
@config ||= Engine::Configuration.new
|
||||
end
|
||||
|
||||
initializer :load_init_rb, :before => :load_application_initializers do |app|
|
||||
initializer :load_init_rb, :before => :load_config_initializers do |app|
|
||||
files = %w(rails/init.rb init.rb).map { |path| File.expand_path path, root }
|
||||
if initrb = files.find { |path| File.file? path }
|
||||
if initrb == files.first
|
||||
|
|
|
@ -39,7 +39,6 @@ module Rails
|
|||
# # lib/my_gem/railtie.rb
|
||||
# module MyGem
|
||||
# class Railtie < Rails::Railtie
|
||||
# railtie_name :mygem
|
||||
# end
|
||||
# end
|
||||
#
|
||||
|
@ -51,24 +50,8 @@ module Rails
|
|||
#
|
||||
# module MyGem
|
||||
# class Railtie < Rails::Railtie
|
||||
# railtie_name :mygem
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# * Make sure your Gem loads the railtie.rb file if Rails is loaded first, an easy
|
||||
# way to check is by checking for the Rails constant which will exist if Rails
|
||||
# has started:
|
||||
#
|
||||
# # lib/my_gem.rb
|
||||
# module MyGem
|
||||
# require 'lib/my_gem/railtie' if defined?(Rails)
|
||||
# end
|
||||
#
|
||||
# * Or instead of doing the require automatically, you can ask your users to require
|
||||
# it for you in their Gemfile:
|
||||
#
|
||||
# # #{USER_RAILS_ROOT}/Gemfile
|
||||
# gem "my_gem", :require_as => ["my_gem", "my_gem/railtie"]
|
||||
#
|
||||
# == Initializers
|
||||
#
|
||||
|
@ -82,13 +65,11 @@ module Rails
|
|||
# end
|
||||
#
|
||||
# If specified, the block can also receive the application object, in case you
|
||||
# need to access some application specific configuration:
|
||||
# need to access some application specific configuration, like middleware:
|
||||
#
|
||||
# class MyRailtie < Rails::Railtie
|
||||
# initializer "my_railtie.configure_rails_initialization" do |app|
|
||||
# if app.config.cache_classes
|
||||
# # some initialization behavior
|
||||
# end
|
||||
# app.middlewares.use MyRailtie::Middleware
|
||||
# end
|
||||
# end
|
||||
#
|
||||
|
@ -104,9 +85,6 @@ module Rails
|
|||
# # Customize the ORM
|
||||
# config.generators.orm :my_railtie_orm
|
||||
#
|
||||
# # Add a middleware
|
||||
# config.middlewares.use MyRailtie::Middleware
|
||||
#
|
||||
# # Add a to_prepare block which is executed once in production
|
||||
# # and before which request in development
|
||||
# config.to_prepare do
|
||||
|
@ -160,7 +138,7 @@ module Rails
|
|||
# By registering it:
|
||||
#
|
||||
# class MyRailtie < Railtie
|
||||
# subscriber MyRailtie::Subscriber.new
|
||||
# subscriber :my_gem, MyRailtie::Subscriber.new
|
||||
# end
|
||||
#
|
||||
# Take a look in Rails::Subscriber docs for more information.
|
||||
|
|
|
@ -234,6 +234,22 @@ module ApplicationTests
|
|||
assert_equal File.expand_path(__FILE__), last_response.headers["X-Lighttpd-Send-File"]
|
||||
end
|
||||
|
||||
test "config.secret_token is sent in env" do
|
||||
make_basic_app do |app|
|
||||
app.config.secret_token = 'ThisIsASECRET123'
|
||||
end
|
||||
|
||||
class ::OmgController < ActionController::Base
|
||||
def index
|
||||
cookies.signed[:some_key] = "some_value"
|
||||
render :text => env["action_dispatch.secret_token"]
|
||||
end
|
||||
end
|
||||
|
||||
get "/"
|
||||
assert_equal 'ThisIsASECRET123', last_response.body
|
||||
end
|
||||
|
||||
test "protect from forgery is the default in a new app" do
|
||||
make_basic_app
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ class MiddlewareStackDefaultsTest < Test::Unit::TestCase
|
|||
|
||||
Object.const_set(:MyApplication, Class.new(Rails::Application))
|
||||
MyApplication.class_eval do
|
||||
config.cookie_secret = "3b7cd727ee24e8444053437c36cc66c4"
|
||||
config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
||||
config.session_store :cookie_store, :key => "_myapp_session"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -71,6 +71,7 @@ module ApplicationTests
|
|||
assert_in_load_path "lib"
|
||||
assert_in_load_path "vendor"
|
||||
|
||||
assert_not_in_load_path "app", "views"
|
||||
assert_not_in_load_path "app", "metal"
|
||||
assert_not_in_load_path "config"
|
||||
assert_not_in_load_path "config", "locales"
|
||||
|
|
|
@ -14,7 +14,7 @@ module ApplicationTests
|
|||
require "action_controller/railtie"
|
||||
|
||||
class MyApp < Rails::Application
|
||||
config.cookie_secret = "3b7cd727ee24e8444053437c36cc66c4"
|
||||
config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"
|
||||
config.session_store :cookie_store, :key => "_myapp_session"
|
||||
end
|
||||
|
||||
|
|
|
@ -51,6 +51,13 @@ class AppGeneratorTest < Rails::Generators::TestCase
|
|||
).each{ |path| assert_file path }
|
||||
end
|
||||
|
||||
def test_application_controller_and_layout_files
|
||||
run_generator
|
||||
assert_file "app/controllers/application_controller.rb", /layout 'application'/
|
||||
assert_file "app/views/layouts/application.html.erb", /stylesheet_link_tag 'application'/
|
||||
assert_file "public/stylesheets/application.css"
|
||||
end
|
||||
|
||||
def test_name_collision_raises_an_error
|
||||
content = capture(:stderr){ run_generator [File.join(destination_root, "generate")] }
|
||||
assert_equal "Invalid application name generate. Please give a name which does not match one of the reserved rails words.\n", content
|
||||
|
|
|
@ -66,7 +66,6 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
|
|||
new
|
||||
show
|
||||
).each { |view| assert_file "app/views/users/#{view}.html.erb" }
|
||||
assert_file "app/views/layouts/users.html.erb"
|
||||
end
|
||||
|
||||
def test_functional_tests
|
||||
|
|
|
@ -70,14 +70,10 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
|
|||
show
|
||||
_form
|
||||
).each { |view| assert_file "app/views/product_lines/#{view}.html.erb" }
|
||||
assert_file "app/views/layouts/product_lines.html.erb"
|
||||
|
||||
# Helpers
|
||||
assert_file "app/helpers/product_lines_helper.rb"
|
||||
assert_file "test/unit/helpers/product_lines_helper_test.rb"
|
||||
|
||||
# Stylesheets
|
||||
assert_file "public/stylesheets/scaffold.css"
|
||||
end
|
||||
|
||||
def test_scaffold_on_revoke
|
||||
|
@ -101,13 +97,9 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
|
|||
|
||||
# Views
|
||||
assert_no_file "app/views/product_lines"
|
||||
assert_no_file "app/views/layouts/product_lines.html.erb"
|
||||
|
||||
# Helpers
|
||||
assert_no_file "app/helpers/product_lines_helper.rb"
|
||||
assert_no_file "test/unit/helpers/product_lines_helper_test.rb"
|
||||
|
||||
# Stylesheets (should not be removed)
|
||||
assert_file "public/stylesheets/scaffold.css"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
require 'generators/generators_test_helper'
|
||||
require 'rails/generators/rails/stylesheets/stylesheets_generator'
|
||||
|
||||
class StylesheetsGeneratorTest < Rails::Generators::TestCase
|
||||
include GeneratorsTestHelper
|
||||
|
||||
def test_copy_stylesheets
|
||||
run_generator
|
||||
assert_file "public/stylesheets/scaffold.css"
|
||||
end
|
||||
|
||||
def test_stylesheets_are_not_deleted_on_revoke
|
||||
run_generator
|
||||
run_generator [], :behavior => :revoke
|
||||
assert_file "public/stylesheets/scaffold.css"
|
||||
end
|
||||
end
|
|
@ -100,7 +100,7 @@ module TestHelpers
|
|||
end
|
||||
end
|
||||
|
||||
add_to_config 'config.cookie_secret = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"'
|
||||
add_to_config 'config.secret_token = "3b7cd727ee24e8444053437c36cc66c4"; config.session_store :cookie_store, :key => "_myapp_session"'
|
||||
end
|
||||
|
||||
class Bukkit
|
||||
|
|
Loading…
Reference in a new issue